Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
452886f
feat: implement MCP 2026-07-28 alongside the handshake revisions
mcollina Jul 29, 2026
f0cf423
fix: address adversarial review findings
mcollina Jul 29, 2026
4c94b00
fix: preserve dual-era feature compatibility
mcollina Aug 19, 2026
6bcd32f
fix: harden modern protocol edge cases
mcollina Aug 30, 2026
50dc07f
fix: make modern delivery and shutdown reliable
mcollina Aug 31, 2026
09f2095
fix: keep delivery acknowledgement timeout active
mcollina Aug 31, 2026
b9ca836
fix: address protocol review feedback
mcollina Sep 1, 2026
f498df5
fix: address second round of protocol review feedback
mcollina Oct 4, 2026
de26c71
fix: keep task data and input intact across rounds
mcollina Oct 6, 2026
3d44648
fix: harden 2026-07-28 transport and subscription conformance
mcollina Oct 6, 2026
9922d96
fix: validate MRTR input, tool output and result envelopes
mcollina Oct 6, 2026
ea4065f
fix: complete task input rounds and release parked tasks reliably
mcollina Oct 6, 2026
d209416
feat: give handlers a cancellation signal
mcollina Oct 6, 2026
39262ae
fix: correct regressions from the first review round
mcollina Oct 6, 2026
b6a6572
fix: bind, isolate and supervise 2026-07-28 tasks
mcollina Oct 6, 2026
782e519
fix: bound per-caller and per-instance resource use
mcollina Oct 6, 2026
d965356
feat: stream subscriptions and honour cancellation over stdio
mcollina Oct 6, 2026
d0416fc
feat: progress and log notifications on the 2026-07-28 path
mcollina Oct 6, 2026
6035708
fix: smaller round-2 findings, defaults and 3.0.0 notes
mcollina Oct 6, 2026
e926d90
Merge remote-tracking branch 'origin/main' into feat/mcp-2026-07-28
mcollina Oct 7, 2026
fd832fa
fix: harden streams, stdio and task timers after the third review
mcollina Oct 8, 2026
dda86ef
fix: share task supervision across eras and fix limit fairness
mcollina Oct 8, 2026
c8e2e64
fix: validate input requests, default schemas and list changes
mcollina Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Overview

This is a production-ready Fastify adapter for the Model Context Protocol (MCP). The project implements a Fastify plugin that enables MCP communication through the JSON-RPC 2.0 specification with full horizontal scaling capabilities. The codebase includes MCP protocol specifications in the `spec/` directory that define the messaging format, lifecycle management, and various protocol features.
This is a production-ready Fastify adapter for the Model Context Protocol (MCP). The project implements a Fastify plugin that enables MCP communication through the JSON-RPC 2.0 specification with full horizontal scaling capabilities. The codebase includes MCP protocol specifications in the `spec/` directory (currently the **2026-07-28** revision) that define the messaging format, versioning, and various protocol features.

The plugin is **dual-era**: it serves the stateless `2026-07-28` revision and the earlier handshake-based revisions (`2025-11-25` through `2024-11-05`) on the same endpoint. A request is treated as modern when `params._meta` carries `io.modelcontextprotocol/protocolVersion`; everything else takes the legacy path.

## Key Features

- **Complete MCP Protocol Support**: Implements the full Model Context Protocol specification
- **Complete MCP Protocol Support**: Implements the full Model Context Protocol specification (2026-07-28, plus the legacy handshake revisions)
- **Stateless Core**: Per-request protocol version and capabilities, `server/discover`, no sessions on the modern path
- **Multi Round-Trip Requests**: Handlers throw `InputRequired`; state travels through the client under HMAC
- **Subscriptions**: `subscriptions/listen` long-lived notification streams with per-type opt-in
- **Server-Sent Events (SSE)**: Real-time streaming communication with session management
- **Horizontal Scaling**: Redis-backed session management and message broadcasting
- **Session Persistence**: Message history and reconnection support with Last-Event-ID
Expand Down Expand Up @@ -49,10 +54,33 @@ The main entry point is `src/index.ts` which exports a Fastify plugin built with
- Heartbeat mechanism for connection health monitoring
- Support for both GET and POST endpoints

### Protocol Eras

**Modern (2026-07-28)** — `src/modern/`:
- `request-meta.ts` parses and validates the per-request `_meta`; `looksModern()` is the era switch
- `headers.ts` reconciles `Mcp-Method` / `Mcp-Name` / `Mcp-Param-*` against the body, including the `=?base64?…?=` sentinel
- `handlers.ts` dispatches modern requests, wraps results in the `resultType` envelope and adds caching hints
- `input-required.ts` is the handler-facing MRTR API (`InputRequired`, `elicitForm`, …)
- `request-state.ts` seals `requestState` with HMAC and binds it to principal, expiry and request digest
- `subscriptions.ts` owns `subscriptions/listen` streams
- `task-inputs.ts` delivers `tasks/update` responses to a running task

**Legacy (2025-11-25 and earlier)** — `src/handlers.ts`, `src/stores/*session*`, SSE in `src/routes/mcp.ts`.

Business logic is shared: the modern dispatcher calls the same `handleToolsList`, `executeToolCall`, `handleResourcesRead` and `handlePromptsGet` and only changes the envelope.

### File Structure

```
src/
├── modern/ # 2026-07-28 protocol
│ ├── request-meta.ts # Per-request _meta parsing, era detection
│ ├── headers.ts # Header/body reconciliation
│ ├── handlers.ts # Modern dispatch, caching, tasks extension
│ ├── input-required.ts # Multi round-trip request API
│ ├── request-state.ts # Sealed requestState
│ ├── subscriptions.ts # subscriptions/listen streams
│ └── task-inputs.ts # tasks/update delivery
├── brokers/
│ ├── message-broker.ts # Interface definition
│ ├── memory-message-broker.ts # MQEmitter implementation
Expand All @@ -67,7 +95,9 @@ src/
├── handlers.ts # MCP protocol handlers
├── routes.ts # SSE connection handling
├── index.ts # Plugin entry point with backend selection
├── schema.ts # MCP protocol types
├── schema.ts # MCP protocol types (legacy canonical + shared)
├── schema-2026.ts # Types introduced or reshaped by 2026-07-28
├── protocol-version.ts # Revision comparison helpers, era detection
└── types.ts # Plugin types
```

Expand All @@ -94,7 +124,10 @@ The project uses ESM modules (`"type": "module"`) and includes comprehensive MCP
- `serverInfo`: Server identification (name, version)
- `capabilities`: MCP capabilities configuration
- `instructions`: Optional server instructions
- `enableSSE`: Enable Server-Sent Events support (default: false)
- `enableSSE`: Enable Server-Sent Events support for legacy clients (default: false). Does not gate `subscriptions/listen`, which is core to 2026-07-28.
- `caching`: Freshness hints (`ttlMs`, `cacheScope`) per cacheable operation. Defaults to `{ ttlMs: 0, cacheScope: 'private' }`.
- `requestStateSecret`: Shared secret sealing MRTR `requestState`. Required when more than one instance can serve a retry.
- `requestStateTtlMs`: How long sealed state stays valid (default 5 minutes).
- `redis`: Redis configuration for horizontal scaling (optional)
- `host`: Redis server hostname
- `port`: Redis server port
Expand All @@ -114,7 +147,8 @@ Uses a base TypeScript configuration (`tsconfig.base.json`) extended by the main
## Testing

The project includes comprehensive test coverage:
- **369 tests total** covering all functionality including OAuth 2.1 authorization and tasks
- **430+ tests total** covering all functionality including OAuth 2.1 authorization, tasks, and both protocol eras
- **2026-07-28 tests**: `test/spec-2026-07-28.test.ts` (end-to-end) and `test/modern-units.test.ts` (header encoding, request-state sealing, subscription filters)
- **Memory backend tests**: Session management, message broadcasting, SSE handling
- **Redis backend tests**: Session persistence, cross-instance messaging, failover
- **Integration tests**: Full plugin lifecycle, multi-instance deployment
Expand Down
Loading
Loading