An agent that can only talk is a demo. An agent that can look something up in your CRM, raise a ticket, or update a record is useful — and is also where the engineering starts. The gap between the two is mostly about access, identity and what happens when something goes wrong.
Reads and Writes Are Different Projects
Reading is comparatively straightforward: authenticate, query, return. Writing changes the risk profile entirely. A wrong answer wastes someone’s time; a wrong write creates a record somebody has to find and undo. Teams that treat both as “connect the API” discover the difference in production.
A practical progression is to ship read-only first, watch what people actually ask for, then add writes one action at a time — each with its own permission scope and its own decision about whether a human approves it.
Whose Permissions Does the Agent Use?
This is the question most often deferred and most often regretted. Two models:
- Service account. The agent holds one identity with a fixed permission set. Simple to build. The risk is that the account accumulates broad access, and every user effectively inherits it — an agent that can read all records will answer questions the asker was never entitled to ask.
- Delegated user identity. The agent acts as the person asking, inheriting their existing permissions. More work to implement, but your existing access model keeps working and the audit trail names a real person.
Delegated identity is the right default wherever the underlying system supports it, particularly for anything containing customer, HR or financial data.
Design for the Failure Modes
- The system is down or slow. The agent should say so plainly. An agent that answers from stale context during an outage is worse than one that admits it cannot reach the system.
- Ambiguous targets. Three customers share a name. The agent must ask, not guess — guessing is how the wrong account gets updated.
- Partial completion. Two of three steps succeeded. Decide in advance whether to roll back or report precisely what was done; silence here is what erodes trust.
- Repeated actions. A retry should not create a second ticket. Idempotency belongs in the design, not in an incident review.
Where MCP Fits
The Model Context Protocol gives agents a standard way to reach tools and data, which means an integration you build once can serve more than one agent or assistant instead of being wired into a single product. That is a genuine architectural benefit. It does not remove any of the questions above — an MCP server still needs scoped permissions, an identity model, audit logging and sensible failures. The protocol standardizes the plumbing, not the judgement.
What to Log
Anyone operating an agent against business systems will eventually be asked what it did and why. Record the request, the tools invoked with their parameters, what came back, what the agent did, and who approved anything that needed approval. This is not only governance — it is the only practical way to debug behaviour you cannot reproduce on demand.
A Sensible First Project
Pick one workflow with a clear owner, a real cost in staff time, and a bounded blast radius. Ship it read-only, measure whether people use it, then add the one write action that saves the most effort — with approval on it until the logs justify removing that step.
Related service: AI agent integration services
The Tool Surface Is the Real Interface
The model never sees your CRM. It sees a list of tool definitions: a name, a description, a parameter schema, and whatever the tool returns. Almost everything an agent gets wrong about your systems is traceable to that surface. A field named "status" with several possible values and no description will be misused; the same field described as "ticket state; only closed and resolved mean work has stopped" will not.
Mapping tools one to one onto API endpoints is the common mistake. An endpoint exists to be composed by a programmer who has read the documentation and can experiment. A tool has to be self contained, because the agent picks once, in production, with no chance to try the other one first. A named tool such as find_customer_by_email is chosen correctly far more often than a generic search tool with a mode parameter.
Tool count matters as well. Wrong-tool selections and repeated retries start appearing as the list grows, and the fix is usually consolidation rather than better prompting.
- Define a field allowlist per tool instead of returning whole records. A field the agent did not need is still context the model can quote back to someone.
- Return errors as text the model can act on. "This account is read-only in your region" changes the agent's next move; a bare HTTP 403 does not.
- Put units, time zones and identifier formats in the tool description rather than the system prompt. Descriptions travel with the tool to every client that loads it; prompts do not.
- Include in every search result the field that separates near-identical records, usually account number, owner, city or last activity date. A clarifying question is only useful if the payload contains something to ask about.
Writes Need a Contract, Not Just a Scope
A write tool has more to specify than its permission scope. It needs a defined unit of work, a way to name what it changed, and a stated rule for what the agent reports when the system's answer is not a clean success. Most write integrations are built with only the success path defined, which leaves the ambiguous responses to whatever the model improvises at runtime.
Idempotency in practice means the caller supplies the key, not the server. Mint it before the first attempt, derive it from the conversation turn and the parameters, and send the same value on every retry. Where the target system accepts an idempotency key, it will return the original result for a repeated key. Where it does not, the tool has to emulate that itself: record the key and the resulting record id in its own store before returning, and on a repeat key return the stored id instead of calling through.
- Return the identifier of what was created or changed, plus the URL where a person can open it. An agent that reports success without a record id cannot be checked by the person who asked.
- Distinguish "the write was rejected" from "the write may not have happened." The first is an answer. The second is an open question that requires a lookup before anything else is attempted.
- Treat a timeout as unknown rather than failed. A request that timed out may have succeeded on the server.
- Keep the approval gate outside the model. A tool that asks for confirmation inside its own response can be argued out of it across a few turns; a gate in the calling application cannot be.
Delegated Identity Is a Token Management Problem
Choosing delegated identity commits you to token handling. Each user gets an access token and a refresh token, stored encrypted and per user, and those tokens expire, rotate, or are revoked when someone leaves. Refresh happens on a schedule the agent does not control, so token expiry partway through a conversation is a state to design for rather than an error to display.
Consent is a product decision as much as a technical one. Someone has to see a screen naming the scopes and approve them, and that screen appears the first time a user asks the agent to do something real, not at deployment. The agent therefore needs a coherent first interaction with every new user, before it has any access at all.
- Request the narrowest scopes the tools actually use, and request them in separate grants per system. One broad grant makes any later reduction a re-consent event for everybody.
- Key the token cache to your own internal user id rather than an email address. Email addresses change, and a rekeyed cache silently strands the user's grant.
- Never fall back to a shared account when a user's token is missing or expired, which silently converts a delegated design into a service account design.
- Expect some systems to offer no delegated option at all. Where one leg of a workflow can only be reached by a service account, that boundary is the place to log most carefully, because it is the point where the audit trail stops naming a person.
Testing Behavior, Not Just Endpoints
Conventional tests check that a function returns the right value for a given input. Agent integrations fail somewhere else: the tool works correctly, and the model calls it at the wrong moment, with a plausible but wrong parameter, or twice. Coverage has to be written against conversations, not only against functions.
The working artifact is a fixed set of scenarios, each holding the user's actual phrasing, the tool calls the agent should make, and the answer it should end with. Run that set after every prompt change, every tool description edit, and every model version change. All three alter behavior, and only one of them looks like a code change in the diff.
- Include the negative cases: questions the agent should decline, records a given user should not be able to see, and requests that must go to a person.
- Capture real transcripts from the first day of use and promote the surprising ones into the scenario set.
- Version the scenario file alongside the tool definitions. A description edited without a matching scenario is an untested change to the interface the model reads.
When the Agent Should Read a Copy Instead
Not every question needs a live call. Reporting-style questions, such as how many open tickets by region last quarter, are slow and expensive against a transactional API and are also among the most common things people ask. An hourly or nightly extract into a warehouse table, queried by a purpose-built tool, answers those in one query instead of dozens of paged API calls. Route by question type inside the tool definitions: current state and anything the agent may act on comes from the live system, while aggregates and history come from the copy.
The copy carries obligations that do not go away. Freshness has to be visible in the answer, because "42 open tickets" is wrong in a different way than "42 open tickets as of 03:00 today," and only the second lets the reader judge whether it is good enough. The copy also has no row level security of its own: whatever the source system enforced per user must be re-implemented against the extract, or the copy quietly becomes the route around your access model.
- Point every write tool at the live system only. A write derived from a stale read is how an agent closes a ticket somebody reopened an hour ago.
- Give the copy's tools different names from the live ones, so a transcript shows at a glance which source an answer came from.
- Reconcile row counts between source and copy on a schedule. A silently failing extract looks exactly like a quiet quarter.
Frequently Asked Questions
What does connecting an agent to a business system actually mean?
It means defining a set of tools the model can call, each backed by ordinary API code that authenticates, queries or writes, and returns a structured result. The model chooses which tool to call and with what arguments; your code decides what is permitted and what comes back. It is not training a model on your data, and no records are used to change model weights. Your records travel as part of a request and come back in a response, which is why retention and logging are configuration questions rather than model questions.
What does the agent connect to, and where does it run?
It connects through whatever interface the system already exposes to other software: a REST or GraphQL API, a SOAP endpoint on older ERP installations, a database read replica, or a scheduled file exchange. The tool layer runs wherever your application runs, and the model can be a hosted API or a self-managed deployment; only the tool layer needs network reach into the business system. Where a system exposes no programmatic interface at all, the only remaining route is screen-level automation, which is brittle enough that it is worth avoiding for anything that writes.
What has to already exist before this work can start?
An integration path on each system, meaning a documented API or a supported connector, plus the ability to register an application and issue credentials for it. If delegated identity is the goal, an administrator has to be able to create the OAuth application and approve its scopes in that system. A sandbox or a restorable non-production instance is needed before any write is exercised. Systems reachable only through a shared login are worth identifying at the start, because they change the identity design for everything that touches them.
When is it worth building an MCP server rather than calling tools directly?
Direct tool calls are less machinery to build and operate when one application is the only consumer. An MCP server is a JSON-RPC service the client reaches over stdio for a local process or streamable HTTP for a remote one, so a second consumer costs a client configuration rather than another integration. Two things to settle before building one are who operates and monitors the server as a service, and how the tool contract is versioned, since tool names, parameter schemas and description text are an interface that other people's agents will depend on.
How does the integration work actually proceed?
It starts with the workflow and the real shape of each system's interface: what the API exposes, which authentication modes it supports, and where it rate limits. Read-only tools come first, then a scenario set built from how people actually phrase the request, then write actions added one at a time behind an approval step. Expect the ongoing effort after the first working version to be revising tool descriptions and error messages against real transcripts, not adding endpoints.
What do we have to decide rather than hand over?
Which single workflow goes first, whether the agent runs as a service account or as the person asking, which write actions require human approval and who is entitled to give it, and how long transcripts and tool logs are retained and who may read them. You also decide what the agent should do when it cannot reach a system: state that plainly and stop, or route the request to a person. These are questions about your business rules and your risk tolerance, and they cannot be answered from the outside.
When is an agent the wrong tool for this?
When the workflow is deterministic and high volume, meaning the same input leads to the same steps every time, a scripted integration or the system's own workflow engine does the job for less money and fails more predictably. Agents earn their cost where the input is unstructured language, the path varies with the answer, and a person would otherwise be reading and re-keying between systems. If you can write the rule down completely, write the rule down.
