# Stripe Agent Toolkit MCP Comparison

## Overview

[Stripe's Agent Toolkit](https://github.com/stripe/agent-toolkit) (2K stars, TypeScript) wraps the Stripe API as MCP tools for Claude Code, ChatGPT, Vercel AI SDK, and other agent frameworks. It is the closest architectural analog to our MCP server — both are adapter-pattern MCP servers that proxy tool calls to an existing API service rather than executing tools in-process.

---

## How Stripe's MCP server works

1. **In-process SDK calls, not HTTP proxy**: Despite the architectural similarity, Stripe executes tools in-process via the Stripe Node SDK. There is no HTTP proxy hop — the MCP server imports the SDK directly and calls `stripe.customers.list()` etc. This eliminates network latency and the need for a separate running service.

2. **Declarative tool configuration**: Tools are defined as a static configuration object with `actions`, `resources`, and `context`. The toolkit auto-generates MCP tool schemas from the Stripe API schema. Developers configure which tools to expose, not how to implement them.

3. **Multi-framework support**: The same toolkit works as an MCP server, a Vercel AI SDK tool provider, a LangChain tool, and a CrewAI tool. The MCP server is one of several output adapters — the toolkit is framework-agnostic at its core.

4. **Permission model**: Tools are gated by `actions` (create, read, update) and `resources` (customers, invoices, subscriptions). A configuration object specifies which resource+action combinations to expose. This is compile-time gating, not runtime permission checks.

---

## How our system differs

| Aspect                  | Stripe Agent Toolkit               | Coda MCP Server                                    |
| ----------------------- | ---------------------------------- | -------------------------------------------------- |
| **Execution model**     | In-process SDK calls               | HTTP proxy to Express API                          |
| **Auth**                | Stripe API key (server-side)       | Bearer token forwarded to Express                  |
| **Tool registration**   | Auto-generated from API schema     | Static `TOOL_DEFINITIONS` array                    |
| **Permission model**    | Declarative resource+action config | Domain filtering + exclusion set (COD-109 pending) |
| **Transport**           | stdio + Streamable HTTP            | stdio only                                         |
| **Concurrency**         | None (Stripe SDK handles)          | Semaphore(5) from `@coda/async`                    |
| **Error handling**      | SDK error propagation              | `ToolCallOutcome` tagged union + hints             |
| **Observability**       | None built-in                      | OTel tracing + metrics + MCP logging               |
| **Response truncation** | None                               | 100K structural array truncation                   |
| **Schema format**       | JSON Schema (auto-generated)       | Zod v4 (hand-authored with `.describe()`)          |

---

## What we are NOT adopting and why

1. **In-process execution**: Our tools require Express middleware (auth, tenant resolution, rate limiting) and per-request dependencies (Snowflake pools, Notion OAuth). Moving execution in-process would mean reimplementing the entire middleware stack in the MCP process. The HTTP proxy correctly reuses the existing stack.

2. **Auto-generated schemas**: Stripe has a formal API schema (OpenAPI) that can be mechanically converted. Our tools have business-domain semantics (GraphQL schema search, revenue overview, adjustment workflows) that require hand-authored descriptions with domain context. Auto-generation would lose the `.describe()` chains that guide AI behavior.

---

## What we are adopting

### 1. Streamable HTTP transport (future — bundle with SDK v2)

Stripe supports both stdio and Streamable HTTP transport. Their Streamable HTTP implementation enables remote access without a local stdio process. We plan to add this when SDK v2 stabilizes (est. Q3 2026), which would enable:

- Deploying the MCP server as a Fargate service
- Multi-user sessions without per-user processes
- Standard OAuth 2.1 auth instead of Bearer token copy-paste

### 2. Declarative permission gating pattern

Stripe's `actions + resources` configuration is cleaner than our current `MCP_EXCLUDED_TOOLS` string set. Their pattern of declaring what is allowed (whitelist) rather than what is excluded (blacklist) is safer by default. Our COD-109 work should consider a similar declarative permission model.

---

## Validation of our approach

Stripe validates two of our key architectural decisions:

1. **Proxy/adapter pattern is production-viable**: Stripe wraps an existing API (the Stripe API) as MCP tools, just as we wrap our Express API. The pattern is sound for security-sensitive domains where you need to reuse existing auth and middleware.

2. **Selective tool exposure**: Stripe lets you configure which tools to expose, not just expose everything. Our `CODA_MCP_DOMAINS` env var and `MCP_EXCLUDED_TOOLS` set serve the same purpose.

---

## References

- [stripe/agent-toolkit](https://github.com/stripe/agent-toolkit) (GitHub)
- Stripe docs: "Agent Toolkit — Tools for AI agent frameworks"

---

_Comparison conducted 2026-05-10._
