TL;DR:

  • There are five distinct patterns for giving AI agents access to APIs, each with different tradeoffs around scale, maintenance, and reliability
  • OpenAPI specs work well in theory but are often too large to use directly — chunking and selective exposure are essential
  • MCP is becoming the default for external tool access but adds infrastructure; start simpler if you only have one or two integrations

Here’s something that trips up a lot of teams building AI agents: getting the agent to call an API reliably is actually the easy part. Getting it to call the right endpoints, with the right parameters, handle rate limits gracefully, and not accidentally duplicate records in your CRM — that’s where it gets interesting.

The patterns you use for API integration have a big effect on how maintainable your agent becomes as it grows. Let’s go through the five main approaches and when each one makes sense.

Pattern 1: Direct REST Calls

The simplest approach. You hardcode the API calls directly in your agent’s tool functions, write a docstring describing what the tool does, and let the LLM choose when to invoke it.

This works well when you have one or two internal APIs you control. The agent calls a function like get_customer_by_id or create_support_ticket, and you write exactly the API call you need in plain code. No abstraction layer. No schema management. Easy to debug.

The limit is obvious: it doesn’t scale. Adding a new integration means writing more hand-crafted tools. Updating an API means hunting through your tool code. For three or four integrations this is fine. For ten, it becomes a maintenance problem.

Pattern 2: OpenAPI Spec-Generated Tools

You’d think this would be the obvious solution for scale. Dump the OpenAPI spec into the agent, let it understand what endpoints exist, and have it generate the right API calls automatically.

The problem is size. A real-world OpenAPI definition for something like Salesforce, Stripe, or HubSpot can run to hundreds of thousands of tokens. If you put the whole thing in the context, the agent gets confused — it starts calling random endpoints, loses track of what it was trying to do, and generally behaves worse than if you’d given it less information.

The pattern that actually works: selective exposure. Take the OpenAPI spec, identify the ten or twenty endpoints your agent actually needs, generate typed tool wrappers for just those endpoints, and expose only those. You get the structure and type safety of spec-driven generation without the context pollution of a 500KB JSON file.

Some teams automate this with a light tool-generation script that extracts the relevant subset of the spec on each spec update. This is worth the engineering time if you’re working with multiple large external APIs.

Pattern 3: MCP Servers

Model Context Protocol has become the default for giving agents access to external tools, especially third-party services where you want a clean separation between agent logic and API credentials.

The basic idea is you wrap API functionality in an MCP server, which exposes tools through a standard interface. The agent connects to the MCP server and gets a list of available tools with their schemas. Credentials live with the MCP server, not the agent. When you update an API integration, you update the MCP server, not the agent code.

This is genuinely good for medium-to-large deployments. The infrastructure overhead is real though — you’re running additional services that need monitoring, error handling, and authentication. For a single internal API, it’s probably overkill. For a production agent that needs access to Slack, GitHub, your internal CRM, and your data warehouse, it pays off quickly.

The other advantage is reuse. An MCP server you build for one agent can be reused by another. If your organisation is running multiple agents, shared MCP servers for common services become valuable infrastructure.

Pattern 4: Unified API Platforms

Tools like Composio, Toolhouse, and similar managed platforms take the MCP idea and operationalise it across hundreds of common SaaS integrations. Instead of building and running your own MCP server for Salesforce, you connect through the platform’s managed integration, which handles authentication, versioning, and tool schema management.

This is the fastest path to a wide range of integrations. The tradeoffs are vendor dependency, data passing through a third-party service (which may matter for your compliance posture), and less control over exactly what the tools expose.

For internal data and sensitive APIs, you’ll probably still want custom tooling. For commodity integrations like Slack notifications, calendar access, or Airtable reads, a managed platform removes a lot of plumbing.

Pattern 5: Event-Driven Tool Calls

This one’s slightly different — rather than the agent invoking an API synchronously and waiting for a response, it triggers a long-running operation and then receives results asynchronously through webhooks or a queue.

This pattern matters for real-world workflow automation where API calls take time: kicking off a background job, submitting a report for processing, initiating an order that goes through multiple stages. A synchronous tool call that times out after thirty seconds is going to fail on these.

The pattern involves the agent triggering the operation, receiving a job ID or correlation token, and then either polling (manageable for short operations) or having results delivered to the agent via a webhook callback. This needs to be designed into your agent’s state management from the start — retrofitting it later is painful.

What Breaks in Production

Regardless of which pattern you use, a few things bite everyone in production.

Rate limits hit harder than expected when agents run at any volume. You need exponential backoff with jitter, plus awareness of the specific limits for each API you’re calling. Some APIs have per-second limits, some per-minute, some per-day. Build this into your tool wrappers from the start.

Idempotency matters for any write operation. If the agent retries a failed call, you don’t want it creating two orders, two tickets, or two records. Most good APIs provide idempotency keys — use them. For APIs that don’t, you’ll need your own deduplication layer.

Schema drift is an underrated problem. APIs update. What worked against the OpenAPI spec in March may behave differently in October when a new required field was quietly added. A lightweight integration test that runs against a staging environment on a schedule catches this before it breaks production.

The integration pattern itself matters less than the reliability engineering around it. A well-built direct REST integration beats a badly-built MCP server every time.