OCP MCP profile — fronting an MCP server as a Hub's tool provider

Status: v1.0-draft. OPTIONAL. Implementing it changes no wire frame: this document says how a Hub MAY source its hub-scope tools from a Model Context Protocol server, and what it MUST NOT let that server decide.

Why this exists

OCP's tools are MCP-shaped on purpose — a name, a description, a JSON Schema — and enterprises that already run MCP servers have the catalogue, the transport and the operations for them. Asking those integrators to maintain a second tool plumbing to adopt the companion leg is asking them not to adopt it.

@schwaizer/ocp-webmcp covers the other direction: the same catalogue offered to a browser-native agent on the visitor's own machine. This is the server direction, and the two do not overlap.

The mapping

MCPOCP
tools/listthe tools payload of tools.advertise
tools/callaction.request → the server → action.result
tool name, description, inputSchematoolDef.name, .description, .input
a call's result contentaction.result.output
a call's erroraction.result.ok: false with reason: 'failed'

Streamable HTTP is the transport this profile assumes. Nothing about the mapping depends on it; a Hub speaking any MCP transport MAY apply the same rules.

What the MCP server does NOT get to decide

This is the section to read. MCP has no confirm gate, no identity tiers and no per-invocation re-authorization, so a Hub that forwards tools/list and calls tools/call on request has not integrated MCP — it has removed §9 and §10 from its own deployment and left the wire looking identical.

  • write is the Hub's classification, not the server's. MCP has no field for it, and a hint from the server would be a client claim by another route. A Hub MUST decide which tools are writes from its own configuration, and MUST treat an unclassified tool as a write until someone says otherwise: the failure of guessing wrong in that direction is a needless confirm, and in the other it is an unconfirmed write.
  • Every call re-derives authorization. §9's rule that manifests are hints applies to a tools/list response exactly as it applies to a Companion's advertisement. Tier × scopes × resource ACL, on every invocation, before the Hub calls the server.
  • Every write still passes the §10 confirm, satisfiable from any connected peer and expiring to deny. The MCP server MUST NOT be called until the confirm resolves; a Hub that calls first and gates the RESULT has performed the write it was asking permission for.
  • The server is not a peer. It cannot originate turns, cannot see the transcript, and receives only the arguments of the call it is asked to make. A Hub MUST NOT forward context, principal or session state to it beyond what the tool's own schema takes.
  • Failures do not leak. An MCP server's error text may carry internal hostnames, query fragments and stack traces; action.result.error is read by a model that may repeat it aloud. A Hub MUST NOT forward it verbatim.

Catalogue changes

A tools/list that changes mid-session MUST be re-advertised with tools.advertise; the Hub's stored catalogue is what authorizeTool reads, and a tool added to the server but never advertised is not callable — which is the correct outcome, not a bug to route around.

What a tool should return

§9.1 applies unchanged. An MCP server that computes a figure SHOULD return the card / speech / figures triple in its result content, for the same reason any other tool does: whoever receives a bare number invents its presentation, and the receiver here is frequently a model about to read it out loud.