viasocket
All articles
Integration Layer /September 7, 2026
hero-c-numeral-split.svg

How AI Agents Connect to External Tools

12 min read

A user types "reschedule my Thursday call with Priya to Monday morning." Between that sentence and a modified calendar event, roughly eleven things have to happen — and only one of them involves the model.


The model has to be told a rescheduling capability exists, in a format it can reason over. It has to pick that capability over a dozen near-neighbours. It has to emit well-formed arguments. Something has to catch that emission, find the right credential for that specific user's Google account, refresh it if it expired overnight, call the API, handle a 429, interpret a partial failure, decide whether a retry would double-book, shrink a 40 KB response into something worth spending context on, hand it back, and leave an audit trail someone can read six months later during a security review.


Ten of those eleven steps are ordinary distributed-systems work. Most writing on this topic spends its time on the one step that isn't, which is why teams keep shipping demos that work and products that don't.


This article covers the whole path. It separates the layers that are usually blurred together, explains what actually changed in MCP this year, and gives you a decision framework for choosing a connection method — with particular attention to the case most guides skip: an agent acting inside your customers' accounts rather than your own.


#

The five layers of agent-to-tool connectivity

Almost every architectural argument about agent integrations is really a category error — two people discussing different layers as though they were the same one. It helps to name them.

Layer

Question it answers

Typical technology

Who owns it

1. Tool contract

What can the agent do, and how does it express intent?

JSON Schema tool definitions, function calling

Your prompt/tool authors

2. Transport

How does the intent physically reach the tool?

Direct dispatch, MCP, hosted connectors, A2A

Your runtime

3. Connectivity

Whose credentials, against which tenant, with what scopes?

OAuth 2.1, token vault, key management

Integration layer

4. Execution

What happens on retries, timeouts, rate limits, partial failure?

Idempotency keys, queues, backoff, pagination

Integration layer

5. Governance

What was allowed, what happened, who can see it?

Policy engine, approval gates, audit log

Platform/security

Two observations follow immediately.


First, the model only participates in Layer 1. Everything below it is software you would need even if the caller were a cron job. This is why "we'll add MCP" is rarely a plan — MCP is a Layer 2 decision, and Layer 2 is not usually where the difficulty lives.


Second, the layers fail independently. An agent that picks the wrong tool has a Layer 1 problem, solved by better schemas. An agent that picks the right tool and gets a 401 has a Layer 3 problem. An agent that succeeds twice and creates two invoices has a Layer 4 problem. Teams that treat these as one undifferentiated "the agent is flaky" bucket end up tuning prompts to fix token refresh bugs.


five-layer-stack.svg
#

Layer 1 — The tool contract: what the model actually sees

An agent does not "call an API." It emits a structured request that names a tool and supplies arguments, and your code does the calling. The model's entire view of the outside world is a list of tool definitions serialized into its context window — typically a name, a natural-language description, and a JSON Schema for the parameters.


That is the whole interface. The model cannot read your API docs, inspect your database, or ask a colleague what status_id: 4 means. If it isn't in the schema, it doesn't exist.


The loop itself is simple and provider-agnostic:

  1. Tool definitions go into the request alongside the conversation.

  2. The model returns either a normal message or a tool-call block naming a tool and its arguments.

  3. Your runtime executes it and appends the result to the conversation as a tool-result block.

  4. The model reasons over the result and either answers or calls another tool.


Anthropic, OpenAI, and Google differ in field names and streaming semantics but not in this shape. Portability across models is rarely the hard part.

#

Why the description field is the real API

Tool selection is a retrieval problem dressed as a reasoning problem. When an agent picks send_message instead of create_draft, the usual cause is not model weakness — it's two descriptions that are near-identical in embedding space.


A description written for a human reads: "Creates a task." A description written for a model reads: "Creates a new task in a specific project. Use when the user wants work tracked. Do not use to update an existing task — use update_task with its id. Requires project_id; call list_projects first if you don't have one."


The second version encodes selection boundaries, prerequisites, and negative cases. Those three things do more for reliability than any amount of system-prompt tuning, because they're attached to the decision rather than sitting several thousand tokens away.

#

The tool-contract checklist

Before a tool goes into production, it should pass all of these. In practice this list catches more agent bugs than anything else on the page.

  • Verb-first, unambiguous name. create_invoice, not invoice or handle_billing.

  • Explicit negative guidance. Name the tools this one is most likely to be confused with, and say when not to use it.

  • Enums instead of free strings. status: "open" | "closed" removes a whole class of hallucinated values that free-text fields invite.

  • Prerequisites declared. If a call needs an ID the model can't know, say which tool produces it.

  • Constrained, informative output. Return the fields the agent needs to decide what's next — not the provider's full response object. A 40 KB payload costs context on every subsequent turn of the conversation, not just once.

  • Errors written for a reader, not a logger. "No project matches 'Q3 launch'. Call list_projects to see valid names." recovers. {"error":"ENOENT"} loops.

  • Idempotency stated. If calling twice is unsafe, the schema and description should say so, and the runtime should enforce it.

  • Side effects visible in the name. A tool called get_customer must not send an email.

A useful design constraint: write each definition as though it will be read once, by a competent contractor, with no ability to ask follow-up questions. That is precisely the situation the model is in.


#

Layer 2 — Transport: how the call physically travels

Once the model has emitted a tool call, something has to route it. There are four common answers, and they are not interchangeable.

#

Direct function calling

Your runtime holds a dispatch table mapping tool names to local functions. Lowest latency, fewest moving parts, complete control. It's the correct default for tools that are genuinely yours — internal services, database queries, business logic.


The cost is that every capability is compiled into your application. Adding a tool means a deploy. Sharing tools across teams means publishing a library.

#

MCP, and what changed in 2026

The Model Context Protocol standardizes the interface between an agent (client) and a tool provider (server), so the same server works with any compliant client. It is JSON-RPC 2.0 over HTTP, now stewarded by the Linux Foundation rather than any single vendor.


Most published material about MCP is now describing a protocol that no longer exists. The 2026-07-28 revision is the largest structural change the spec has had, and it is not backward compatible in several places. If your architecture notes were written before mid-2026, the following are the parts to re-check:

  • Sessions are gone. The initialize/initialized handshake and the Mcp-Session-Id header have been retired. Each request now carries its own protocol version, client identity, and capabilities inside _meta. There's an optional server/discover RPC for clients that want capabilities upfront, but it isn't required. The practical payoff: any request can land on any server instance behind a plain round-robin load balancer, with no shared session store.

  • Method and tool names travel in headers. Mcp-Method and Mcp-Name are now required on Streamable HTTP requests, so a gateway, rate limiter, or WAF can route and authorize without parsing JSON bodies. This is a meaningful operational unlock — MCP traffic can be governed with the same infrastructure as the rest of your API surface.

  • Mid-call user input works statelessly. Multi Round-Trip Requests replace the old server-initiated elicitation and sampling calls that required a held-open stream. The server returns resultType: "input_required" with the questions it needs answered, and the client retries the original call with inputResponses attached. This is what makes "confirm before this deletes data" possible without persistent connections.

  • Tool catalogs are cacheable. tools/list, prompts/list, resources/list, and resources/read now carry ttlMs and cacheScope, with deterministic ordering — which also keeps upstream prompt caches stable across reconnects.

  • Auth hardened. Clients must validate the iss parameter per RFC 9207 before redeeming an authorization code, closing an authorization-server mix-up hole. Dynamic Client Registration is formally deprecated in favour of Client ID Metadata Documents. Enterprise Managed Authorization has landed as a formal extension, giving identity providers a standard seat in the delegation chain.

  • Deprecations now come with a runway. Roots, sampling, and logging are deprecated, as is the legacy HTTP+SSE transport, with a stated twelve-month minimum window.

The strategic read: MCP has stopped being an AI-specific protocol with unusual operational requirements and become an ordinary HTTP workload. That is good news for anyone who has to run it in production, and it removes most of the "we can't operate this" objections that stalled MCP adoption in 2025.


What MCP does not do is worth stating plainly. It is a delivery protocol. It does not obtain OAuth tokens for your customers, store them, refresh them, scope them per tenant, retry failed calls, or tell you why a sync broke. Exposing tools over MCP and still needing an integration layer underneath is the normal outcome, not a sign you did it wrong.

#

Hosted connectors

Model providers increasingly host the transport themselves. OpenAI's Responses API accepts an mcp tool type with either a server_url or a connector_id plus an authorization token, and supports require_approval and allowed_tools for scoping. It is worth understanding the boundary: the platform relays a bearer token you supply on every request — obtaining that token, refreshing it, and storing it per end user remains your application's job.


This pattern is excellent for prototyping and for first-party tools. It gets uncomfortable when you need per-customer credentials, because the credential lifecycle is the part that wasn't outsourced.

#

A2A solves a different problem

Agent2Agent handles agent-to-agent delegation — one agent discovering another's capabilities via a signed Agent Card and handing off a task. Also a Linux Foundation project, v1.0 since March 2026, with adoption across the major cloud agent platforms.


A2A and MCP are complementary rather than competing: MCP connects an agent to its tools, A2A connects agents to each other. If your question is "how does my agent update a customer's CRM," A2A is not the answer. If it's "how does my agent hand a specialist subtask to a partner's agent," it is.

#

Transport comparison


Direct dispatch

MCP

Hosted connector

A2A

Best for

Your own services

Reusable tool surfaces, third-party clients

Fast integration with one model provider

Cross-vendor agent delegation

Latency

Lowest

One network hop

Provider-dependent

Highest (agent round-trip)

Works across model vendors

Yes (you own it)

Yes

No

Yes

Handles per-user auth

No

No (spec defines the flow, not the storage)

Partially — you still supply tokens

No

Discoverable by external clients

No

Yes

Within that provider

Yes (Agent Cards)

Operational cost

Low

Moderate (a service to run)

Low

Moderate


#

Layer 3 — Connectivity: the layer that actually costs money

This is where projects slip. Not because the concepts are exotic, but because the surface area is larger than it looks from the outside, and none of it is visible in a demo.

#

Two identities, one intersection rule

Every agent action involves two distinct identities:

  • The workload identity — the agent application itself, registered as an OAuth client.

  • The user identity — the human on whose behalf the action is taken.


The rule that keeps you out of trouble: an agent's effective permissions are the intersection of what the agent is allowed to do and what the user is allowed to do — never the union, and never the agent's rights alone. An agent holding a service account with broad access will happily read records the requesting user could never see, and no amount of prompting reliably prevents it. This is an access-control decision, not a model behaviour decision, and it belongs in code.


Delegated access (Authorization Code + PKCE, scoped to the individual user) is the default for anything touching user data. App-only workload credentials are for genuinely user-independent background work, and should be treated as the exception requiring justification.


Multi-hop delegation — agent calls agent calls tool — is the open edge. RFC 8693 token exchange handles a single hop cleanly; the IETF's identity-chaining work extends it to chains, and Cross App Access has begun landing in vendor products and in MCP's authorization extension. If you're building something that will face an enterprise security review in the next two years, this is the area worth tracking closely, because retrofitting delegation semantics is expensive.

#

The multi-tenant problem

Here is the fork in the road that most guides never mention.


If your agent connects to your own systems, you need one set of credentials per service. Store them in a secrets manager, rotate them, move on. This is a weekend of work.


If your agent connects to your customers' accounts — updating their HubSpot, reading their Jira, posting to their Slack — you need something categorically different:

  • An OAuth flow you can present inside your own UI, per provider, per end user

  • Encrypted, tenant-isolated storage for tokens with wildly different lifetimes and refresh semantics

  • Proactive refresh, because a token that expires mid-conversation surfaces as an agent failure to the user

  • Per-tenant rate limit accounting, since providers meter the token, not your app

  • Provider-specific scope handling, so a customer who granted read-only doesn't produce write attempts

  • Graceful revocation, because customers revoke access and the agent must degrade rather than error

  • Per-customer observability, because "it's broken" support tickets are otherwise unanswerable

Multiply by the number of providers you support. Each one has its own OAuth quirks, its own pagination style, its own idea of what a rate limit means, and its own breaking-change cadence. This — not tool calling, not MCP — is what makes agent integrations expensive.

#

The connect-to-revoke lifecycle

Design the whole arc before you build any of it:

  1. Discover — the user sees which integrations exist and what each will access

  2. Connect — OAuth consent, ideally without leaving your product

  3. Scope — which specific actions this connection permits, stored explicitly

  4. Operate — token refresh, rate limiting, error surfacing, all invisible when working

  5. Observe — per-user logs the customer's own admin can inspect

  6. Revoke — from either side, with the agent's tool list updating accordingly

connect-to-revoke-lifecycle.svg

Step 6 is the one that gets skipped and the one that shows up in security questionnaires. An agent whose tool list doesn't shrink when a customer disconnects an app is offering capabilities it can no longer deliver.


#

Layer 4 — Execution semantics

Agents retry. They retry after timeouts, after ambiguous errors, and sometimes after successes they failed to parse. Any tool with side effects needs to survive that.


Idempotency. Every mutating tool call should carry an idempotency key derived from the intent, not from the attempt. Stripe's model is the reference implementation and worth copying wholesale. Without it, a network blip becomes a duplicate charge.


Retry policy belongs below the model. Exponential backoff with jitter, in your integration layer, invisible to the agent. Letting the model decide whether to retry burns tokens and produces inconsistent behaviour across runs.


Pagination has to be bounded. An agent asked to "check all open tickets" against a 12,000-ticket queue will page until something breaks. Cap results, return an explicit has_more with a continuation token, and let the tool description say what the cap is.


Rate limits are a tenant-level concern. Providers meter per token. Ten customers on one connector means ten independent budgets, and one heavy user must not be able to exhaust another's.


Long-running work needs a different shape. Anything past a few seconds shouldn't block a tool call. MCP's Tasks extension formalizes this with a poll-based tasks/get — but the underlying pattern is older than MCP and applies regardless of transport: return a handle immediately, let the agent poll or receive a callback.


Partial failure needs a vocabulary. "Created the ticket, failed to attach the file" is a real and common outcome. If your tool returns a boolean, the agent will guess, and it will guess wrong in both directions.


#

Layer 5 — Governance and blast radius

The security model for tool-using agents is not primarily about the model. It's about what combination of capabilities you granted in a single execution path.


The sharpest available framing is Simon Willison's lethal trifecta: an agent becomes an exfiltration tool when it simultaneously has (1) access to private data, (2) exposure to untrusted content, and (3) a channel to send data outward. Each is individually reasonable. Together they mean an attacker who can plant instructions anywhere the agent reads — a support ticket, a web page, an email, a third-party API response — can direct it to fetch private data and ship it out. The model has no reliable way to distinguish instructions in data from instructions in its system prompt, and the 2026 incident record across multiple major AI productivity products bears this out.


lethal-trifecta.svg

Filtering untrusted content doesn't work reliably. Telling the model to ignore embedded instructions doesn't work reliably. What works is topology:

  • Break the triangle per execution path. An agent that reads untrusted content should not, in the same run, hold credentials to private systems and have an outbound channel.

  • Split agents by trust level rather than giving one agent everything.

  • Human approval gates on irreversible actions — sends, deletes, payments, external posts. MCP's MRTR makes this expressible in-protocol; it can equally be a wrapper in your own runtime.

  • Enumerate outbound channels honestly. Image URLs, link previews, webhook calls, and error reporting are all exfiltration paths. So is any tool that accepts a URL.

  • Log the call, not the conversation. Tool name, arguments, acting user, tenant, result status, timestamp. This is what an auditor asks for and what your own debugging depends on.


#

The tool-count problem nobody plans for

Every tool definition occupies context on every single request. Twenty tools is unremarkable. Two hundred — entirely normal once you're exposing several connectors per customer — is a real cost in tokens, latency, and selection accuracy, because near-identical tools crowd each other.


Three mitigations are now first-class, and they compose:


Deferred loading with tool search. Rather than sending every definition upfront, mark tools with defer_loading and let the model retrieve relevant ones on demand. Anthropic exposes this via a tool search beta; the trade-off is that search quality becomes the new bottleneck, and tool names and descriptions have to be written to be findable, not just understandable.



tool-context-cost.svg

Programmatic tool calling. Instead of one model round-trip per tool call, the model writes code that orchestrates several calls in a sandbox, and only the final result enters context. Anthropic's documentation reports that on agentic search benchmarks — BrowseComp and DeepSearchQA — adding programmatic tool calling on top of basic search tools improved performance by roughly 11% on average while using about 24% fewer input tokens. The canonical example is checking budget compliance across twenty employees: twenty round-trips and thousands of line items collapse into one script returning a handful of rows.


Context editing and caching. Old tool results can be cleared once they've served their purpose; stable tool definitions can be prompt-cached so you pay for them once. Neither reduces what you send — they reduce what you pay and what you carry.


The design implication: a large catalog is fine, an undifferentiated large catalog is not. Group tools by connector, name them consistently, and make sure the description of hubspot_create_contact says something salesforce_create_contact doesn't.


#

Choosing a connection method

Work down this table until a row matches. The first match is usually right.

If this is true

Use

Because

The tool is your own service, called only by your own agent

Direct function dispatch

No protocol tax, no extra hop, full control

You want external agents (Claude, ChatGPT, Cursor, a customer's own agent) to act inside your product

Expose an MCP server

Standard discovery; one surface serves every compliant client

Your agent needs one or two third-party APIs, with credentials you control

Direct API calls behind your own tools

A connector platform is overhead at this scale

Your agent needs your customers' third-party accounts, across several providers

Integration infrastructure with per-end-user auth

Token lifecycle across tenants is the actual work; it doesn't get cheaper as you add providers

You need normalized reads across many providers in one category (all CRMs, all ATSs)

Unified API

One schema beats N schemas — accepting that it flattens provider specifics

You need customer-configurable multi-step logic, not single actions

Embedded iPaaS / workflow layer

Agents are bad at orchestrating long deterministic sequences; give them one tool that runs the sequence

Another team's or vendor's agent should own a subtask

A2A

Agent-to-agent delegation with capability discovery

Two clarifications this table depends on, since the terms get used interchangeably in vendor content and shouldn't be:

  • A unified API normalizes many providers behind one schema. Excellent for reads, lossy at the edges, historically weaker on writes.

  • An embedded iPaaS lets your customers configure integrations inside your product. It solves configuration and workflow, and adds latency when an agent just needs a single action.

  • Integration infrastructure is the auth, execution, and observability layer underneath both. It's what you're building yourself if you're not buying it, whatever else you buy.


An agent product frequently needs two of these at once: low-latency single actions for the agent, plus a workflow surface for the deterministic sequences you don't want a model improvising.


#

The build-vs-buy arithmetic

Don't take anyone's number for this, including ours. Take the model and use your own inputs.

build-vs-buy-crossover.svg

One-time cost per connector

Build_initial = OAuth flow + token storage/refresh
              + endpoint mapping for the actions you need
              + pagination + rate limit handling
              + error normalization
              + sandbox account setup and testing

Most teams land somewhere between one and three engineer-weeks for a well-documented provider with standard OAuth, and considerably more for the ones that aren't — the providers with non-standard auth, undocumented limits, or per-customer API versions.


Recurring cost per connector per year

Build_ongoing = breaking API changes
              + auth/scope model changes
              + new endpoints customers ask for
              + support burden (per-customer failures)
              + on-call for silent sync breakage

The recurring line is the one that gets underestimated, because it doesn't appear in the first quarter. It's also the line that scales with customers as well as connectors: 30 connectors across 500 customers is 15,000 live credential relationships, each capable of breaking independently.


The comparison to run

Total_build  = Σ(Build_initial) + (years × Σ(Build_ongoing))
Total_buy    = platform fee + integration work on top
               + cost of gaps the platform doesn't cover
Break-even   = the connector count where Total_buy < Total_build

Three honest observations about the result:

  1. At one to three connectors, building usually wins. The platform overhead isn't worth it, and you keep full control.

  2. The curve is not linear. Build cost grows with connectors and customers; platform cost grows mostly with usage. The lines cross earlier than most teams project, typically once the recurring maintenance of the fifth or sixth connector overlaps with building the tenth.

  3. The variable that decides it is rarely cost. It's whether integrations are your product's differentiation. If customers choose you because of your Salesforce depth, own it. If integrations are table stakes that gate deals, every week spent on OAuth refresh logic is a week not spent on the thing they actually buy.



#

Six failure modes and what causes them


The agent calls the wrong tool. Layer 1. Two descriptions that don't distinguish themselves. Fix the schemas before touching the system prompt.


It works for you and fails for customers. Layer 3. You tested with one credential and shipped a multi-tenant assumption you never validated. Test with at least three tenants at different scope levels.


Duplicate records appear intermittently. Layer 4. A retry after an ambiguous timeout, with no idempotency key.


Quality degrades as you add connectors. Layer 1 crowding plus Layer 4 context bloat. Introduce deferred loading before the catalog gets large, not after.


The agent claims success when nothing happened. Layer 4. A tool that returns 200 for a partial failure, or an error message the model reads as a status update.


It passed the demo and failed the security review. Layer 5. No per-user audit trail, no approval gate on irreversible actions, and an execution path holding all three legs of the trifecta.


#

Where integration infrastructure fits

Nothing in Layers 3 through 5 is intellectually difficult. It's just relentless — a long tail of provider-specific behaviour that has to be maintained indefinitely by people who could be building your product instead.


This is the gap integration infrastructure exists to close. viaSocket is built for the customer-facing case specifically: SaaS and AI companies that need their agents acting inside their users' third-party accounts, with per-end-user OAuth, managed token lifecycle, and a connector catalog they don't maintain — either embedded into their own product UI, or exposed to their customers as a managed MCP endpoint so external agents like Claude or ChatGPT can act inside their app.


The evaluation question isn't which vendor has the longest connector list. It's narrower and more useful: which layers am I outsourcing, which am I keeping, and does the platform's model of "a user" match mine? A platform designed for internal automation and one designed for multi-tenant customer-facing integrations look similar in a demo and diverge sharply the moment you have five hundred customers with independently revocable credentials.


#

Frequently asked questions


Is MCP a replacement for APIs?

No. MCP is a description and invocation layer that sits in front of APIs. The underlying REST or GraphQL endpoint still does the work; MCP standardizes how an agent discovers what's available and calls it. You can't skip the API by adopting MCP.

MCP or function calling — which should I use?

They're different layers, so the question doesn't quite parse. Function calling is the model-side capability of emitting a structured tool call; every major model has it. MCP is a transport for delivering tools to any compliant client. You use function calling always, and MCP when you want tools reachable by clients you don't control.

How do AI agents authenticate to third-party apps?

Almost always OAuth 2.1 Authorization Code with PKCE, scoped to an individual user, with the resulting access and refresh tokens stored per user per tenant. The agent should act with the intersection of its own permissions and that user's — never with a broad service account that bypasses the user's own access controls.

How many tools can an agent handle before quality drops?

There's no universal threshold; it depends far more on how distinguishable your tools are than on the raw count. Practical guidance: below about twenty well-differentiated tools, load everything. Above that, watch for selection errors between similar tools and adopt deferred loading with tool search before the catalog becomes unwieldy.

Do I need MCP if my agent only calls my own APIs?

Probably not. Direct dispatch is faster and simpler. MCP earns its place when you want other people's agents calling your tools, or your agent calling tools you didn't build.

What broke in the 2026-07-28 MCP revision?

The protocol became stateless. The initialize handshake and Mcp-Session-Id header were removed, server-initiated requests were replaced by Multi Round-Trip Requests, and Mcp-Method/Mcp-Name headers became required. Roots, sampling, logging, and the legacy HTTP+SSE transport are deprecated with a twelve-month minimum window. Servers on the new revision may not interoperate with older clients.

Can an agent handle long-running operations?

Yes, but not inside a blocking tool call. Return a handle immediately and let the agent poll or receive a callback. MCP formalizes this as the Tasks extension; the pattern works on any transport.

What's the single biggest security risk?

Indirect prompt injection reaching an execution path that also holds private data access and an outbound channel. The mitigation is architectural — separate those capabilities across execution paths — not a prompt instruction telling the model to be careful.


Read More


What Is Embedded iPaaS? Complete Guide for SaaS Companies

How to Add Integrations to a SaaS Product: A Practical Guide

What It Actually Costs to Build an Integration (A Cost Model, Not a Range)