MCP for agents

Agents burn meters faster than people do. The Argus MCP server gives them a view of every meter you track, so an agent can check its own runway, notice a provider running dry, and route around trouble — before your alert email does. It can also connect providers and create connect links; it cannot delete anything.

The v1 server

https://mcp.argus.town serves the v1 API as tools. Each tool is an operation: same name as its operation id, same arguments as the REST call (path and query parameters and body fields, flat), same results, typed errors (as a tool result with isError: true), idempotency (an idempotency_key argument) and rate limit. Send an API key or an MCP key as the bearer token. An API key sees every tool below; an MCP key sees the ones marked mcp. There is no tool for deleting, for sending events, or for creating keys and sources: those stay with a person or a source credential.

claude mcp add --transport http argus https://mcp.argus.town \
  --header "Authorization: Bearer $ARGUS_API_KEY"
providers_listread · api, mcp

List providers. The provider catalog: pricing model and whether Argus can poll the provider with a credential. Public, no key. Arguments: limit, cursor, connectable.

providers_getread · api, mcp

Get a provider. One provider with its full offering: plans, rate limits and how spend is observed. Arguments: slug*.

project_getread · api

Get the key's project. Who am I: the project this key belongs to, the key itself, what it may call, the plan, and what to do next. Arguments: none.

summary_getread · api, mcp

Spend summary. What the project is spending and what is about to run out: month-to-date and projected totals, every connection with its metrics, and advisories. Arguments: none.

connections_listread · api, mcp

List connections. Providers the project tracks, polled, pushed or both, newest first. Credentials are never returned. Arguments: limit, cursor, provider, status, origin, expand.

connections_getread · api, mcp

Get a connection. One connection. Expand `usage`, `breakdown`, `rate_limits`, `sync_runs` and `plan` for the detail view; expansions only add fields. Arguments: id*, expand.

events_listread · api

List events. The project's call ledger, newest first, paged with a keyset cursor so events sharing a timestamp are never skipped. Time-bounded: `since` defaults to 31 days before `until` (default: 48 hours ahead of now) and the window is at most 31 days. `id` and `metadata[key]=value` filters need an explicit `since` and a window of at most 7 days. By default only events with a cost or a status of 400 or above are listed; `view=all` also lists cost-less events, and filtering by `id` or `cost_provenance` always does. Every accepted event counts toward `events_this_month` on `GET /billing`, listed or not. Arguments: limit, cursor, connection, provider, model, id, status, cost_provenance, since, until, view, metadata.

spend_getread · api, mcp

Spend over time. Daily spend for the project: totals and a day-by-day series, optionally split by `provider`, `connection` or `model`. Totals are the sum of the daily rollups. `model` groups use provider-reported breakdowns where a connection has them and itemized events otherwise, so they can sum to less than the day's spend. Defaults to the last 30 days; at most 366. Arguments: since, until, granularity, group_by, provider, connection.

connections_createwrite · api, mcp

Connect a provider. Poll a provider with a credential. Argus checks the credential with the provider before storing it (encrypted; it is never returned) and queues the first sync. A repeated `label` for the same provider is a 409 `label_conflict`: rotate the credential with `PATCH /v1/connections/{id}` instead. Without a `label` an extra account gets a distinct default one. A provider the project already tracks by telemetry only (no label given) is upgraded in place (`origin: both`). At most 100 polled connections per project (telemetry-only ones are capped separately). Arguments: provider*, credential_type, secret*, label, meta, idempotency_key.

connections_updatewrite · api

Update a connection. Relabel a connection or rotate its credential. Send `secret` to rotate: it is checked with the provider, replaces the stored credential and re-queues a sync. `credential_type` and `meta` are part of the credential, so they are accepted only together with `secret` (non-secret fields you leave out of `meta` keep their stored values). A connection an operator suspended stays suspended. Credentials of AI-built connectors rotate in the app. Nothing secret is ever returned. Arguments: id*, label, secret, credential_type, meta, idempotency_key.

syncs_createwrite · api, mcp

Refresh a connection. Queue an immediate refresh of balance, usage and plan, and get a sync to poll with `GET /v1/syncs/{id}`. At most one refresh is queued per connection a minute, whatever state the last one is in: a request inside that window returns the latest sync instead of queueing another. Telemetry-only and suspended connections have nothing to poll: 409 `connection_not_pollable`. Arguments: id*, idempotency_key.

syncs_getread · api

Get a sync. One refresh, or one scheduled run as listed under a connection's `sync_runs` expansion. Arguments: id*.

connect_links_createwrite · api, mcp

Create a connect link. A single-use URL, valid for an hour, where a human pastes the provider credential so it never passes through the agent. The `url` is returned only now and cannot be read back; a replay with the same `Idempotency-Key` returns it from an encrypted store. Poll `GET /v1/connect_links/{id}` until `status` is `done`. A `label` another connection to the provider already has is a 409 `label_conflict`: a link never rotates an existing connection's credential. At most 10 unused links per project. Arguments: provider*, credential_type, label, idempotency_key.

connect_links_getread · api, mcp

Get a connect link. Poll a link: `pending`, `submitting`, `done`, `expired` or `locked` (too many failed attempts). When `done`, `connection` is the new connection's id, or the object with `expand[]=connection`. The URL is not returned again. Arguments: id*, expand.

alert_rules_createwrite · api

Create an alert rule. Email the project's members when a connection crosses a threshold. `threshold` is USD, days or percent depending on `type`. `connections` lists the connections to watch; omit it to watch all of them. An id that is not a connection of the project is a 422, never a rule that silently watches everything. At most 100 rules per project. Arguments: type*, threshold*, connections, enabled, idempotency_key.

alert_rules_listread · api

List alert rules. The project's alert rules, newest first. Arguments: limit, cursor.

alert_rules_updatewrite · api

Update an alert rule. Change any of `type`, `threshold`, `connections` (`null` watches every connection) and `enabled`. Connection ids are checked like on creation. Arguments: id*, type, threshold, connections, enabled, idempotency_key.

alert_firings_listread · api

List alert firings. When rules fired, newest first. Filter with `rule` or `connection` (the same ids the objects carry). Arguments: limit, cursor, rule, connection.

negotiated_pricing_putwrite · api

Set negotiated pricing. Record what your deal with a provider costs, so spend is priced at your rates instead of list price. `rates` are set one per `sku` and `unit` (rates you do not list are kept); `plan` replaces the negotiated subscription, and fields you omit from it are cleared. Every entry is validated and one bad entry rejects the request with `param` naming it: nothing is skipped silently. Events from the last 7 days that were left unpriced are repriced. `provider` is any provider slug your events use, catalog or not. At most 500 rates and 100 plans per project. List rates are read-only (`GET /v1/negotiated_pricing/{provider}?expand[]=list_rates`); resetting to list price is done in the app. Arguments: provider*, rates, plan, idempotency_key.

negotiated_pricing_getread · api

Get negotiated pricing. The project's own rates and subscription for a provider; empty `rates` and a null `plan` when nothing is negotiated. `expand[]=list_rates` adds Argus's list rates, which negotiated rates replace one for one. Arguments: provider*, expand.

The server lives on its own host: it answers at / and /mcp, and browsers are refused unless their origin is allow-listed.

The legacy server below keeps its tools and names unchanged.

Connect to the legacy server

Point any MCP client at the server with an MCP key as the bearer token (create one of type mcp in Settings → API keys):

{
  "mcpServers": {
    "argus": {
      "url": "https://api.argus.town/mcp",
      "headers": { "Authorization": "Bearer argus_mcp_..." }
    }
  }
}

In Claude Code, one command:

claude mcp add --transport http argus https://api.argus.town/mcp \
  --header "Authorization: Bearer argus_mcp_..."

Legacy tools

Read tools, all scoped to the key's project:

get_overview

Every provider's metrics and totals at once. Includes spend_basis, observed_since and balance_scope, which say whether month-to-date spend is reported or inferred from balance drops, and whether the balance is account-wide.

list_connections

Connected providers and their status.

get_provider

Full metrics and rate-limit snapshots for one connection.

get_rate_limit_status

The tightest rate-limit headroom and error rates across providers — the 'am I about to hit a wall' check.

get_advisories

Active warnings: low balances, short runway, spend spikes.

get_cost_accuracy

How exact each provider's numbers are right now (reconciliation drift and coverage).

get_request_costs

Recent itemized request costs for a provider — what did the last N calls actually cost.

Management tools

Agents can also manage connections, scoped to the key's project: an agent holding a project's key can only ever act on that project.

list_available_providers

Providers connectable with an API key, and which credential types each accepts.

connect_provider{ provider, secret, credential_type?, label?, meta? }

Connect a provider with a credential. Validated against the provider before storage, stored encrypted, initial sync queued. credential_type defaults to the provider's primary type — call list_available_providers for the accepted types per provider. Agents should only pass secrets their operator provided.

create_connect_link{ provider, credential_type?, label? }

Returns a single-use URL (valid an hour) where your operator pastes the provider key, so the secret never passes through you. Prefer it over connect_provider whenever you don't already hold the key.

get_connect_link{ id }

Poll a link: pending, submitting, done (with connection_id), expired, or locked.

sync_connection{ connection_id }

Queue an immediate refresh for one connection.

There is deliberately no remove tool — deleting a connection erases its ledger, so removal stays a human action in the signed-in dashboard. MCP keys also can\'t mint keys or sources; credentials come from a person\'s approval (see For agents).

Which providers can be connected

Two lists that differ on purpose: GET /v1/providers knows the pricing shape of every provider Argus tracks, but only some are pollable with a key. Each catalog entry carries connectable and credential_types, and list_available_providers returns exactly the connectable set — check one of those before calling connect_provider.

A wrinkle worth knowing: openai and anthropic need an org admin / usage-scoped key (not a normal sk-… API key) — Argus validates against the provider and will reject a standard key. Providers that aren't pollable are still tracked via SDK/ingest telemetry.