Connect Your Agent to the Hosted Stripe MCP Server (mcp.stripe.com): OAuth, the 14 Tools, and a Safe Setup — Cesar Ayala
← All posts

Connect Your Agent to the Hosted Stripe MCP Server (mcp.stripe.com): OAuth, the 14 Tools, and a Safe Setup

Point an MCP client at https://mcp.stripe.com and authenticate with OAuth (recommended, more secure — granular, user-based) or a restricted API key as a Bearer token (Authorization: Bearer rk_...). The hosted server exposes ~14 tools — payment links, invoices, refunds, resource search — so your agent acts on Stripe without you writing the tool code.

The short answer: point your MCP client at mcp.stripe.com

To connect an AI agent to the Stripe MCP server, point any MCP client at https://mcp.stripe.com and authenticate with OAuth (recommended — granular, user-based permissions) or a restricted API key as a Bearer token (Authorization: Bearer rk_...) for unattended agents. The hosted server exposes around 14 tools, so your agent acts on Stripe with no tool code. This is the companion to the Stripe Agent Toolkit post: same safety spine, different delivery mechanism.

The one thing to internalize before you connect anything: the agent is acting on your own Stripe account. That is the opposite flow from the shopper-facing Shared Payment Token work — here a model you don’t fully control is holding the keys to money that is already yours. So the real content of this post is not “how do I connect it” (that’s two commands). It’s “how do I connect it so that a prompt-injected agent can’t drain the account.”

What the Stripe MCP server is (and hosted vs. the embedded Agent Toolkit)

Stripe ships two supported paths for giving an agent the ability to transact, and they are gated by the same primitive.

  • The Stripe Agent Toolkit — a library you embed inside your own agent process (@stripe/agent-toolkit on npm, stripe-agent-toolkit on PyPI). You import it, hand it a key, and declare which actions to expose as function-calling tools. It plugs into the OpenAI Agents SDK, LangChain, CrewAI, and the Vercel AI SDK.
  • The hosted Stripe MCP server — a remote server, run by Stripe, that your MCP client connects to over HTTP at https://mcp.stripe.com. You write no tool code and maintain no dependency; you point a client at a URL and authenticate.

Both are bounded by a Restricted API Key — the load-bearing safety primitive we’ll come back to in every section. If you’re deciding between the two, the toolkit is for teams building a bespoke agent runtime; the hosted server is for connecting an existing MCP client (Claude Code, Cursor, an internal agent) to Stripe fast. For the general pattern of wiring an agent to external systems, see connect an AI agent to your data with MCP.

Hosted MCP (mcp.stripe.com)

  • No tool code, no dependency to maintain
  • OAuth or rk_ Bearer auth
  • Connect any MCP client in one command
  • Best when you already have an MCP client

Embedded Agent Toolkit

  • A library inside your own agent
  • You declare the exposed actions in code
  • OpenAI SDK / LangChain / CrewAI / Vercel
  • Best when you own the agent runtime

The ~14 tools it exposes — check the docs, not this list

As of 2026-07-06 the hosted server exposes around 14 primary MCP tools, which fan out to roughly 40+ underlying API methods. The tools you’ll see include:

  • stripe_api_search — search across Stripe resources
  • stripe_api_read — read a resource (a customer, an invoice)
  • stripe_api_write — create or update a resource
  • create_refund — issue a refund (a money-moving action)
  • search_stripe_resources — resource lookup
  • stripe_report — pull reporting data

The supported methods cover creating and listing customers, payment links, invoices, refunds, and subscriptions. Treat this list as a snapshot, not a contract. The count changes as Stripe ships. When you connect, enumerate the tools your client actually received (every MCP client can list a server’s advertised tools) and build your allow-list from that, not from a blog post. The official MCP docs are the ground truth for the current tool set.

OAuth vs. a restricted-key Bearer token: which one, and why

Two auth methods, and the choice is a security decision, not a convenience one.

OAuth is the default and the recommendation. Stripe’s own framing: OAuth is “more secure than using your secret key because it allows more granular permissions and user based authorization.” A user authorizes the client through a browser consent flow, the grant is tied to that user, and it can be scoped and revoked without rotating a shared secret. For anything user-facing — an internal tool a teammate signs into, a product feature — OAuth is the answer.

A restricted API key as a Bearer token is for autonomous agents that run headless, with no human to complete a consent flow. You pass an rk_ key as Authorization: Bearer rk_.... This is where the Restricted API Key does its real work.

Here is why the rk_ prefix matters more than any other detail in this post. A secret key (sk_) can do anything in your account — full read and write across every resource. A Restricted API Key (rk_test_ / rk_live_) can do only what you grant it: per-resource read / write / none permissions that you set when you mint the key. Stripe puts it plainly — “a RAK can do only what you give it permission to do.” The key is the hard cap on blast radius. Even if the agent is fully manipulated by an indirect prompt injection, it physically cannot call an API the key forbids. Never hand an agent an sk_. Read the restricted API keys docs and mint a key scoped to exactly the resources the agent touches.

Secret key (sk_) — full accountunbounded
Restricted key (rk_) — scoped writebounded
Restricted key (rk_) — read-onlyminimal
OAuth grant — user-scoped + revocablegranular

Adding mcp.stripe.com to your client: Claude Code, Cursor, VS Code

The mechanics are genuinely two commands. For Claude Code, add the server over the HTTP transport:

claude mcp add --transport http stripe https://mcp.stripe.com/

Claude Code will walk you through the OAuth flow on first use. For an autonomous setup, pass the restricted key as a Bearer header instead.

For Cursor, add an entry to mcpServers in your MCP config JSON:

{
  "mcpServers": {
    "stripe": {
      "url": "https://mcp.stripe.com",
      "headers": {
        "Authorization": "Bearer rk_live_your_restricted_key_here"
      }
    }
  }
}

For VS Code, the shape is the same under the servers key:

{
  "servers": {
    "stripe": {
      "type": "http",
      "url": "https://mcp.stripe.com",
      "headers": {
        "Authorization": "Bearer rk_live_your_restricted_key_here"
      }
    }
  }
}

Drop the headers block entirely if you’re using OAuth — the client handles the token exchange for you. Never commit an rk_ to source control; load it from an environment variable or a secrets manager. If you’d rather run your own server instead of the hosted one, the build your own MCP server walkthrough covers that path.

Wiring it into a Claude tool-use loop

If you’re driving Claude directly through the API rather than through Claude Code, MCP tools surface as normal tool-use blocks. You define tools in the tools parameter, each with a name, a description, and an input_schema (JSON Schema), and Claude decides when to call them. A minimal shape:

import anthropic

client = anthropic.Anthropic()

resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[
        {
            "name": "create_refund",
            "description": "Issue a refund for a Stripe charge. Money-moving: requires approval.",
            "input_schema": {
                "type": "object",
                "properties": {
                    "charge_id": {"type": "string"},
                    "amount": {"type": "integer", "description": "Amount in the smallest currency unit"},
                },
                "required": ["charge_id"],
            },
            "strict": True,
        }
    ],
    tool_choice={"type": "auto"},
    messages=[{"role": "user", "content": "Refund charge ch_123 for the duplicate order."}],
)

Three knobs matter for safety. strict: True enforces that the tool input validates against your JSON Schema, so a malformed or injected argument is rejected before it reaches Stripe. tool_choice controls whether Claude may call tools at all: auto lets it decide, any forces some tool, tool forces a named one, and none disables tools entirely — a useful kill switch when you want a read-only turn. When Claude returns a tool_use block, your code runs the actual Stripe call — which means the confirmation gate lives in your loop, not in the model. See how to use the Claude API and build an autonomous agent with Claude Sonnet 5 for the full loop; the tool use docs are authoritative.

The safety posture: scope the grant, gate money-moving tools, log every call

Assume the agent will be tricked. An indirect prompt injection can arrive in an invoice memo, a customer note, or any text the agent reads. Your job is to make the worst case survivable. Five controls, in order of leverage:

  1. Scope the credential to least privilege. Mint an rk_ (or an OAuth grant) that can touch only the resources the task needs — read-only wherever a write isn’t required. This is the hard cap; everything below is defense in depth.
  2. Expose only the tools the agent needs. Don’t advertise create_refund to an agent whose only job is looking up invoices. Fewer tools, smaller attack surface.
  3. Require human approval before money-moving actions. Refunds and payouts should be proposed by the agent and confirmed by a human or a deterministic rule — never executed straight from a tool_use block. The gate lives in your code.
  4. Prefer OAuth over a bearer secret for any user-facing app, so grants are per-user and revocable.
  5. Log every agent-initiated Stripe call — tool name, arguments, and result — so you have an audit trail when something looks wrong.
  1. Agent proposesClaude returns a create_refund tool_use block
  2. Policy checkDeterministic rule: amount, resource, and rk_ scope
  3. Human approvalA person confirms refunds and payouts
  4. Execute + logRun the Stripe call, then record name, args, result

None of this is Stripe-specific hardening you invent from scratch — it maps to the general checklist in how to secure an MCP server, and the injection scenarios are the same ones covered in securing an email/WhatsApp agent against injection. OWASP tracks prompt injection as the top LLM risk (OWASP LLM Top 10); treat the Stripe grant as the thing that keeps that risk bounded.

When the hosted MCP server beats the embedded toolkit — and when it doesn’t

Both paths end at the same restricted key, so pick on operational fit, not on security — the key bounds you either way.

Reach for the hosted MCP server when you already run an MCP client (Claude Code, Cursor, an internal agent), you want zero tool code and zero dependency to maintain, and you’re happy delegating transport and tool schemas to Stripe. It’s the fastest path from “no Stripe access” to “the agent can create a payment link.”

Reach for the embedded Agent Toolkit when you own the agent runtime and want the actions config to live in your codebase next to your tests — for example, declaring exactly one capability in TypeScript:

import { StripeAgentToolkit } from "@stripe/agent-toolkit/openai";

const toolkit = new StripeAgentToolkit({
  secretKey: process.env.STRIPE_SECRET_KEY!, // pass an rk_ here to double-bound it
  configuration: {
    actions: {
      paymentLinks: { create: true },
    },
  },
});

Here tool availability is the actions config intersected with the restricted key’s permissions — two independent limits, one in code and one in the key. That double-bounding is the toolkit’s edge for regulated or high-stakes flows. Pass an rk_ as secretKey and the key wins even if the config is wrong.

Endpointhttps://mcp.stripe.com
Auth (recommended)OAuth — granular, user-based
Auth (agents)Bearer rk_ (restricted key)
Never give an agenta secret key (sk_)
Money-moving toolsrequire human approval

Whichever path you choose, the discipline is identical: a least-privilege rk_, a small set of exposed tools, a confirmation gate on anything that moves money, and a log of every call. Connect the agent to Stripe in one command — then spend your real effort making sure a manipulated agent can’t do more than the key allows. For the broader payments context in this market, see payment gateways in Mexico and how to integrate Stripe into your SaaS.