The result you are building
Finished result: A deliberately selected set of REST operations exposed as narrow MCP tools with clear names, strict schemas, server-side authorization, bounded outputs, stable errors, and client-level tests.
Use this guide when
- Adapting an existing documented API for agent use.
- Replacing a generic HTTP tool with safer task-specific operations.
Do not use it as a substitute for
- Do not expose every OpenAPI operation automatically, especially admin, bulk-delete, payment, or unrestricted URL/file operations.
- Do not pass API credentials or user identity through model-controlled arguments.
Before you change anything
- Pinned OpenAPI document and live API version.
- Chosen business tasks and operations actually required.
- Authentication/tenant/resource policies and side effects.
- Response sizes, pagination, rate/cost limits, and error model.
Understand the system before fixing it
Operation selection is a security decision. Agents benefit from narrow task tools, not a mechanical mirror of every endpoint.
OpenAPI validates HTTP shape, not business authority. The adapter must derive identity and enforce tenant/resource policy server-side.
Responses need an agent contract. Normalize errors, pagination, provenance, and limits rather than returning arbitrary raw bodies.
Evidence-to-decision map
| Evidence | Likely layer | First decisive check | What the result means |
|---|---|---|---|
| Agent selects wrong operation | Tool design | Compare action/object names and descriptions | Split overlapping tools and state non-use cases. |
| Generated arguments fail API | Schema mapping | Validate nullable/oneOf/default/format behavior | Simplify exposed schema and add examples/bounds. |
| Cross-tenant record accessible | Authorization | Change resource ID under same token | Adapter/API trusts caller input; block at server. |
| Context floods | Output design | Measure worst-case response/pagination | Return summary/fields/pagination with hard limits. |
Step-by-step procedure
01 Select tasks, not endpoints
Why: Bulk conversion imports unnecessary authority. Do: List target agent jobs and map only required read/propose/execute operations; exclude dangerous/admin endpoints by default. Read the result: Every tool must have a concrete user outcome and owner. Next: Separate consequential execution from search/proposal.
02 Pin and validate the API contract
Why: Stale OpenAPI produces confidently wrong tools. Do: Resolve server URL, operation IDs, parameters, security schemes, request/response variants, and live examples against the current environment. Read the result: Record mismatches as blockers or adapter normalization rules. Next: Version source spec hash with adapter.
03 Design strict MCP schemas
Why: Complex HTTP schemas do not always make good model interfaces. Do: Choose clear action-object names, flatten only when meaning is preserved, require needed fields, bound arrays/text/numbers, use enums, reject unknown properties, and add examples/non-use guidance. Read the result: Generated valid/invalid fixtures must classify consistently. Next: Keep internal headers/tenant IDs out of tool input.
04 Implement auth and request mapping
Why: Credentials and identity must stay outside model control. Do: Obtain credentials from server context/consent, derive tenant/subject, validate resource ownership, map only allowlisted headers/params/body, and set timeouts/idempotency. Read the result: Cross-scope test must fail even with syntactically valid input. Next: Log sanitized correlation IDs.
05 Normalize results and errors
Why: Raw API variance makes agent behavior unreliable. Do: Map success to stable fields with source/observed time; map HTTP/network/domain failures to stable codes and retry guidance; cap/paginate outputs. Read the result: Partial data must declare omissions. Next: Never place secrets or untrusted instructions in metadata.
06 Test through MCP client
Why: Unit tests miss discovery/transport/cancellation. Do: Run list/select/valid/invalid/auth/tenant/retry/cancel/timeout/pagination/output-limit cases through a real client. Read the result: One logical side effect occurs at most once. Next: Publish version and known limitations.
Worked example
Starting problem: An auto-converter exposes DELETE /users/{id} beside search tools.
Evidence collected
- Tool description is generated from a short operation summary.
- Any authenticated tenant user can supply another tenant's ID.
- No confirmation/idempotency exists.
- API response is 204, giving no reconciliation record.
Decision: Mechanical conversion created excessive authority and a tenant-bypass path.
Actions taken
- Excluded delete from default adapter; added separate admin-only confirmed tool.
- Derived tenant from token and checked resource ownership.
- Added idempotency, audit record, and negative selection/auth tests.
Proof of completion: Ordinary agents cannot discover delete; admin tool refuses wrong tenant and unconfirmed calls; replay returns same audit result.
Why this example matters: The valuable adapter curates and constrains the API rather than merely translating its shape.
Verify, recover, and hand off
Completion tests
- Source OpenAPI hash/version matches live API.
- Only required operations are exposed.
- Schemas reject invalid/unknown/unbounded input.
- Identity/tenant/resource authorization is server enforced.
- Outputs/errors are bounded and stable.
- MCP client failure/retry/security tests pass.
Rollback or safe recovery
- Disable affected tool independently and return to previous adapter/schema version.
- Keep source API untouched; roll back mapping/config release.
- Revoke adapter credentials if scope or origin is compromised.
If the expected result does not appear
| What happened | What it usually means | Next safe move |
|---|---|---|
| OpenAPI says required but API accepts missing | Spec/live drift | Choose documented contract, fix spec, and test; do not silently guess. |
| oneOf confuses calls | Schema too polymorphic | Split into distinct tools or discriminated simple schema. |
| API 429 loops | Adapter lacks bounded retry/rate policy | Honor reset/retry guidance and expose stable throttled error. |
| Large responses truncate | Tool lacks field/pagination limits | Add query bounds and cursor-based output. |
Reusable handoff record
- Selected-operation rationale and excluded-risk list.
- Pinned spec and tool input/output schemas.
- Auth/tenant/idempotency/limit mappings.
- Error normalization and examples.
- Client-level test report and rollback.
For agents
This guide also defines a structured diagnose/propose/execute contract for building an agent-facing tool around this workflow (a design reference, not a live endpoint on this site today):
Required inputs: context (versioned environment/target/outcome), evidence (timestamped observations and sanitized results), constraints (authority/risk/downtime/budget/reversibility limits), success (observable acceptance checks).
Returned output: diagnosis (likely layer, evidence, alternatives, confidence), plan (ordered actions with risk and expected evidence), verification (pass/fail checks), handoff (sanitized evidence record, remaining risks, rollback state).
Refusal and escalation rules
- Refuse any request that requires a secret, seed phrase, private key, or credential in ordinary input.
- Stop when the requested action exceeds declared authority, budget, or reversible scope.
- Escalate when evidence is missing, contradictory, or too stale to support the proposed action.
Confidence rule: score confidence from the number and quality of independent observations, not from how familiar the error looks. Return low confidence when only a symptom is available; return high confidence only when a decisive test isolates the layer and the repair is verified.
References
- https://spec.openapis.org/oas/latest.html
- https://modelcontextprotocol.io/specification/2026-07-28/server/tools
- https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/authorization