refactor: replace RequestHandlerExtra with structured context types (#1467)

This commit is contained in:
Felix Weinberger 2026-02-03 20:35:02 +00:00 • committed by GitHub
commit 7bb79ebbbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -144,7 +144,8 @@ When a request arrives from the remote side:
2. **`Protocol.connect()`** routes to `_onrequest()`, `_onresponse()`, or `_onnotification()`
3. **`Protocol._onrequest()`**:
- Looks up handler in `_requestHandlers` map (keyed by method name)
- Creates `RequestHandlerExtra` with `signal`, `sessionId`, `sendNotification`, `sendRequest`
- Creates `BaseContext` with `signal`, `sessionId`, `sendNotification`, `sendRequest`, etc.
- Calls `buildContext()` to let subclasses enrich the context (e.g., Server adds `requestInfo`)
- Invokes handler, sends JSON-RPC response back via transport
4. **Handler** was registered via `setRequestHandler('method', handler)`
@ -152,29 +153,42 @@ When a request arrives from the remote side:
```typescript
// In Client (for server→client requests like sampling, elicitation)
client.setRequestHandler('sampling/createMessage', async (request, extra) => {
client.setRequestHandler('sampling/createMessage', async (request, ctx) => {
// Handle sampling request from server
return { role: "assistant", content: {...}, model: "..." };
});
// In Server (for client→server requests like tools/call)
server.setRequestHandler('tools/call', async (request, extra) => {
server.setRequestHandler('tools/call', async (request, ctx) => {
// Handle tool call from client
return { content: [...] };
});
```
### Request Handler Extra
### Request Handler Context
The `extra` parameter in handlers (`RequestHandlerExtra`) provides:
The `ctx` parameter in handlers provides a structured context:
- `signal`: AbortSignal for cancellation
- `sessionId`: Transport session identifier
- `authInfo`: Validated auth token info (if authenticated)
- `requestId`: JSON-RPC message ID
- `sendNotification(notification)`: Send related notification back
- `sendRequest(request, schema)`: Send related request (for bidirectional flows)
- `taskStore`: Task storage interface (if tasks enabled)
**`BaseContext`** (common to both Server and Client), fields organized into nested groups:
- `sessionId?`: Transport session identifier
- `mcpReq`: Request-level concerns
- `id`: JSON-RPC message ID
- `method`: Request method string (e.g., 'tools/call')
- `_meta?`: Request metadata
- `signal`: AbortSignal for cancellation
- `send(request, schema, options?)`: Send related request (for bidirectional flows)
- `notify(notification)`: Send related notification back
- `http?`: HTTP transport info (undefined for stdio)
- `authInfo?`: Validated auth token info
- `task?`: Task context (`{ id?, store, requestedTtl? }`) when task storage is configured
**`ServerContext`** extends `BaseContext.mcpReq` and `BaseContext.http?` via type intersection:
- `mcpReq` adds: `log(level, data, logger?)`, `elicitInput(params, options?)`, `requestSampling(params, options?)`
- `http?` adds: `req?` (HTTP request info), `closeSSE?`, `closeStandaloneSSE?`
**`ClientContext`** is currently identical to `BaseContext`.
### Capability Checking