MCP and a plain API
Use the public API when your software knows what it wants: it has pagination, idempotency, versioning, webhooks and an OpenAPI description you can generate a client from. Use MCP when a *model* has to decide at runtime what to call, because MCP's contribution is discovery and descriptions written to be read by a model rather than by a developer.
What MCP actually adds#
- Runtime discovery. A client asks what tools exist and gets typed schemas back, so a model can be told what it may do without anybody hard-coding a list.
- Descriptions aimed at a model. A tool's description is part of the contract; on a plain API that text lives in documentation the caller may never read.
- One envelope. Every call has the same shape, so a client can support any server without bespoke code per endpoint.
- Resources and prompts alongside tools, so context and instructions travel through the same channel as actions.
- A single endpoint. Streamable HTTP: one URL, POST only in the 2026-07-28 revision.
None of that makes a request faster or more reliable. It makes the surface *legible to something that is deciding as it goes*, which is a real problem and not one REST was built for.
What a plain API does better#
| Need | The API gives you | MCP |
|---|---|---|
| A generated client | An OpenAPI 3.1.0 description | Schemas per tool, not a client-generation contract |
| Large result sets | Pagination, filters, stable ordering | Tools return what the tool returns |
| Safe retries | Idempotency keys and documented semantics | Retry behaviour is the client's problem |
| Being told when something happens | Outbound webhooks with signature verification | Nothing — a tool call is a call |
| Change management | Explicit versioning | A protocol revision, which is a different axis |
| Multi-step processes | Arazzo 1.1.0 workflow descriptions | You orchestrate the calls yourself |
| Event stream design | An AsyncAPI 3.1.0 description | Not applicable |
If you are writing a nightly synchronisation, a webhook consumer or a dashboard, the API is the correct answer and MCP would be a detour.
They are not two views of the same surface#
The MCP surface is a named set of tools — the public ones and the workspace ones — rather than a projection of every endpoint. A tool is chosen because it is a sensible unit of work for a model to invoke, which is not the same criterion as a resource being a sensible unit for a program to fetch.
Choosing#
Write down who decides which call to make: your code, or a model, at the moment of the request.
Result Code deciding means the API. A model deciding means MCP.
If it is a model, check whether it needs to be told when something changes.
Result It probably also needs webhooks, which are an API concern — most real integrations use both surfaces.
Authenticate for the workspace, not for the person.
Result Both surfaces are workspace-scoped and pass through the allowlist, the workspace kernel and row-level security. Neither is a side door.
Questions#
Is MCP a replacement for the API?
No, and treating it as one produces a client that reimplements pagination and retries badly. They are complementary surfaces over the same workspace-scoped services; most integrations that do anything substantial end up using the API for bulk and events and MCP for the model's own decisions.
Which is more secure?
Neither, because both go through the same three isolation layers and the same authentication requirements. What differs is the failure mode: an MCP server must validate Origin and answer 403 when it is present and invalid, which surprises browser-based clients that work elsewhere.
Can I expose Connect's tools to my own agent?
That is what the MCP server is for, with authentication that resolves to your workspace. Read building an agent on Connect safely first — a tool that can act deserves the same thought as a person who can.