Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
run: which julia
continue-on-error: true
- name: Install Julia, but only if it is not already available in the PATH
uses: julia-actions/setup-julia@v1
uses: julia-actions/setup-julia@v2
with:
version: '1'
# arch: ${{ runner.arch }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/previews-cleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
ref: gh-pages

Expand Down
44 changes: 44 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Repository Guidance

## Scope

`ModelContextProtocol.jl` provides Julia client and server support for MCP over
Streamable HTTP.

- The general implementation supports stateful MCP `2025-11-25` and stateless
MCP `2026-07-28`.
- The static JuliaC implementation is a separate, tools-only `2025-11-25`
subset. Do not add dynamic dispatch or unsupported features to it.
- Keep the export surface small. Put specialized and low-level helpers under
the `ModelContextProtocol` namespace.

## Required checks

Run these checks before you open or merge a pull request:

```sh
julia --startup-file=no --project=. -e 'using Pkg; Pkg.test()'
julia --startup-file=no --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
julia --startup-file=no --project=docs docs/make.jl
```

`Pkg.test()` includes the JuliaC `--trim=safe` compile check. Test on Julia
1.10 when code uses a Julia API that can differ across supported releases.

## Protocol changes

- Verify wire behavior against the matching dated MCP specification.
- Preserve both protocol eras unless the change explicitly removes support.
- Add a regression test for headers, metadata, JSON-RPC error codes, HTTP
status codes, and side-effect rules.
- Use the official MCP conformance runner for a changed `2026-07-28` contract
when a relevant scenario exists. `test/conformance_client.jl` is the client
adapter.
- Treat authentication, cancellation, and request metadata as security
boundaries. Do not weaken validation to make one fixture pass.

## Documentation

Update the support matrix in `ROADMAP.md` and the relevant Documenter guide
when behavior or a support limit changes. Examples in `@example` blocks
must build and pass as doctests.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ uuid = "a630a0b0-4325-47f6-86f8-c7db38e4394e"
version = "1.0.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Expand Down
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

Julia server and client utilities for the Model Context Protocol (MCP).

The package targets MCP protocol version `2025-11-25` and currently focuses on
Streamable HTTP, discovery manifests, OAuth-protected resources, tools, prompts,
resources, completions, logging notifications, and client smoke tests. It also
The package supports the stateful MCP `2025-11-25` protocol and the stateless
MCP `2026-07-28` protocol over Streamable HTTP. Clients default to
`2025-11-25` for compatibility. The package includes discovery manifests,
OAuth-protected resources, tools, prompts, resources, completions, logging,
multi-round-trip results, subscriptions, and custom tool headers. It also
ships first-class support for [MCP Apps](MCP-App-playbook.md) (SEP-1865) —
interactive HTML widgets rendered inline by hosts like Cursor and Claude; see
[MCP-App-playbook.md](MCP-App-playbook.md) for the end-to-end guide.
Expand Down Expand Up @@ -76,6 +78,24 @@ result = call_tool(client, "add"; arguments=Dict("numbers" => [1, 3, 4]))
terminate_session!(client)
```

Use the stateless protocol when the server supports MCP `2026-07-28`:

```julia
client = prepare_manual_client(
discovery;
config=MCPClientConfig(
protocol_version=ModelContextProtocol.PROTOCOL_VERSION_2026_07_28,
),
capabilities=Dict("elicitation" => Dict()),
)
initialize_client!(client) # calls server/discover
```

See the
[MCP 2026-07-28 guide](https://juliaservices.github.io/ModelContextProtocol.jl/stable/protocol-2026/)
for capability checks, multi-round-trip results, custom headers, caching, and
subscriptions.

## Agentif Tools

When `Agentif.jl` is loaded, this package can register Agentif tools directly:
Expand Down
216 changes: 68 additions & 148 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,148 +1,68 @@
# MCP 2025-06-18 Compliance Roadmap

This document captures the work needed to bring `ModelContextProtocol.jl` into
alignment with the Model Context Protocol revision published on
2025‑06‑18. References to the upstream specification use the markdown files in
`docs/specification/2025-06-18/…` from the
`modelcontextprotocol/modelcontextprotocol` repository.

## Current Coverage Snapshot
- Discovery and manual client creation over plain HTTP are implemented
(see `src/discovery.jl`, `src/client.jl`).
- Server primitives exist for basic tool, prompt, and resource registration
with JSON-RPC handling (`src/server.jl`).
- OAuth helper wrappers exist for attaching tokens (`src/auth.jl`).
- Test suite exercises a happy-path HTTP server/client interaction.

The implemented surface matches the 2024-era MCP draft and omits large
portions of the 2025-06-18 revision.

## Compliance Gaps and Required Enhancements

### Lifecycle, Transport, and Session Management
- **`initialize` / `initialized` handshake** (`basic/lifecycle.mdx`): client
must send `notifications/initialized` after a successful response, and server
should avoid initiating requests before it is received. Neither side enforces
this today.
- **Protocol headers and session IDs** (`basic/transports.mdx` §Streamable HTTP):
client requests must send `Accept: application/json, text/event-stream`,
`MCP-Protocol-Version`, and (when provided) `Mcp-Session-Id`. Server responses
should set these headers and support resumable SSE streams. Current client and
server only support stateless POSTs with JSON responses.
- **Server-to-client notifications & requests**: HTTP transport lacks SSE support,
so logging messages, list change notifications, progress updates, and server
initiated requests cannot flow.
- **Timeouts and cancellation** (`basic/lifecycle.mdx`, `basic/utilities/cancellation.mdx`):
no helpers exist for sending or handling cancellation or progress
notifications.

### Discovery & Manifest
- **Manifest schema drift** (`basic/transports.mdx`, `schema.mdx`):
generated manifest lacks fields introduced in 2025-06-18 (e.g. `description_for_model`,
richer transport descriptors, `instructions`). Need to audit against the
latest schema and expose configuration knobs in `MCPServerConfig`.
- **Capability exposure**: manifest should accurately reflect negotiated
capabilities (including `logging`, `completions`, resource sub-capabilities).

### Server Capabilities
- **Tools** (`server/tools.mdx`):
- `call_tool` handlers should return `content`, `structuredContent`,
`isError`, and optional `outputSchema`. Current handlers expect an
`outputs` array.
- `MCPServerTool` lacks fields for `outputSchema` and `annotations`.
- Pagination cursors (`nextCursor`) are unsupported.
- `notifications/tools/list_changed` and capability flag plumbing are absent.
- Error handling must distinguish protocol errors vs execution errors per spec.
- **Prompts** (`server/prompts.mdx`):
- Response format should allow single content objects and annotations.
- Pagination and `nextCursor` not supported.
- No `notifications/prompts/list_changed`.
- **Resources** (`server/resources.mdx`):
- Method name mismatch (`resources/get` vs `resources/read`).
- No support for resource templates, subscriptions, or list change notifications.
- `MCPServerResource` should expose spec-compliant fields (`title`, `annotations`,
`size`) and handler helpers should produce `text`/`blob` payloads.
- **Logging** (`server/utilities/logging.mdx`):
- Missing `logging` capability, `logging/setLevel`, and `notifications/message`.
- **Completions** (`server/utilities/completion.mdx`):
- No plumbing for `completion/complete`, capability declaration, or helper APIs.
- **Utilities (ping/progress/cancellation)** (`basic/utilities/*.mdx`):
- No helpers for sending `ping`, `progress` or handling cancellation.

### Client Responsibilities
- **Request sequencing** (`basic/lifecycle.mdx`): send `notifications/initialized`
and guard against issuing feature calls before initialization completes.
- **Extended operations**:
- Add wrappers for `resources/read`, `resources/templates/list`,
`resources/subscribe`, `completion/complete`, `logging/setLevel`, `ping`,
`cancelled`, and `sampling`/`elicitation` request handlers (see
`client/sampling.mdx`, `client/elicitation.mdx`, `client/roots.mdx`).
- Handle pagination cursors returned from list operations.
- Support structured tool responses (`structuredContent`, `isError`).
- **Streaming / notifications**: implement SSE listener so clients can consume
server notifications (`notifications/message`, `notifications/resources/updated`,
list change events, etc.) and respond to server-initiated requests.
- **Capability negotiation helpers**: expose ergonomic APIs for setting client
capabilities (roots, sampling, elicitation) and for registering handlers the
server can invoke.

### Authorization & Security
- **OAuth metadata** (`basic/authorization.mdx`): extend discovery helpers to
surface `WWW-Authenticate` parameters like `resource`, `scope`, and issuer
selection. Ensure HTTP client attaches `Authorization` and `DPoP` headers per
spec.
- **Origin validation** (`basic/transports.mdx` security warning): HTTP server
should enforce origin checks and allow binding to loopback-only by default.
- **Annotations**: ensure resource/prompt/tool annotations map cleanly to spec
keys to avoid leaking unintended metadata.

### Typing & Schema Alignment
- Audit type aliases (`src/types.jl`) against `schema.mdx`:
- Introduce types for shared content payloads (text/image/audio/resource).
- Support `_meta` blocks where permitted.
- Validate enums (log levels, stop reasons, etc.).
- Provide serialization helpers to guarantee responses conform to schema (e.g.
ensure timestamps are ISO-8601).

## Recommended Implementation Phases

### Phase 1 – Core Protocol Compliance
1. Retrofit HTTP client/server pipeline to include protocol headers and add
preliminary SSE support (even if notifications are buffered).
2. Update lifecycle: send `notifications/initialized`, add timeout/cancellation
hooks.
3. Align server methods with spec naming and payloads (`resources/read`,
structured tool results, annotations).
4. Extend manifest generation/configuration to cover new schema fields.
5. Expand test suite to cover updated request/response shapes.

### Phase 2 – Notifications and Advanced Capabilities
1. Implement logging, completion, and pagination helpers.
2. Add resource templates, subscriptions, and list change notifications.
3. Support prompt/tool/resource `listChanged` flows end-to-end (server + client).
4. Introduce SSE event loop in client to receive notifications and server requests.
5. Provide first-class APIs for registering completion/logging handlers.

### Phase 3 – Client Feature Surface
1. Add sampling and elicitation handler plumbing so client applications can fulfill
server requests (`client/sampling.mdx`, `client/elicitation.mdx`).
2. Implement roots capability negotiation with list change notifications.
3. Harden authorization flows (refresh token management, DPoP when required).
4. Document migration guide from pre-2025 APIs to new payloads.

## Testing and Validation Strategy
- Unit tests for each JSON-RPC method covering success, error, pagination, and
annotation handling.
- Integration tests exercising Streamable HTTP with SSE (can use loopback server).
- Contract tests against the official schema (JSON Schema validation of responses).
- Authorization tests using stub issuer/resource metadata (extend existing auth stubs).
- Regression tests for manifest generation and discovery parsing.
- Load/latency checks for SSE reconnection and notification bursts.

## Open Questions & Follow-Ups
- Decide whether to continue supporting legacy `resources/get` / `outputs`
structures behind a compatibility flag.
- Determine minimum acceptable subset of SSE features (full resumability vs simple
single-stream) for initial release.
- Evaluate need for a higher-level state machine to coordinate simultaneous
server→client requests once sampling/elicitation are added.
# Protocol Status and Roadmap

This file records the current support boundary for `ModelContextProtocol.jl`.
The dated protocol guides in the published MCP specification are the source of
truth for wire behavior.

## Current support

The package supports Streamable HTTP for two protocol eras:

- MCP `2025-11-25`: stateful initialization, sessions, resumable server event
streams, cancellation, ping, logging level changes, resource subscriptions,
tools, prompts, resources, completions, and MCP Apps.
- MCP `2026-07-28`: stateless request metadata, `server/discover`, standard and
custom request headers, cache metadata, client capability checks,
multi-round-trip `input_required` results, request-scoped progress and log
events, and `subscriptions/listen`.

The general server accepts both versions by default. The client defaults to
`2025-11-25`. Applications opt in to `2026-07-28` with `MCPClientConfig`.

The package also includes a separate tools-only server for JuliaC
`--trim=safe` builds. That server intentionally supports only the documented
`2025-11-25` subset.

## Validation baseline

The repository tests these areas:

- Julia 1.10, current stable Julia, and Julia nightly on Linux, macOS, and
Windows.
- OAuth 2 and OAuth 3 compatibility.
- Stateful and stateless HTTP client/server integration.
- Strict JSON-RPC parsing and notification side-effect rules.
- MCP Apps resource and tool metadata.
- Official MCP conformance scenarios for stateless metadata, capability
checks, standard request headers, and `x-mcp-header` behavior.
- JuliaC trim compilation for the static server.
- Documenter build and doctests.

## Intentional limits

- The transport is HTTP only. The package does not provide a stdio transport.
- Tool input and output schemas are advertised but are not a complete runtime
JSON Schema validation engine. A handler must still validate domain rules.
- Modern request-scoped progress and log events keep their correct order, but
the server buffers them until the handler returns.
- Modern sampling, roots, and elicitation are exposed as multi-round-trip input
requests. The application performs the external interaction and retries the
original MCP request.
- OAuth helpers do not implement every optional proof-of-possession mechanism.
- The static JuliaC server does not support prompts, resources, OAuth, MCP Apps,
arbitrary middleware, or the `2026-07-28` stateless protocol.

## Next work

1. Add the official MCP conformance runner to CI when its `2026-07-28` package
release is stable.
2. Stream modern request-scoped events while a handler is still running.
3. Add a standard client API that closes one `subscriptions/listen` stream
without ending the server.
4. Evaluate a lightweight JSON Schema validator for tool arguments and
structured results.
5. Add a stdio transport only if a concrete Julia deployment needs it.

Do not add a feature only to increase surface coverage. Preserve the small
export surface. Keep specialized helpers under the `ModelContextProtocol`
namespace.
25 changes: 25 additions & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: model-context-protocol-jl
description: Maintain ModelContextProtocol.jl protocol, transport, conformance, documentation, and JuliaC static-server behavior.
---

# ModelContextProtocol.jl Maintenance

Use this skill for changes in this repository.

1. Read `AGENTS.md`, `ROADMAP.md`, and the guide for the affected protocol
era.
2. Identify whether the change affects the stateful server, the stateless
server, the client, the static JuliaC server, or more than one surface.
3. Reproduce the wire behavior before editing. Record the JSON-RPC code, HTTP
status, metadata, and headers.
4. Implement the smallest change that preserves the other protocol era.
5. Add a focused regression test. Use the official MCP conformance runner when
it has a matching scenario.
6. Run the package suite, JuliaC trim check, Documenter build, and doctests.
7. Keep new low-level APIs namespaced unless they are a primary user entry
point.

For MCP `2026-07-28`, start with `docs/src/protocol-2026.md`. For the static
server, start with `docs/src/static-server.md`. Do not infer support beyond the
limits stated in those files.
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ makedocs(
),
pages=[
"Home" => "index.md",
"MCP 2026-07-28" => "protocol-2026.md",
"Auth0 Federation Example" => "auth0.md",
"Trim-safe static server" => "static-server.md",
"API" => "api.md",
Expand Down
16 changes: 16 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,19 @@ for the full guide.
- `start_event_listener!`
- `stop_event_listener!`
- `terminate_session!`

## MCP 2026-07-28

The modern low-level helpers stay under the package namespace to keep the
export surface small. See the [MCP 2026-07-28 guide](protocol-2026.md).

- `MCPInputRequired`
- `ModelContextProtocol.PROTOCOL_VERSION_2026_07_28`
- `ModelContextProtocol.discover_server_info!`
- `ModelContextProtocol.is_input_required`
- `ModelContextProtocol.input_responses`
- `ModelContextProtocol.request_state`
- `ModelContextProtocol.send_progress!`
- `ModelContextProtocol.send_log!`
- `ModelContextProtocol.listen_subscriptions!`
- `ModelContextProtocol.close_subscription_listeners!`
Loading
Loading