Use credits.dev with AI agents
The credits.dev Model Context Protocol server gives AI agents native tools to reserve, spend, and report on credits. Drop the snippet into your agent runtime and the agent will see credits-dev in its tool catalog within seconds — no SDK install required.
Local (stdio)
Best for Claude Desktop, Cursor, and the MCP Inspector. The package is published as@credits-dev/mcp-serveron npm and runs via npx.
Claude Desktop / Claude Code
Add to ~/.config/claude/claude_desktop_config.json:
{
"mcpServers": {
"credits-dev": {
"command": "npx",
"args": ["-y", "@credits-dev/mcp-server"],
"env": { "CREDITS_API_KEY": "sk_live_..." }
}
}
}Cursor
// ~/.cursor/mcp.json
{
"mcpServers": {
"credits-dev": {
"command": "npx",
"args": ["-y", "@credits-dev/mcp-server"],
"env": { "CREDITS_API_KEY": "sk_live_..." }
}
}
}Get an API key at app.credits.dev/dashboard/api-keys.
Hosted (Streamable HTTP)
Best for agent platforms that can't run subprocesses. POST JSON-RPC envelopes to https://mcp.credits.dev/mcp. Authenticate with Authorization: Bearer <key> or X-API-Key: <key>.
curl -X POST https://mcp.credits.dev/mcp \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}'The endpoint is stateless — every request instantiates a fresh credits.dev client bound to the API key on the request. Safe behind any load balancer.
Tools
Eleven tools, scoped to what an autonomous agent realistically needs. Account-scoped tools accept either accountId or externalId — agents should pass externalId.
| Tool | Description | Type |
|---|---|---|
| get_balance | Available, reserved, and total credit balance for an account. | Read |
| get_account | Account profile (id, externalId, name, email, balance, metadata). | Read |
| reserve_credits | Hold N credits before paid work. Returns reservationId. | Write |
| confirm_reservation | Settle a reservation at the actual amount used. | Write |
| cancel_reservation | Release a reservation without spending. | Write |
| deduct_credits | One-shot debit when the cost is known up front. | Write |
| record_usage | Record token-level usage tied to a transaction (for analytics). | Write |
| list_transactions | Recent debits/credits for an account. | Read |
| list_reservations | Open or all reservations for an account. | Read |
| calculate_cost | Estimate credits for a model + token counts. | Read |
| list_models | Catalog of supported models with pricing. | Read |
All write tools accept an optional idempotencyKey. Repeating the same call with the same key is safe and returns the original result.
Typical flow
The pattern that protects against runaway spend: estimate, reserve, do the paid work, settle.
// 1. Estimate the credits the LLM call will burn
const estimate = await callTool("calculate_cost", {
modelId: "gpt-4o",
inputTokens: 4000,
outputTokens: 800,
})
// 2. Reserve a buffer (~10% over the estimate is typical)
const { structuredContent: rsv } = await callTool("reserve_credits", {
externalId: "agent_writer_42",
amount: 25,
idempotencyKey: requestId,
})
// 3. Make the LLM call
const completion = await openai.chat.completions.create({ /* ... */ })
// 4. Settle at the real cost — unspent credits are released back
await callTool("confirm_reservation", {
reservationId: rsv.reservationId,
actualAmount: 22,
idempotencyKey: `${requestId}-confirm`,
})
// 5. Attribute the spend to a model
await callTool("record_usage", {
externalId: "agent_writer_42",
transactionId: rsv.reservationId,
modelId: "gpt-4o",
inputTokens: completion.usage.prompt_tokens,
outputTokens: completion.usage.completion_tokens,
})Error model
Failed tool calls return isError: true with a structured payload so the agent can react without parsing free-form text.
{
"isError": true,
"content": [{ "type": "text", "text": "Insufficient credits: requested 1000, available 50" }],
"structuredContent": {
"code": "insufficient_credits",
"status": 402,
"message": "Insufficient credits: requested 1000, available 50"
}
}| Code | HTTP | Meaning |
|---|---|---|
| insufficient_credits | 402 | Account doesn't have enough available balance. Top up or fall back to a cheaper model. |
| not_found | 404 | Account or reservation does not exist. |
| unauthorized | 401/403 | API key is missing, revoked, or doesn't have access. |
| rate_limited | 429 | Too many requests. Back off and retry. |
| validation_error | 4xx | Request parameters are invalid (e.g. missing both accountId and externalId). |
| internal_error | 5xx | Unexpected server-side failure. Safe to retry with the same idempotencyKey. |
Auth & v2
v1 uses credits.dev API keys (env var for stdio, Authorization: Bearer for hosted). MCP-native OAuth and dynamic client registration are on the roadmap once client support stabilizes.