Token Offset for developers

Token Offset runs a hosted MCP server, so Claude, ChatGPT, Cursor and other assistants can read and run a Token Offset account for the person who signs in. Agents that sign people up or report usage on their behalf use the agent protocol, which is plain HTTP with an agent key. Both are below.

https://mcp.tokenoffset.com/mcpStreamable HTTP

Overview

The server speaks Streamable HTTP and is stateless. There is nothing to install or run. A client connects to the address above, the server answers 401 with a pointer to its sign-in, and the client opens a Token Offset page where the person signs in with their email and approves the app.

MCP serverAgent protocol
ForA person using their own assistantAn agent product acting for many people
Addresshttps://mcp.tokenoffset.com/mcphttps://api.tokenoffset.com/api/agents/*
Sign-inOAuth 2.1, the person's own accountAgent API key, plus the person's approval per link
Reach24 tools over one accountAccounts that approved the agent
SpecTool reference/agents

Things an assistant can do once connected: check the monthly estimate and where it comes from, move to a different usage band or a custom amount, cancel or resume, change the monthly support add-on, read billing, page through or export offset history as CSV, log tokens an agent used, refresh or remove an estimate source, and revoke agents and other connected apps. Adding a card and pasting a provider admin key stay in the browser, so tools that need them return a link to the right Settings page.

Quickstart

You need a Token Offset account. If you don't have one, the sign-in page creates it from your email. Every client below ends with the same Token Offset approval page.

Claude

  1. 1In Claude, open Settings, then Connectors, and choose Add custom connector.
  2. 2Name it Token Offset and paste https://mcp.tokenoffset.com/mcp.
  3. 3Choose Connect. Claude opens Token Offset, where you sign in and approve it.

Custom connectors work in Claude on the web, desktop and mobile once added. On Team and Enterprise plans an owner may need to add the connector first.

ChatGPT

  1. 1In ChatGPT settings, open Apps and Connectors, then Advanced settings, and turn on Developer mode.
  2. 2Back in Apps and Connectors, choose Create. Name it Token Offset, paste https://mcp.tokenoffset.com/mcp and pick OAuth.
  3. 3Save, then sign in and approve on the Token Offset page that opens.

Developer mode is available on paid ChatGPT plans. ChatGPT asks before it runs a tool that makes changes.

Cursor

Add it to ~/.cursor/mcp.json, or to .cursor/mcp.json in a project. Cursor asks you to sign in the first time it connects.

~/.cursor/mcp.json
{
  "mcpServers": {
    "tokenoffset": {
      "url": "https://mcp.tokenoffset.com/mcp"
    }
  }
}

VS Code

Add it to .vscode/mcp.json in a workspace, or run MCP: Add Server from the command palette and pick HTTP. VS Code shows a sign-in prompt on first use.

.vscode/mcp.json
{
  "servers": {
    "tokenoffset": {
      "type": "http",
      "url": "https://mcp.tokenoffset.com/mcp"
    }
  }
}

Windsurf

Open the MCP settings from the Cascade panel, choose View raw config, and add the server. Refresh the MCP list, then sign in when Windsurf asks.

~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "tokenoffset": {
      "serverUrl": "https://mcp.tokenoffset.com/mcp"
    }
  }
}

Claude Code

Terminal
claude mcp add --transport http tokenoffset https://mcp.tokenoffset.com/mcp

Then run /mcp inside a session and pick tokenoffset to sign in.

Gemini CLI

~/.gemini/settings.json
{
  "mcpServers": {
    "tokenoffset": {
      "httpUrl": "https://mcp.tokenoffset.com/mcp"
    }
  }
}

Then run /mcp auth tokenoffset inside Gemini CLI to sign in.

Other clients

Any client that supports remote Streamable HTTP servers and the MCP authorization spec finds the sign-in on its own: add the address and connect. For a client that only runs local stdio servers, bridge it with mcp-remote, which handles the sign-in in your browser.

stdio bridge
{
  "mcpServers": {
    "tokenoffset": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://mcp.tokenoffset.com/mcp"
      ]
    }
  }
}

To try the server without an assistant, run npx @modelcontextprotocol/inspector, choose Streamable HTTP, paste the address and connect.

Sign-in and OAuth

Token Offset is its own OAuth 2.1 authorization server for public clients. A client registers itself, sends the person to the consent page, and swaps the code for tokens. You never paste a key into the assistant.

  1. 1The client calls https://mcp.tokenoffset.com/mcp and gets 401 with a WWW-Authenticate header naming the protected resource metadata.
  2. 2It reads the metadata and registers through dynamic client registration (RFC 7591) at /oauth/register.
  3. 3It opens /oauth/authorize with a PKCE challenge (S256). The person signs in with an emailed link if needed, sees who is asking, and approves.
  4. 4The client exchanges the code at /oauth/token and calls the server with the access token as a bearer.
Protected resource metadata
https://mcp.tokenoffset.com/.well-known/oauth-protected-resource/mcp
Authorization server metadata
https://mcp.tokenoffset.com/.well-known/oauth-authorization-server
Issuer
https://mcp.tokenoffset.com
Resource
https://mcp.tokenoffset.com/mcp
Endpoints
/oauth/authorize, /oauth/token, /oauth/register, /oauth/revoke
Grant types
authorization_code with PKCE S256, refresh_token
Client auth
none (public clients, no client secret)
Access token
1 hour
Refresh token
60 days, rotates on every use. Reusing an old one ends the connection.
Authorization code
5 minutes, single use
Redirect URIs
https, or http on localhost and 127.0.0.1 (any port)

Scopes

read covers the 13 tools that only look. write adds the 11 that change something, and includes read. The consent page always grants read and lets the person untick write, so a client can end up with less than it asked for. The server lists only the tools the granted scope allows, and a write tool called on a read-only connection returns a plain error.

What a connection can reach

One connection is one person's account and nothing more. Every tool looks up records through the signed-in account, so an id from another account reads as not found. Connections can't add a card, see a full card number, paste provider admin keys or rotate agent keys.

Revoking

Every connected app is listed in Settings, Agents with when it connected and when it was last used. Disconnecting one deletes the grant, and its tokens stop working on the next request. Clients can also revoke their own tokens at /oauth/revoke (RFC 7009).

Tool reference

24 tools in 5 groups. Each one carries a title and read-only or destructive hints, so clients can ask before running anything that changes your account. Amounts are in US cents, dates are YYYY-MM-DD, and band prices come from list_usage_bands.

Account

get_accountread-only

Get my account

The signed-in person's Token Offset account: email, name, member since, plan status, and how many estimate sources, agents and connected apps it has.

update_profileneeds write

Update my name

Change the display name on the account. An empty name clears it. The email can only be changed by contacting support.

  • name string, requiredNew display name, up to 80 characters. Empty clears it.
send_feedbackneeds write

Send feedback to Token Offset

Send a bug report, feature request or other note to the Token Offset team from the signed-in account.

  • kind bug | feature | other, requiredWhat sort of feedback it is.
  • message string, requiredThe feedback, in the person's words.

Plan and billing

list_usage_bandsread-only

List usage bands

The preset monthly usage bands (Casual, Worker, Agentic, Extreme) with the tokens each assumes and the suggested monthly amount.

get_planread-only

Get my monthly plan

The monthly offset plan: amount, status, next billing date, whether card billing is on, monthly support, and lifetime totals.

set_planneeds writedestructive

Set my monthly offset

Set the monthly offset amount from a usage band or a custom amount in cents ($4.99 to $10,000). Creates the plan if there is none. When card billing is on, the new amount is charged from the next invoice. 90% of each offset payment goes to Token Offset's climate partner and Token Offset keeps 10%; Token Offset is a for-profit company and payments aren't tax-deductible. Confirm the amount with the person first.

  • band casual | worker | agentic | extremeUsage band to size the plan from. Use this or amountCents.
  • amountCents integerCustom monthly amount in US cents, e.g. 500 for $5.00.
cancel_planneeds writedestructive

Cancel my monthly plan

Cancel the monthly offset plan. Card billing stops at the end of the period already paid for. Confirm with the person first.

resume_planneeds writedestructive

Resume my monthly plan

Turn a cancelled plan back on. If the paid period hasn't ended, the existing card billing simply continues.

get_billingread-only

Get my billing details

Card on file (brand, last four digits, expiry) and whether the subscription is set to end. Card changes happen on the billing page, linked in the result.

set_monthly_supportneeds writedestructive

Set my monthly support

Set the optional monthly amount that supports Token Offset itself, separate from the offset. 0 removes it. Needs card billing to be on. Applies from the next invoice. Confirm with the person first.

  • amountCents integer, requiredMonthly support in US cents. 0 removes the support line.
get_offset_historyread-only

Get my offset history

Monthly offsets and support payments, newest first, one page at a time: amount, status, dates, the tokens each period covered, and a summary of everything that matches. Simulated rows are periods before card billing was on; no money moved for them. Paid offset rows show the 90% that goes to the climate partner and the 10% Token Offset keeps. These are payments to a for-profit company and are not charitable donations.

  • from string (date)First charge date to include, YYYY-MM-DD.
  • to string (date)Last charge date to include, YYYY-MM-DD.
  • kind offset | supportOnly offsets or only support payments.
  • status paid | simulated | failed | refundedOnly rows with this status.
  • limit integerRows per page. Default 50.
  • cursor stringcontinueCursor from the previous page.
export_offset_historyread-only

Export my offset history as CSV

The same history as two CSV files (payments, and the usage behind them) plus receipt links, for a spreadsheet or bookkeeping. Narrow the dates if the export comes back truncated.

  • from string (date)First charge date to include, YYYY-MM-DD.
  • to string (date)Last charge date to include, YYYY-MM-DD.
  • kind offset | supportOnly offsets or only support payments.
  • status paid | simulated | failed | refundedOnly rows with this status.

Usage

get_usage_summaryread-only

Summarize my AI usage

Tokens reported by connected assistants today, this week and in the last 30 days, the usage synced from estimate sources, and the current plan.

get_usage_estimateread-only

Estimate my monthly usage

Projected monthly tokens from the connected estimate sources, with the suggested monthly offset. Without a source it returns the usage bands instead.

get_daily_usageread-only

Get my daily usage

Daily token totals per provider from the estimate sources, split into input, output and cache tokens with a per-model breakdown. Up to 93 days per call.

  • startDate string (date), requiredFirst day, YYYY-MM-DD (UTC).
  • endDate string (date), requiredLast day, YYYY-MM-DD (UTC).
  • provider anthropic | openai | cursor | openrouter | xaiOnly this provider.
get_usage_logread-only

Get my reported usage log

Recent token reports from assistants and agents, newest first, optionally for one session.

  • sessionId stringOnly reports with this session id.
  • limit integerHow many reports. Default 50.
report_usageneeds write

Report token usage

Add a conversation turn's token counts to the person's usage. Use it when the person wants this conversation counted toward their offset. Only counts and an optional model and session id are stored, never message content.

  • inputTokens integer, requiredUncached input (prompt) tokens for the turn.
  • outputTokens integer, requiredOutput (completion) tokens for the turn.
  • cacheReadTokens integerPrompt-cache reads, when the provider reports them. Weighted at 2% of an output token.
  • cacheWriteTokens integerPrompt-cache writes, when the provider reports them.
  • model stringModel id, e.g. claude-sonnet-5-5.
  • sessionId stringStable id for the conversation, to keep a running total.

Estimate sources

list_estimate_sourcesread-only

List my estimate sources

Connected read-only usage keys (Anthropic, OpenAI, Cursor, OpenRouter, Grok API) that feed the usage estimate, with sync status. Adding one happens in the browser, linked in the result.

refresh_estimate_sourceneeds write

Re-sync an estimate source

Pull the latest usage from one estimate source now.

  • sourceId string, requiredSource id from list_estimate_sources.
disconnect_estimate_sourceneeds writedestructive

Remove an estimate source

Remove an estimate source and delete the usage it synced. The stored key is deleted. Confirm with the person first.

  • sourceId string, requiredSource id from list_estimate_sources.

Agents and apps

list_agentsread-only

List agents on my account

Agent integrations that asked to act on the account through the agent protocol, with their approval status.

revoke_agentneeds writedestructive

Revoke an agent

Remove an agent's access to the account. Confirm with the person first.

  • linkId string, requiredLink id from list_agents.
list_connected_appsread-only

List my connected apps

Assistants and apps signed in to the account through MCP, with access level, connected date and last use. The current one is marked.

disconnect_appneeds writedestructive

Disconnect an app

Sign an assistant or app out of the account. Disconnecting the current app ends this session. Confirm with the person first.

  • appId string, requiredApp id from list_connected_apps.

Agent protocol

Agent products that act for many people register once, get an agent API key, and ask each person to approve a link by email. The full HTTP spec, with request and response bodies, is at /agents and in plain text at /agents-protocol.txt.

The same protocol is available as MCP tools. Send your agent key as Authorization: Bearer to_agent_… to https://mcp.tokenoffset.com/mcp and the server lists the agent tools below in place of the account tools. Integrations set up before OAuth keep working at https://mcp.tokenoffset.com/agent/mcp.

Agents are registered over HTTP at https://api.tokenoffset.com/api/agents/register. The owner can see and rotate the key in Settings, Agents when signed in with the email the agent was registered under.

tokenoffset_get_protocolread-only

Read the agent protocol

The plain-text Token Offset agent integration protocol.

tokenoffset_list_usage_bandsread-only

List usage bands

Preset monthly usage bands (Casual, Worker, Agentic, Extreme) with suggested offset amounts.

tokenoffset_quick_signup

Request an account for a person

Create a Token Offset account for a person and email them a link to approve this agent. No agent key needed. One email per address per hour.

  • userEmail string (email), requiredThe person's email address.
  • userName stringThe person's name.
  • agentName string, requiredProduct name shown in the approval email, e.g. Cursor.
  • agentDescription stringOne line on what the agent does.
  • agentWebsiteUrl string (url)Agent homepage.
tokenoffset_signup_user

Sign a person up

Create an account for a person under this agent and email them an approval link. Needs an agent API key.

  • userEmail string (email), requiredThe person's email address.
  • userName stringThe person's name.
  • exclusiveAgent booleanTrue when this agent is the only intended actor on the account.
tokenoffset_report_usage

Report token usage

Add a turn's token counts to an approved person's usage. Reuse sessionId to keep a running total.

  • linkId string, requiredlinkId returned by signup_user or quick_signup.
  • sessionId stringStable id for the conversation.
  • inputTokens integer, requiredUncached input tokens.
  • outputTokens integer, requiredOutput tokens.
  • cacheReadTokens integerPrompt-cache reads, weighted at 2% of an output token.
  • cacheWriteTokens integerPrompt-cache writes.
  • model stringModel id.
tokenoffset_get_usage_logread-only

Get the usage log

Token reports this agent sent for a person, optionally for one session.

  • linkId string, requiredlinkId returned by signup_user or quick_signup.
  • sessionId stringOnly this session.
  • limit integerHow many. Default 50.
tokenoffset_get_usage_summaryread-only

Summarize a person's usage

Tokens this agent reported, usage from the person's estimate sources, and their active plan.

  • linkId string, requiredlinkId returned by signup_user or quick_signup.
tokenoffset_set_plandestructive

Set a person's monthly offset

Set an approved person's monthly offset from a usage band or a custom amount. Changes what their card is charged from the next invoice.

  • linkId string, requiredlinkId returned by signup_user or quick_signup.
  • band casual | worker | agentic | extremeUsage band.
  • amountCents integerCustom monthly amount in cents.
  • source usage_estimate | preset_casual | preset_worker | preset_agentic | preset_extreme | customWhere a custom amount came from. Required with amountCents.
  • sizedForMonthlyTokens integerMonthly tokens the amount was sized for.
tokenoffset_connect_provider

Connect a provider usage key

Store a read-only usage key (Anthropic, OpenAI, Cursor, OpenRouter or Grok API) for an approved person so their usage can be estimated.

  • linkId string, requiredlinkId returned by signup_user or quick_signup.
  • provider anthropic | openai | cursor | openrouter | xai, requiredWhich provider the key is for.
  • apiKey string, requiredanthropic: Admin key (sk-ant-admin…) or Claude Enterprise Analytics key; openai: Admin key (sk-admin-…); cursor: team Admin API key; openrouter: management key; xai: Grok API management key.

Rate limits

Tool calls
60 per minute for each connected app
Client registration
60 new clients every 10 minutes across the server
Quick signup emails
1 per email address per hour
get_daily_usage
Up to 93 days per call
report_usage
Up to 50 million tokens per call
get_usage_log
Up to 200 rows per call
get_offset_history
Up to 200 rows per page, with a cursor for the next
export_offset_history
Each CSV up to about 200 KB; narrow the dates past that

Over a limit, the server answers 429 with how long to wait. Retrying straight away counts against the same window.

FAQ

Does the assistant see my prompts?
No. Token Offset works from token counts. When an assistant logs usage with report_usage, it sends numbers, a model name and an optional session id. The server has no field for prompt or reply text.
Can an assistant charge my card?
It can change what you pay each month, the same as the plan controls in the dashboard, and your saved card is billed on the usual date. It can't add or replace a card. Tools that change billing are marked, so clients that ask before running them will ask here.
How do I connect a read-only assistant?
Untick Make changes on the approval page. The assistant gets the read tools only. You can reconnect later to grant more.
My client says it can't sign in.
Check that it supports remote servers with OAuth. If it only runs local servers, use the mcp-remote bridge under Other clients. If the approval page says the link doesn't work, start the connection again from the client; codes last five minutes.
What happens to a connection when I close my account?
Closed accounts can't connect apps, and existing connections stop working.
Where is the server listed?
In the official MCP registry as io.github.jakehandy/tokenoffset. Read how we handle data in the Privacy Policy and the rules for connected apps in the Terms.
Who do I talk to?
Email support@tokenoffset.com for help, or partnerships@tokenoffset.com to build an agent integration with us.