plimsoll trainer · 06 / discoverable contract
A model calling your run_code tool, offered to it over
MCP (Model Context Protocol, the standard an AI application uses to offer tools
to a model), has to know what the tool returns and what the functions injected into the
sandbox (its typed globals) accept. If the only source is a name, it probes blind. The fix is one document that produces every view of the
contract, and a test that fails the moment a real return stops matching it.
getLight(id) from the specgen example, as its three audiences see it:
the model reads the tool definition, the sandbox code calls the typed globals, and the
broker, the part of plimsoll that makes the sandbox's API calls, enforces the
route list. plimsoll-specgen generates all three from the same OpenAPI
document (a machine-readable description of an HTTP API), so they agree by
construction. Flip the switch to change the API
underneath them and watch which views go stale, and which check would catch it.
Tool annotations are four hints in an MCP tool definition that tell a client how a call behaves before it runs it: read-only, idempotent (calling it twice has the same effect as calling it once), destructive, and open-world (it can reach things outside your own backend). A wrong hint is worse than none: a tool that changes state but is marked read-only invites unconfirmed calls. Fill in the four hints for four tools, then check.
Derive the result shape from what the tool actually returned, not from what you assume. A field is required only when every sample has it; an absent field is unknown, not a default. Toggle a field in a sample and watch the schema follow.
The typed globals are not MCP tools, so they get no schema for free. A model needs their signatures before it writes sandbox code. Pick the delivery by what your server already registers, and keep one generated source.
A resource is data an MCP server offers at a URI for the client to read. Here, a URI such as stockroom://sandbox-api.d.ts that returns the generated .d.ts, a TypeScript declaration file (or the same facts as JSON). Best when the server already registers resources: the client discovers the globals the way it discovers everything else.
describe_sandbox_api returning, per function, the typed parameters, the return schema, a one-line description and an example. For servers with no resource surface yet.
Not both. A resource and a tool that can disagree are two sources of truth, and they will drift. Whichever you pick, it is rendered from the same document as the tool schema and the route list.
A plausible-looking schema is not a correct one, and a correct one drifts: the API changes and the description does not. Confirm the definitions against the current protocol specification once, then test every declared shape against real returns on every build.