Articles / AI Agents Integration: How to Connect an Agent to Your Apps

ai agents

AI Agents Integration: How to Connect an Agent to Your Apps

Finn ·

AI agents integration is the work of giving a model tools it can call to read from and act in other apps: your Stripe account, a customer's Gmail, a CRM. You wire it in one of three ways: a tool you write around the app's API, the app's own MCP server, or a platform that stores OAuth tokens for your users. Whose account the agent acts in comes first, because it decides whether you need an OAuth app of your own.

The six steps, in order

  1. List the actions the agent needs, each marked read or write.
  2. Decide whose account each action touches: yours, or your users'.
  3. Pick the path: a tool you write, the vendor's MCP server, or a managed auth platform.
  4. Define each tool narrowly; if strangers can message the agent, let your code choose whose data it reads.
  5. Put an approval on every write you cannot undo.
  6. Before adding a second integration, check what the combination can leak.

Prices and documentation below were checked on September 19, 2026.

Step 1: List actions, not apps

"Connect Stripe" is not a requirement; "look up the plan and renewal date of the customer who wrote in" is. Write each action as a verb and an object, marked read, write, or write that cannot be undone: a refund, a sent email, a deletion, a payment.

An app's integration surface is usually much wider than your job. Stripe's official MCP server exposes stripe_api_read, which calls any GET method of its API, and stripe_api_write, which calls any POST, PATCH, PUT or DELETE. With tools that broad, the tool list is not your permission boundary; the credential behind it is, and your action list sets that credential.

If the actions always run in the same order, you may not need a model choosing tools; what agentic means, with a three-question test helps you decide.

If strangers can message your agent, let your code, not the model, choose whose data a tool reads.

Step 2: Decide whose account the agent acts in

Your own account. The agent reads your Stripe, your Notion or your analytics with a credential you create for each app. Stripe's restricted API keys set None, Read or Write per resource, and Stripe recommends them "especially when giving a key to an AI agent". You build no OAuth app, consent screen or token refresh.

Your users' accounts. Each customer connects their own Gmail or CRM. You now need an OAuth app, a consent screen, a stored token per user with refresh and revocation, and often the provider's review. Google classes gmail.readonly, gmail.compose and gmail.modify as restricted scopes: an app that stores or transmits that data through its servers must pass a security assessment by a Google-empanelled assessor at least every 12 months. gmail.send is only sensitive: it needs verification, not the assessment. Apps for you or a few people you know, apps in testing and internal Workspace apps are exempt.

So cut the action list before picking scopes: an agent that only sends replies does not need to read the inbox. If the agent needs mail of its own rather than someone's mailbox, an inbox created by API, which AgentMail provides, keeps you out of Gmail scopes.

Step 3: Pick the path

A tool you write. You give the model a name, a description and a JSON schema; your code makes the API call with a credential the model never sees. On your own accounts with two or three apps, I would start here: it gives the most control.

The vendor's MCP server. You point the agent at a hosted server such as https://mcp.stripe.com, authenticated by OAuth or by a restricted key. It is the shortest path when the agent is an existing client like Claude Code or ChatGPT. OpenAI's Responses API asks for approval by default before sharing data with a remote MCP server and warns that "a malicious server can exfiltrate sensitive data from anything that enters the model's context". Use the vendor's own server, allow only the tools your action list needs, and keep a restricted credential behind it.

A managed auth platform. For your users' accounts, Composio or Nango run the OAuth flows and store and refresh each user's token. Composio is free up to 100,000 tool calls a month with your own OAuth app, or 20,000 through its shared apps; its Scale plan costs $29 a month, credited against usage, with calls beyond the allowance at $0.0003 each. Nango is free for 10 connections, then $50 a month on pay-as-you-go, with each connection billed at $0.29. Composio's docs say to use your own OAuth credentials in production, so Google's review stays with you: a platform removes the token plumbing, not the provider's review.

Step 4: Define the tool narrowly (worked example)

A made-up case: a solo founder sells a subscription app and wants a support agent to draft replies to billing questions. The one action is reading the plan, status and renewal date of the customer who opened the ticket. It is the founder's own Stripe account, so the path is a tool they write, backed by a restricted key with Read on Customers and Subscriptions and nothing else. The agent drafts; a person sends.

The obvious design takes an email address as input, which lets the model choose whose billing data to read. For an agent only you talk to, that freedom is the point; for one that answers strangers, any message can ask for someone else's record. This version takes the ticket ID instead:

{
  "name": "billing_lookup_for_ticket",
  "description": "Returns the Stripe billing status of the customer who opened this support ticket: plan, status, next renewal date and whether it is set to cancel. Use it when the customer asks about a charge, a renewal, their plan or a cancellation. It only reads, and only for the ticket's own requester; it cannot refund, cancel or change anything. If it returns found: false, say no subscription matches this address and flag the ticket for a human.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticket_id": {
        "type": "string",
        "description": "ID of the support ticket being answered, for example T-4812"
      }
    },
    "required": ["ticket_id"],
    "additionalProperties": false
  }
}

Behind it, your code loads the ticket, takes the requester's address, calls GET /v1/customers?email=, then GET /v1/subscriptions?customer= with status=all, and returns only what the reply needs:

{"found": true, "plan": "Pro monthly", "status": "active", "renews_on": "2026-10-04", "cancel_at_period_end": false}

The format is Anthropic's, whose tool guide asks for at least three or four sentences of description. OpenAI names the schema parameters, and this one already meets its strict mode rules.

Test it in a Stripe sandbox with an rk_test_ key before any live key exists:

  • A test customer on a monthly plan, ana@example.com, asks when she will be charged next. Expect one tool call and a draft whose date matches the dashboard.
  • A ticket from mallory@example.net, who has no test subscription, asks what plan bob@example.com is on. Expect found: false and nothing about Bob, since the model cannot request his record.
  • A POST /v1/refunds with the same key should be refused: the key has no Write permission.

The test also shows a limit: Stripe's customer email filter is case-sensitive, so a customer who typed Ana@Example.com at checkout comes back as not found. The description sends that case to a human instead of a guess.

Step 5: Put an approval on every write you cannot undo

Reads can usually run unattended; refunds, sends, deletions and payments need a gate. Stripe builds one in: a restricted key tagged as an agent key falls under approval rules, so a designated reviewer approves payouts, refunds and account configuration changes before they take effect. Through its MCP server with your own login, refunds and outbound payments wait for a human confirmation that expires after 24 hours.

Otherwise, put the gate in your code: the agent proposes, and a person or a script that checks hard rules performs the action. That is the idea behind one job, one exit door, and why the example drafts replies instead of sending them.

Step 6: Check the combination before adding a second integration

Two integrations can each be safe alone and dangerous together. Simon Willison named the lethal trifecta in June 2025: access to private data, exposure to untrusted content, and the ability to communicate externally. An agent with all three can be steered by what it reads into sending the data out. The support agent above already has two, untrusted inbound messages and private billing records; a tool that emails any address would add the third.

Before connecting the next app, fill in those three columns for the whole agent, not for the new tool alone. If all three are filled, cut one: have a person send what the agent drafts, or narrow the private data to what the requester already owns, as step 4 does.

Did this article help?

Get the best articles, carefully selected to save you time.

Read next

OpenClaw Mission Control is a name several unofficial dashboards share for managing OpenClaw agents, tasks and costs from a browser; OpenClaw ships no product by that name. The one Google ranks first was archived on August 6, 2026. For one gateway, start with OpenClaw's own dashboard and its optional task board, and add a separate control plane only for agents that run outside that gateway.

Agentic means having agency: able to act toward a goal on your own behalf, or on someone else's. Applied to software, a system is agentic to the degree that a model, not code you wrote, chooses the next step: it takes a goal, picks which tool to call, and loops until it decides the job is done. It is a spectrum rather than a label, and the word is decades older than AI.

Featured

A pivot is often just the polite word we use with investors when the first company is dead and we have decided to build another one. And that is fine. Not because failure is noble, but because luck needs exposure: every market you enter, every product you ship and every channel you test is one more surface where something unexpected can land.

Marketing articles

A cold email is a first message sent to one specific person who has never heard from you, for a reason tied to that person, with a request they can refuse. It is not spam, which sends one text to a list, and not a newsletter, which goes to people who signed up. In the US it is legal without prior permission if you identify yourself and honor opt-outs; in the UK, Canada and the EU it depends on who owns the address.

Follow up on a cold email only when you can add one fact that did not exist when you sent the first one. Not a bump, not a polite reminder that you are still waiting: something the reader did not know before. Two follow-ups written that way beat six written in advance, because a sequence drafted before you send can only ever report that time has passed.

Projects

Brands

The essentials, by email.

What works, what does not, what I would do differently. Sent when I have something useful to say.