← Blog

November 3, 2026 ·

Your Next API Consumer Is an Agent: One Manifest for MCP, REST and CLI

An agent-facing API needs more than an MCP adapter over REST. It needs one tool manifest from which MCP, REST, and CLI are derived. With that architecture, schemas, descriptions, and authorization have shared definitions to maintain, and agents get a first-class interface while developers and operators can keep using their own surfaces.

Why agents are a structurally different API consumer than developers

A developer reads documentation, writes deterministic integration code, and revises it when an endpoint changes. An agent selects capabilities while a task is running, using the tool definitions available in its context. That changes what the interface must explain. Names, schemas, and descriptions must support a decision at runtime, while every definition consumes tokens the model must reason over.

REST alone does not provide that discovery contract. Its inputs can be spread across paths, query parameters, headers, and bodies, while each API brings its own authorization and error conventions. Nor does REST provide a protocol-level exchange for pausing a call to request missing information. Those gaps require application code or custom adapters, multiplying the integration work as agents reach more systems. If agents are a real consumer class, their needs belong in the initial API design.

What MCP actually exposes and how agents use it

MCP provides an open, message-based standard for discovering and invoking capabilities from external servers. It exposes three primitives, which are callable tools, read-only resources, and reusable prompts. Tools dominate the practical design problem because agents invoke them to perform work. A client calls tools/list and receives tool names, descriptions, and input schemas at runtime. The model then uses those definitions to select a tool and construct its arguments.

The capability description travels with the server. A compliant client can translate it into its native function-calling format rather than requiring a developer to wire each integration separately. Unlike REST’s scattered inputs, an MCP tool accepts a single flat input schema. That constraint makes the complete argument contract available in one place, whether the underlying operation reaches a REST API, database, or filesystem.

The description is part of that contract. FastMCP can build JSON Schema from type hints, while the function’s docstring becomes the description presented to the model. A docstring therefore influences both whether the operation is selected and whether a developer understands it later. Documentation quality becomes an interface-design concern.

Why bolting MCP onto an existing REST API as an adapter produces a second-class agent experience

An independently maintained adapter creates a second version of the API contract. When a REST field changes, the MCP schema does not change automatically unless both come from a shared source. Even smaller naming differences create ambiguity. Mixing userId, id, and user_id across tools makes the model reason over distinct names for what may be the same concept. The failure is duplicated ownership.

Authorization has the same problem when REST gateway rules and MCP scope definitions are kept up to date separately. A permission change on one surface must be reproduced correctly on the other. Without that matching change, a read-only REST key can gain write access through an adapter that is out of date.

Descriptions introduce a different kind of mismatch. Human documentation is written for a reader who can follow links, use the text around them, and look into anything unclear. Copying that prose into an MCP definition does not necessarily tell a model which similar tool to choose or when not to act. A CLI built on its own also adds a third contract for operators and scripts. The fix must replace those separate definitions with shared ones, going beyond a better way to keep them in sync.

The single-manifest architecture: deriving MCP, REST, and CLI from one source of truth

The manifest defines each capability before any transport exposes it. Each entry contains a consistent verb-style tool name, a model-facing description, a flat input schema, an output schema, and an authorization scope. Names such as get_user, create_task, and list_projects express action intent. With shared output types such as User, Task, and ProjectSummary, each consumer knows what to expect from the results. The description distinguishes the operation from related tools and states when it should not be called.

Each surface then derives its contract from that definition. FastMCP or an equivalent implementation registers the MCP tools using the manifest’s types and descriptions. Zod-driven generation or an equivalent process produces the REST OpenAPI 3.1 specification without a separate authoring step. The CLI maps flags that are easy for people to use onto the same input schema and calls the same logic. Transport presentation differs, but names, types, and descriptions have one owner.

Authorization follows the same derivation rule. Each surface can have scoped keys, but the scope definitions live in one shared table within the manifest. Read-only means read-only across MCP, REST, and CLI because the permission is not redefined for each interface. When all three contracts are generated from that source, schema drift between those generated contracts is structurally excluded. A capability change propagates to every consumer.

Knit demonstrates the value of a unified schema across 180+ HR, ATS, CRM, Accounting, and other systems. Its get_employee tool returns the same normalized object whether the underlying system is Workday or BambooHR. The useful consistency comes from the shared schema. The manifest applies that principle across consumer surfaces, so an agent does not inherit differences that belong to the underlying integration.

What the July 2026 spec revision changes about deploying this architecture in production

The MCP 2026-07-28 specification release candidate, locked on 2026-05-21, describes a stateless protocol core, with final publication scheduled for July 28, 2026. Its deployment consequence is direct. A remote server that used to need sticky sessions, a shared session store, and a gateway that inspected request bodies can run behind a plain round-robin load balancer. This removes the protocol’s dependence on session-aware infrastructure, while the application retains responsibility for managing its own state.

The revision removes the initialize/initialized handshake and the Mcp-Session-Id header. Each request now carries the protocol version, client information, and client capabilities in _meta. Gateways can use Mcp-Method and Mcp-Name headers to route, rate-limit, and trace traffic. MCP therefore becomes operationally closer to REST without requiring the two interfaces to have identical request shapes.

Discovery also gains an explicit caching contract. Clients can cache tools/list responses for the duration permitted by ttlMs. In the single-manifest design, a manifest change becomes the signal to update all surfaces and invalidate that cache. Applications that need state across calls can expose handles such as basket_id or browser_id as ordinary tool arguments. The application contract keeps state in view, with no need to hide it in transport metadata.

Multi-round-trip requests can now work without a persistent connection too. A server returns an InputRequiredResult, and the client gathers the requested information before reissuing the original call with the needed payload. Any server instance can handle the retry. Together with authorization changes that align MCP more closely with OAuth and OpenID Connect deployments, these changes support shared infrastructure and policy.

Three design decisions that determine whether the agent experience is first-class or broken

The first decision is how capabilities are grouped and named. Grouping by resource and action intent gives the model a useful selection signal before it reads the full description. Distinct operations need distinct tools. If update_user and verify_user do different things, hiding both behind a flag in one overloaded tool makes it easy to use them the wrong way. The useful boundary is the set of capabilities agents can predict and compose.

Second, decide which tools each agent can see. Every exposed definition consumes context, so broad access increases both the authorization burden and the amount of text the model must evaluate. A code-review agent needs repository access, with CRM access outside its task scope. Task-scoped keys use the manifest’s scope table to make that distinction and set which tools discovery returns.

The third decision is how failures are expressed. Errors are output for the model as well as clues that help an operator work out what went wrong. “File not found at /tmp/foo.txt; check the path is correct” names both the problem and a possible recovery, while “ENOENT” leaves that reasoning unstated. A message such as “try with a smaller page size” gives the agent a basis for retrying, and an alternative-tool suggestion can guide the next selection. Names, visibility, and error text all affect how reliably tools run, even when they look like matters for documentation or support.

Where human-in-the-loop fits in an architecture built for autonomous agents

An agent-first interface does not imply unrestricted action. MCP distinguishes read-only resources from callable tools, providing a foundation for separating access to information from operations that change systems. For consequential tools, including writes to production systems, the manifest’s description should make the confirmation step explicit. The model can then anticipate approval rather than interpret the request for confirmation as an execution failure.

A tool requiring human confirmation returns an InputRequiredResult containing the prompt, which the client presents to the user before collecting an answer and reissuing the call. No persistent connection is required for that exchange. The revision also restricts server-initiated requests to the processing of an active client request, so elicitation traces back to an operation the user or agent started.

What this means for a founder or technical lead choosing their API architecture at the start of a project

For a new project, the practical starting point is the manifest, before the REST API is built. Define capabilities, model-facing descriptions, flat inputs, predictable outputs, and tool scopes there. Generate the OpenAPI specification from the manifest. Build MCP from the same definitions using FastMCP or the official Python or TypeScript SDK, and keep the CLI a thin consumer of those definitions. Use the shared scope table to issue scoped keys for each surface.

That sequence makes consistency an architectural property. It also gives technical due diligence a concrete test, namely whether MCP and REST share schemas and authorization definitions. Separate versions point to debt that began with the original design. For a pre-seed to Series A founder, choosing the pattern early is a stack-selection decision, while adopting it later requires schema reconciliation and authorization remediation under delivery pressure.

Steve Johnson used this pattern for a company’s agent-facing infrastructure, generating the MCP server, REST API, and internal CLI from one manifest and keeping schemas and authorization scopes consistent from day one. His fractional CTO practice is one way to put an embedded senior technical lead in charge of that design while the architecture can still change.

Someone must define the manifest, establish schema standards, and hold all three implementations to the shared contract. A team without that senior technical voice should bring one into the project before separate interfaces take hold. Define the manifest first, then derive MCP, REST, and CLI from it.