megaloop-mcp
v0.8.2
Published
MCP server for megaloop - drive the AI subscriptions you already pay for from an agent
Maintainers
Readme
megaloop-mcp — the megaloop MCP server
A Model Context Protocol stdio server that lets a Claude Code or Codex session drive megaloop from the terminal: link provider accounts, see how much of each account's subscription is left, watch an account drop out of the pool, read usage and traffic, and manage API keys — all as tool calls against the megaloop REST API.
Your client can show the limits of the one account it is signed into. This server shows them for
every account in your pool, side by side, and tells you which one still has headroom — ask
get_limits and you get per-account session/weekly utilization with the reset time for each.
Every tool sends your API key in the x-api-key header and nothing else. The key is read once
from the environment and is never written to a log line, an error message, or a tool result.
Get a key first
The server authenticates with a megaloop API key, and it is the same key you use for inference — there is no separate login, OAuth step or device code for MCP.
- Sign in at megaloop.dev.
- Link at least one provider account (Claude, OpenAI or Ollama) on Accounts. You can also do
this from the agent later with
start_account_link. - On Keys, mint a key. It starts
sk-ml-v1-, and you can copy it again later from its row on the Keys page. Give itread— the default isinferencealone, which serves requests but cannot see anything, so every tool here excepthelpwould answer 403. - Set it as
MEGALOOP_API_KEYbelow.
A key's capabilities decide which tools answer:
| capability | what it unlocks here |
| ---------- | -------------------- |
| read | get_status, get_limits, get_usage, get_traffic, list_accounts, list_providers, list_keys, list_pools, billing_status |
| manage | mint_key, revoke_key, pools — create_pool, set_pool_accounts, rename_pool, delete_pool — OAuth linking: start_account_link, complete_account_link — and read_transcript |
| inference | serving requests through api.megaloop.dev. Nothing in this server needs it. |
So an inference-only key already pointed at megaloop is not enough for these tools; a refusal
names the missing capability and how to mint a key that has it. Step 2 above needs manage if you
do the linking from the agent rather than the dashboard.
Configure
The server takes two environment variables:
| Variable | Required | Default | What it is |
| ------------------- | -------- | ---------------------- | ------------------------------------------------------- |
| MEGALOOP_API_KEY | yes | — | An sk-ml-v1- key. Mint one in the dashboard or with mint_key. |
| MEGALOOP_BASE_URL | no | https://megaloop.dev | Where the control plane lives. |
Without MEGALOOP_API_KEY the server refuses to start and says so on stderr.
The examples below install from npm with npx, which needs only node 20+. The published package
is a single self-contained file: it bundles its dependencies, so nothing else is downloaded.
Everything the server needs ships in the package; there is nothing to clone or build.
Claude Code — claude mcp add
claude mcp add megaloop \
--env MEGALOOP_API_KEY=YOUR_KEY \
-- npx -y megaloop-mcpClaude Code — JSON config
In your project's .mcp.json (or the mcpServers block of your Claude Code settings):
{
"mcpServers": {
"megaloop": {
"command": "npx",
"args": ["-y", "megaloop-mcp"],
"env": {
"MEGALOOP_API_KEY": "YOUR_KEY"
}
}
}
}Codex CLI
In ~/.codex/config.toml:
[mcp_servers.megaloop]
command = "npx"
args = ["-y", "megaloop-mcp"]
env = { MEGALOOP_API_KEY = "YOUR_KEY" }Example prompts
"Link my Claude account." The agent calls
list_providers, thenstart_account_linkand hands you the authorize URL. You approve in a browser and paste the code back; it callscomplete_account_linkand the account joins the pool."How much have I got left?" The agent calls
get_limitsand reads back every account's subscription windows at once:Subscription limits — 3 account(s), tightest window first. Headroom: side has the most left (88% free on its tightest window); main is closest to a limit at 94% used. - main [anthropic]: Session (5h) 94% used, resets 2026-08-06T20:10:00.000Z · Week (7d) 48% used, resets 2026-08-10T00:00:00.000Z - side [anthropic]: Session (5h) 12% used, resets 2026-08-06T20:10:00.000Z - spare [anthropic]: no limit data yet (nothing observed for this account)utilizationis a fraction in[0, 1]in the JSON block that follows;windowis an opaque provider label, so expect ones you have not seen and read them as data. An account with an emptylimitshas had nothing observed — that is not the same as zero spent."Which account should I route this through?"
get_limitsorders the pool tightest-first and names the account with the most headroom, so the answer is the last line rather than a calculation."Is any account rate-limited right now?" The agent calls
list_accounts(orget_status) and reads thehealthon each: acooling_downaccount is one that just hit a limit and dropped out.pausedcovers two different things, andhealth.resumablesays which.trueis an account somebody took out of rotation and can put back with a resume.falsemeans the provider killed its stored sign-in — no resume can fix that, and the remedy is to re-link it:start_account_link, thencomplete_account_linkwithreplaces_account_idset to the account's id. Never unlink and link again to repair a sign-in; unlinking cascades the account out of every pool it belongs to and strands its usage history."How much have I used today?" The agent calls
get_usagefor today's window and sums the per-account request and token counts. (get_usagecounts requests and tokens we served;get_limitsreports what the provider says is left of the plan. They answer different questions.)
Tools
| Tool | REST call |
| ----------------------- | ------------------------------------ |
| get_status | GET /v1/accounts + GET /v1/billing/status (composed) |
| get_limits | GET /v1/limits |
| list_accounts | GET /v1/accounts |
| list_providers | GET /v1/providers |
| start_account_link | POST /v1/accounts/link/start |
| complete_account_link | POST /v1/accounts/link/complete |
| mint_key | POST /v1/keys |
| list_keys | GET /v1/keys |
| revoke_key | DELETE /v1/keys/:id |
| get_usage | GET /v1/usage |
| get_traffic | GET /v1/requests |
| read_transcript | GET /v1/requests/{id}/transcript |
| list_pools | GET /v1/pools |
| create_pool | POST /v1/pools |
| set_pool_accounts | PUT /v1/pools/{id}/accounts |
| rename_pool | PATCH /v1/pools/{id} |
| delete_pool | DELETE /v1/pools/{id} |
| billing_status | GET /v1/billing/status |
| help | none — answers from this server |
Removing an account is deliberately absent: it deletes a stored credential for good, so megaloop requires a signed-in session and refuses an API key. Unlink from the dashboard.
get_status and list_accounts also carry each account's limits inline, so a session that
already called one of them does not need a second round trip for headroom.
Support
Questions, or something here that is wrong: [email protected].
megaloop is not affiliated with, endorsed by, or sponsored by any provider. Provider names appear only to tell you which of your own accounts is which.
License
MIT — see LICENSE. Copyright (c) 2026 AI PWRD Inc.
