modelcontextprotocol / modelcontextprotocol/php-sdk

Add server lifecycle events (ServerStarted / ServerStopped)

Aperta
#286 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

enhancement needs confirmation
Lingua principale
PHP
Stelle
1.6k
Fork
173
Merge medio
2g 49m
PR unite (30g)
23

Descrizione

Problem

The SDK currently dispatches only request-scoped events (RequestEvent, ResponseEvent, ErrorEvent, list-changed events). There is no hook that fires once per Server::run() invocation.

Consumers that need one-time setup/teardown per server boot must either:

  • Duplicate the logic in every transport's entry point (HTTP controller, CLI command, custom transports), or
  • Subscribe to RequestEvent + matching ResponseEvent/ErrorEvent and deal with per-request overhead, fiber suspension, and every error path.

Proposal

Add two events in Mcp\Event:

  • ServerStartedEvent — dispatched at the top of Server::run($transport), before the first request is read. Exposes the server and transport.
  • ServerStoppedEvent — dispatched just before Server::run() returns, in a finally so it fires on clean exit, thrown exceptions, and transport close. Exposes the exit code and any captured throwable.

Use cases

  • Identity / impersonation: switch the current user of a host framework (Drupal, Symfony Security) once when the server boots. This is our concrete motivation — without a lifecycle hook we either patch every transport or pay the cost of switching on every RequestEvent.
  • Metrics / observability: increment mcp_server_started_total, start a run-duration timer, emit a "server up" log line including registered tool/prompt/resource counts.
  • Resource management: warm caches, acquire leases, open long-lived connections at start; release them at stop.

Alternatives considered

  • Use RequestEvent as a pseudo-start hook — works but is per-request. Adds overhead to what is logically a one-shot, and requires pairing with ResponseEvent/ErrorEvent for cleanup. Fiber suspension (Protocol::handleRequest, early return on $fiber->isSuspended()) means the terminal event can be delayed or skipped from the subscriber's perspective.
  • Subclassing Server — not portable; transports and framework integrations instantiate Server directly via the Builder.
  • Transport-level hooks — would require a change in every transport implementation (Stdio, StreamableHttp, any custom transport) rather than in one place in Server::run().

Backward compatibility

Purely additive. Subscribers that don't care about the new events are unaffected. No public API changes to existing events or handlers.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da Server::run($transport), quindi esamina Protocol::handleRequest e i punti di ingresso del transport creati da Builder. Esamina gli Events esistenti e i relativi test di dispatching, se presenti. Il lavoro è completato quando ServerStartedEvent viene emesso una volta prima della prima richiesta e ServerStoppedEvent viene emesso da finally in caso di uscita regolare, eccezioni e chiusura del transport, trasportando il contesto specificato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
php
Ambito
api, backend
Tipo di issue
Funzionalità
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
52/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.