Skip to main content
Glama
README.md
# Code Mode for any API

![GitHub's whole API in 677 tokens instead of 427,509](docs/img/hero.png)

**Give your AI agent a whole API for under 1,000 tokens.**

**New to this?** Get the step-by-step setup and a copy-paste AI prompt at [jamesrowdy.com/tools/code-mode](https://jamesrowdy.com/tools/code-mode/?utm_source=github&utm_medium=readme&utm_campaign=code-mode).

Most MCP servers give your agent one tool per endpoint. GitHub's API has 1,259 endpoints, so the agent reads about 427,000 tokens of tool definitions before it does anything. That is twice the size of a 200K context window.

Code Mode, the approach [Cloudflare published](https://blog.cloudflare.com/code-mode-mcp/) for its own API, swaps all of that for two tools:

1. **search**: the agent writes a few lines of JavaScript that look through the API's OpenAPI spec and find the endpoints it needs.
2. **execute**: the agent writes a small program that calls those endpoints, loops, filters and returns only the answer.

The spec stays on your machine, and the agent only sees what its code returns.

This tool does that for **any API with an OpenAPI spec**, and shows you the token count before and after.

<p align="center"><img src="docs/img/demo.gif" width="420" alt="The AI writes one small program, it runs in a sandbox, and only the answer comes back"></p>

## Token counts

Measured on 5 Nov 2026 with `code-mode count <api>`:

| API | Endpoints | One tool per endpoint | Same, required inputs only | Code Mode | Smaller by |
|---|---:|---:|---:|---:|---:|
| GitHub | 1,259 | 427,509 | 87,236 | **677** | 631x |
| Stripe | 612 | 437,776 | 31,821 | **653** | 670x |
| Cloudflare | 3,767 | 1,540,853 | 258,272 | **650** | 2,371x |
| OpenAI | 388 | 431,488 | 20,587 | **634** | 681x |
| Vercel | 482 | 170,044 | 29,109 | **648** | 262x |

- **One tool per endpoint** is what most OpenAPI to MCP converters build: every endpoint as a tool, with its inputs and their schemas filled in.
- **Required inputs only** strips each of those tools down to what it must have. It is the smallest that approach can get.
- **Code Mode** is the exact tool list this server sends.

Tokens are counted with OpenAI's o200k tokenizer. Cloudflare's own post counted 1.17 million tokens for 2,500+ endpoints. The spec downloaded on 5 Nov 2026 has 3,767, so the count here is higher.

## Quick start

You need [Node.js](https://nodejs.org) 20 or newer.

See the numbers for any built-in API:

```sh
npx -y github:jamesrowdyy/code-mode count github
```

This also downloads and caches the spec, so your agent starts the server fast the first time.

### Add it to your agent

**Claude Code**

```sh
claude mcp add github-api -- npx -y github:jamesrowdyy/code-mode github
```

**Codex**

```sh
codex mcp add github-api -- npx -y github:jamesrowdyy/code-mode github
```

**Cursor, Hermes Agent, Claude Desktop or any other MCP app**: add a stdio server with command `npx` and args `["-y", "github:jamesrowdyy/code-mode", "github"]`.

Swap `github` for `stripe`, `cloudflare`, `openai`, `vercel`, or a link to any OpenAPI spec.

### API keys

The server reads your key from an environment variable and adds it to each request itself. Pass it when you add the server, for example `claude mcp add stripe-api -e STRIPE_API_KEY=rk_live_... -- npx -y github:jamesrowdyy/code-mode stripe`.

| API | Variable | Notes |
|---|---|---|
| github | `GITHUB_TOKEN` | Optional. If you are logged in with the `gh` CLI, it uses that login. |
| stripe | `STRIPE_API_KEY` | Use a [restricted key](https://dashboard.stripe.com/apikeys) with read access only. |
| cloudflare | `CLOUDFLARE_API_TOKEN` | Make a read-only [API token](https://dash.cloudflare.com/profile/api-tokens). |
| openai | `OPENAI_API_KEY` | |
| vercel | `VERCEL_TOKEN` | |

### Any other API

```sh
# The spec says where the API lives
npx -y github:jamesrowdyy/code-mode https://petstore3.swagger.io/api/v3/openapi.json

# A local spec, with its address and key
npx -y github:jamesrowdyy/code-mode ./openapi.yaml --base-url https://api.example.com --token-env EXAMPLE_API_KEY
```

The key goes in an `Authorization: Bearer` header by default. Use `--auth header:X-Api-Key`, `--auth query:api_key` or `--auth none` for APIs that do it differently.

## Safe by default

- **Read-only.** Only GET requests go out. Start the server with `--allow-writes` if you want your agent to create, change or delete things.
- **Your key never enters the AI's code.** The code runs in a QuickJS sandbox (WebAssembly) with no network, files, environment variables or modules. Its only way out is `api.request()`, which the server sends to the API's own address and signs with your key on the way out.
- **Limits.** Each execute call gets 30 seconds and 100 requests, and a memory cap. Results over about 6,000 tokens are cut off with a note telling the agent to return less.

## What your agent writes

Asked "how many pull requests were merged into cloudflare/mcp in the last 30 days, who merged them, and what were the latest three?", Codex used only these two tools. It made 5 calls, and its answer (71 merged) matched the `gh` CLI. A search call looks like this:

```js
async () => ops
  .filter(o => /pull request/i.test(o.summary) && o.method === 'GET')
  .map(o => o.method + ' ' + o.path + '  ' + o.summary)
```

And an execute call:

```js
async () => {
  const pulls = await api.request({
    method: 'GET',
    path: '/repos/{owner}/{repo}/pulls',
    params: { owner: 'cloudflare', repo: 'mcp' },
    query: { state: 'closed', per_page: 100 },
  });
  const merged = pulls.filter(p => p.merged_at);
  return { merged: merged.length, latest: merged.slice(0, 3).map(p => p.title) };
}
```

## Commands

```
code-mode <api> [options]        Start the MCP server (your agent runs this)
code-mode count <api> [options]  Show the tokens before and after
code-mode list                   Show the built-in APIs

Options:
  --base-url URL     Where requests go, if the spec does not say
  --token-env NAME   Environment variable that holds the API key
  --auth TYPE        bearer (default), header:NAME, query:NAME or none
  --header "K: V"    Extra header on every request (repeatable)
  --allow-writes     Allow POST, PUT, PATCH and DELETE (off by default)
  --timeout SEC      Time limit per execute call (default 30)
  --max-requests N   Request limit per execute call (default 100)
  --name NAME        Display name for the API
  --refresh          Download the spec again instead of using the cache
  --json             With count: print JSON
```

Specs are cached in `~/.cache/code-mode` and refreshed in the background once a day.

## Credit

Code Mode is Cloudflare's idea, from their post [Code Mode: give agents an entire API in 1,000 tokens](https://blog.cloudflare.com/code-mode-mcp/) and their [server for the Cloudflare API](https://github.com/cloudflare/mcp). This project applies the same idea to any OpenAPI spec. It is not affiliated with Cloudflare.

## Development

```sh
git clone https://github.com/jamesrowdyy/code-mode
cd code-mode
npm install
npm test
```

## License

MIT. Made by [James Rowdy](https://jamesrowdy.com/tools/?utm_source=github&utm_medium=readme&utm_campaign=code-mode). More free tools at jamesrowdy.com/tools.