Skip to content

Instantly share code, notes, and snippets.

@jonasvanderhaegen
Last active June 3, 2026 21:12
Show Gist options
  • Select an option

  • Save jonasvanderhaegen/99cde7bc7086fd2ffbb6eb2200b7ceac to your computer and use it in GitHub Desktop.

Select an option

Save jonasvanderhaegen/99cde7bc7086fd2ffbb6eb2200b7ceac to your computer and use it in GitHub Desktop.
MCP complete reference: all primitives (server+client), utilities, transports, OAuth, and the 2026-07-28 RC direction - research notes June 2026

MCP: the complete option surface

Research notes (June 2026). Everything an MCP implementation can offer, on both sides of the wire: the primitives, the utilities, the transports, authorization, and where the protocol is heading (the 2026-07-28 release candidate changes the picture substantially). Companion to the deep-dive notes on resources, prompts, and the LSP comparison.

Spec versions to date: 2024-11-05, 2025-03-26 (Streamable HTTP, OAuth), 2025-06-18 (elicitation, structured tool output, resource indicators), 2025-11-25 (current stable), 2026-07-28 (release candidate, locked May 21 2026).

1. The architecture in one paragraph

Host application (Claude Code, an IDE, a chat app) runs an MCP client per connection; each client talks JSON-RPC 2.0 to one server. Both sides declare capabilities during initialization and only negotiated features exist in the session. Messages are requests (expect a response), notifications (fire and forget), and responses; both directions can send requests. The wire format is UTF-8 JSON-RPC over a transport (section 6).

2. Lifecycle

  • initialize (client -> server): carries protocolVersion, capabilities, clientInfo. Server answers with its capabilities, serverInfo, optional instructions (free text the host can inject into model context; in Claude Code this is auto-injected and truncated at ~2KB, and it is the single most reliable way for a server to steer model behavior).
  • notifications/initialized confirms; then normal traffic.
  • Version negotiation: client proposes a version, server answers with the same or its closest supported; client disconnects if incompatible.

3. Server-side primitives (what a server can offer)

Primitive Controlled by Methods Notes
Tools model tools/list, tools/call, notifications/tools/list_changed The only model-driven primitive. Input via JSON Schema; since 2025-06-18 also outputSchema + structuredContent for typed results. Annotations: readOnlyHint, destructiveHint, idempotentHint, openWorldHint (advisory, not security).
Resources application/user resources/list, resources/read, resources/templates/list, resources/subscribe, notifications/resources/updated, notifications/resources/list_changed Read-only data behind URIs; RFC 6570 templates; text or base64 blob; annotations (audience, priority, lastModified). In Claude Code only surfaced via user @-mention.
Prompts user prompts/list, prompts/get, notifications/prompts/list_changed Parameterized message templates; multi-modal content incl. embedded resources. In Claude Code surfaced as /mcp__server__prompt slash commands.

Capability flags: tools: {listChanged}, resources: {subscribe, listChanged}, prompts: {listChanged}.

4. Client-side primitives (what a client can offer servers)

These run in the reverse direction: the server asks, the client (and its user) answers. All three require the client to declare the capability.

Sampling (sampling capability)

Server asks the client to run an LLM completion: sampling/createMessage with messages (text/image/audio), systemPrompt, maxTokens, and modelPreferences: hints (substring model-name suggestions, in preference order) plus three normalized priorities (costPriority, speedPriority, intelligencePriority). The client controls the actual model and SHOULD keep a human in the loop on both the request and the response. Lets a server be "agentic" without owning an API key. Deprecated in the 2026-07-28 RC (12+ month window): direction is direct LLM provider integration instead.

Roots (roots: {listChanged} capability)

Client exposes filesystem scope to the server: roots/list returns {uri: "file:///...", name} entries; notifications/roots/list_changed on change. Defines where the server may operate (workspace boundaries). Client must guard against path traversal. Deprecated in the 2026-07-28 RC: direction is tool parameters or configuration instead.

Elicitation (elicitation capability, added 2025-06-18)

Server requests structured input from the USER mid-flow: elicitation/create with a message and a requestedSchema (deliberately restricted to a FLAT object of primitives: string with optional format email/uri/date/date-time, number/integer with min/max, boolean, enum). Response is one of three actions: accept (with content matching the schema), decline, or cancel. Servers MUST NOT elicit sensitive information. This is the standard way to do "confirm/configure before proceeding" interactively.

5. Utilities (cross-cutting plumbing)

  • Ping: ping request either way; health check.
  • Progress: caller attaches a progressToken in _meta; receiver emits notifications/progress (progress, optional total, message).
  • Cancellation: notifications/cancelled with the requestId to abort an in-flight request.
  • Logging (logging capability): client sets level via logging/setLevel; server emits notifications/message (RFC 5424 levels). Deprecated in the 2026-07-28 RC: direction is stderr or OpenTelemetry.
  • Completion (completions capability): completion/complete autocompletes prompt arguments and resource-template variables (the "IDE-style argument autocomplete" for primitives).
  • Pagination: list operations take a cursor and return nextCursor.
  • _meta: extension point on most objects for protocol- and app-level metadata.

6. Transports

stdio (preferred default)

Client launches the server as a subprocess; newline-delimited JSON-RPC on stdin/stdout (no embedded newlines); stderr is free-form logging. Nothing but MCP messages may touch stdout (one stray print corrupts the channel).

Streamable HTTP (replaced HTTP+SSE from 2024-11-05)

One MCP endpoint supporting POST and GET:

  • Every client message is a POST with Accept: application/json, text/event-stream. Server answers a request either with a single JSON body or by opening an SSE stream (response arrives as an event, possibly after server-initiated requests/notifications).
  • GET opens a server-to-client SSE stream for unsolicited messages.
  • Sessions: server MAY issue Mcp-Session-Id on initialize; client then sends it on every request; 404 means re-initialize; DELETE ends the session.
  • Resumability: SSE event ids + Last-Event-ID header replay missed messages per-stream.
  • MCP-Protocol-Version header REQUIRED on subsequent HTTP requests.
  • Security: MUST validate Origin (DNS-rebinding defense), SHOULD bind localhost only when local, SHOULD authenticate.

Custom transports

Allowed; must preserve JSON-RPC framing and lifecycle.

7. Authorization (HTTP transports only; OPTIONAL)

OAuth 2.1 stack, subset profile:

  • MCP server = resource server; MUST serve Protected Resource Metadata (RFC 9728) advertising its authorization server(s); 401 responses carry WWW-Authenticate pointing at the metadata.
  • Client MUST do AS metadata discovery (RFC 8414); SHOULD use Dynamic Client Registration (RFC 7591); MUST use PKCE; MUST send the RFC 8707 resource parameter binding tokens to the specific server.
  • Tokens: Authorization: Bearer header only (never query string); server MUST validate audience; token passthrough to upstream APIs is explicitly forbidden (confused-deputy defense).
  • stdio servers do not use this; they take credentials from the environment.

8. Where the protocol is heading (2026-07-28 RC, supersedes 2025-11-25)

  • Stateless redesign: initialize handshake and Mcp-Session-Id removed; client info and protocol version travel in _meta on every request; new server/discover replaces capability exchange. Servers can sit behind plain load balancers.
  • Routing/caching headers: required Mcp-Method / Mcp-Name headers; list responses gain ttlMs and cacheScope; W3C Trace Context propagation.
  • Extensions framework (SEP-2133 lineage): first-class extensions with reverse-DNS ids, capability-map negotiation, independent versioning. Official extensions: MCP Apps (server-rendered HTML in sandboxed iframes) and Tasks (a tools/call may return a task handle for long-running, client-polled operations).
  • Deprecations (12+ month windows): roots, sampling, logging.
  • Schema upgrade: tool input/output schemas become full JSON Schema 2020-12; resource-not-found error moves from -32002 to -32602.
  • Authorization hardening: mandatory iss validation, application_type at registration, scope accumulation clarified.

9. Picking options: a decision table

You want Use
Model performs an action or fetch on demand Tool (the only model-triggered option)
Steer model behavior automatically, every session instructions (initialize result) + concise tool descriptions
Background data the user can attach Resource (@-mention in Claude Code)
Reusable user-fired command Prompt (slash command in Claude Code)
Ask the user a structured question mid-operation Elicitation
Long-running operation Progress notifications now; Tasks extension when final
Argument autocomplete Completion capability
Local single-user deployment stdio, or Streamable HTTP daemon bound to 127.0.0.1 with Origin validation
Multi-client shared/warm deployment Streamable HTTP (+ sessions today; stateless after the RC lands)
Remote multi-tenant deployment Streamable HTTP + the OAuth 2.1 stack
Server needs an LLM / filesystem scope / log channel Sampling / roots / logging exist today but are RC-deprecated; prefer direct integration, tool params, stderr/OTel

10. How skyline maps onto this

Ships today: tools (14), resources (skyline://guide), instructions, stdio + Streamable HTTP daemon (localhost-bound), and a self-reported tool-manifest digest for drift detection. Unused options with plausible value: elicitation (confirm before a large non-dry-run srewrite), completion (autocomplete for language names), Tasks once final (directory-wide rewrites as polled tasks). Skippable: sampling/roots/logging (RC-deprecated), prompts (the agent prompts live in the README), OAuth (localhost daemon).

Sources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment