MCP server — contract¶
The post-implementation contract for iiiris's Model Context Protocol server
(roadmap 2.0-era platform glue). Operator/consumer how-to lives in
../mcp.md; this file is the durable "what this subsystem
guarantees" a re-implementation must satisfy.
What it does¶
iiiris exposes its read-only IIIF capabilities to MCP hosts (Claude
Desktop/Code, the Claude API remote-MCP connector) over a single Streamable
HTTP endpoint at /mcp. An agent can browse a source, read image metadata,
render image regions (returned as pictures), and read Presentation
manifests/collections — as MCP tools plus a manifest resource template.
The surface is off by default and enforces the same IIIF Auth as the Image API.
Surface¶
HTTP route¶
| Method | Path | Purpose |
|---|---|---|
| POST/GET/DELETE | /mcp |
MCP Streamable HTTP endpoint (the SDK handler dispatches by method) |
Mounted only when mcp.enabled.
Config¶
mcp.enabled is the only field; it maps to server.Deps.MCPEnabled. Off by
default (a new protocol surface and dependency).
Tools¶
| Tool | Input | Result |
|---|---|---|
browse |
path (empty = root) |
JSON entries {identifier, name, type}, type ∈ image|collection |
get_image_info |
identifier |
JSON {identifier, width, height, formats, qualities, maxWidth, maxHeight} |
get_region |
identifier, region, size, rotation, quality, format (IIIF Image API 3.0 grammar; empty → full/max/0/default/jpg) |
an MCP image content block |
get_manifest |
identifier |
Presentation JSON (stored served as-is, or derived) |
Resources¶
A resource template iiiris:///presentation/{+identifier} (RFC 6570
reserved expansion, so the identifier may contain slashes). Reading a matching
URI returns the manifest as application/ld+json.
Public Go API — internal/mcp¶
The only consumer of github.com/modelcontextprotocol/go-sdk (pinned).
Pure protocol glue over a Backend interface the server layer implements:
NewHandler(backend Backend, version string, baseURL func(*http.Request) string) http.HandlerBackend—Browse/ImageInfo/Region/Manifest, each taking the originating*http.Request; plus theEntry,ImageInfo,RegionSelectortypes.
Contracts¶
- Off by default, opt-in.
/mcpmounts only whenmcp.enabled: true. Nothing undermcp:is required; the zero-config, Image, Presentation, and Content-State paths are unaffected whether MCP is on or off. - Single SDK consumer.
github.com/modelcontextprotocol/go-sdkis imported only byinternal/mcp(mirrorsgovips→internal/image,prometheus→internal/metrics). The version is pinned; SDK/spec churn is contained to this one package. - Read-only, stateless. No tool mutates state. The endpoint runs in the SDK's stateless Streamable HTTP mode (no session tracking).
- Tools reuse the IIIF core. Tool handlers wrap the existing
resolve/probe/render/list and Presentation serve/derive primitives — they do
not re-derive IIIF behaviour.
get_regionenforces the same pipeline limits (maxWidth/maxHeight/maxArea) as the Image API; identifiers returned bybrowseare the identifiers the other tools accept. - Auth is enforced, not bypassed. Every tool and the resource read route
through the configured
auth.Authorizer, evaluated against the credentials on the/mcprequest (an MCP host presents its IIIF access token as aBearertoken or session cookie — the same token the Image API accepts). No separate MCP credential, no extra config. A gated identifier is denied (get_image_info/get_region/get_manifestreturn an error result);browseomits entries the caller can't access. With the zero-configAllowAllauthorizer nothing is gated. - Per-request server. The MCP server is rebuilt per HTTP request (in the
Streamable HTTP
getServerclosure), so each tool/resource handler closes over that request's public base URL (for canonical URLs) and its credentials (for auth).internal/mcpforwards the request; the server-sideBackendowns authorization. - Manifest resource ≡ tool. The
iiiris:///presentation/{+identifier}resource read reusesBackend.Manifest, so it is authorised and derive-capable identically toget_manifest; no duplicated logic. - Honesty gate. A source without listing support reports a
browseerror rather than an empty listing; capabilities advertised (get_image_infoformats/qualities) come from the same single-sourced v3 slices info.json uses.
Out of scope¶
- Write tools (ingest, annotate) — stateful; roadmap Phase 3.
- stdio transport — iiiris is a networked server; only Streamable HTTP is served.
- Prompts primitive — no templated-workflow surface is offered.
- Presentation 2.1 over MCP —
get_manifestand the manifest resource emit 3.0 only. - Full-tree resource enumeration — manifests are addressable via the
template; discovery of which identifiers exist is via
browse, not a server-enumerated resource list. - MCP client — iiiris is an MCP server; it does not call out to MCP servers.