Expose one operation through API and MCP
Share the registered behavior while keeping authentication, transport formats and evidence explicit.
Source and verification context ⌄
Source-guided
Inspect the source ↗Repository links may require access. Source inspection is separate from a clean public-package installation.
Get the shape of this guide.
Move through the ideas, inspect their relationships, or make a focused reading path. The complete guide stays below.
Start from one registry
Register the operation and bind its handler once. The REST createFetchHandler and MCP registerMcpTools implementations both call OperationSpecRegistry.executeResult. That shared invocation path is the useful connection between an API request and an agent tool call.
Read the supporting context
The adapters still serve different protocols. Share the operation's semantics and test transport-specific behavior instead of assuming their payloads will be identical.
Explore a section, then continue with the complete article below.
Start from one registry
Register the operation and bind its handler once. The REST createFetchHandler and MCP registerMcpTools implementations both call OperationSpecRegistry.executeResult. That shared invocation path is the useful connection between an API request and an agent tool call.
The adapters still serve different protocols. Share the operation's semantics and test transport-specific behavior instead of assuming their payloads will be identical.
Change the entry point. Keep the meaning.Trace the mechanism · 3 ways to look closer+
Follow a request to export a report through three interfaces. The useful common ground is the registered operation and its boundary.
A form helps someone make a valid request.
A person selects a report and gives a reason for the export.
Collect the report and reason, and explain errors in the person’s language.
Labels, validation messages and the way the result is presented.
The report, required reason, business implementation and configured execution checks.
The form can make a requirement clear. The server still needs to reject a request that bypasses the form.
Where this explanation comes from
An authored situation, grounded in the linked source guides. Choosing a case explores its expected responsibilities; it does not execute an operation.
Configure context for each transport
REST accepts a context factory for each request and can adapt transport approval evidence. MCP uses a tool context factory and an approval adapter. Both copy the host context for a call so request-specific evidence does not have to mutate a shared object.
Resolve the caller on the server side. A tool argument that says it is an administrator is business input, not a trustworthy authenticated subject.
| Concern | REST | MCP |
|---|---|---|
| Entry point | createFetchHandler | registerMcpTools |
| Business execution | Registry executeResult | Registry executeResult |
| Public shape | HTTP request and response | Tool schema and CallToolResult |
| Failure representation | Transport response from canonical result | isError plus canonical structuredContent |
| Approval evidence | Request-specific adapter/context | Tool-specific adapter/context |
Compare a real denied call
Use a valid request to an operation that requires approval. Supply fixture identity but omit the receipt. Each actual adapter should reach the common approval check before the bound handler can run.
Record the wire output you observe. For MCP, the implementation returns isError and includes the canonical failure in structuredContent. For REST, inspect the response produced by its result mapper. Compare the meaningful error code and effect count, not incidental formatting.
Add the human interface
A small form can call the same REST operation used by other clients. Its role is to help a person supply valid data and understand the result. It should not recreate the server's authorization logic as the only protection.
When you change a required field, update the form and inspect the MCP tool schema together. Validate both entry points: the MCP SDK may reject malformed input before it reaches the registry, while an HTTP request may fail inside the operation boundary.