Skip to main content
Glama
@argosvix/mcp-server
by argosvix

@argosvix/mcp-server

Argosvix MCP server lets AI agents (Claude Desktop, Cursor, Codex CLI, custom MCP clients) query, manage, and operate their LLM observability data directly from the conversation. Supports both stdio (subprocess) and HTTP (remote / self-host) transports.

Surface: 89 tools (86 generally available + 3 internal operations tools that return 403 for customer accounts) / 3 resources / 8 resource templates / 3 prompts. Health and anomaly endpoints (get_account_health / detect_anomaly / propose_alert_rules / classify_calls_batch / propose_eval_criteria) plus a runtime control plane (budget gates / policy gates / human-approval gates) let an agent both observe and act. Release history is available on npm.

npm version License: MIT

Why

You're already sending LLM calls through @argosvix/sdk or the Python SDK. Now ask Claude / Cursor questions like:

  • "What was my OpenAI cost over the past 24h?"

  • "Which alerts are firing right now?"

  • "Show me the 20 most expensive calls today."

No dashboard tab-switching. The agent fetches the data via this MCP server using your Argosvix API key.

Related MCP server: Agent Analytics MCP Server

Install

One-click (starts keyless; set ARGOSVIX_API_KEY afterwards to use the tools for your own account):

Add to Cursor Install in VS Code

Claude Code users can install the argosvix plugin instead — it bundles this server plus setup skills:

/plugin marketplace add argosvix/claude-plugin
/plugin install argosvix@argosvix
/reload-plugins

Manual:

npm install -g @argosvix/mcp-server

Configure (Claude Desktop)

Edit your Claude Desktop config:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "argosvix": {
      "command": "argosvix-mcp",
      "env": {
        "ARGOSVIX_API_KEY": "argk_..."
      }
    }
  }
}

Restart Claude Desktop. All 89 tools appear under the argosvix__ prefix (e.g. argosvix__query_calls, argosvix__get_account_health, argosvix__create_budget_gate).

No API key yet? The server also starts without ARGOSVIX_API_KEY in introspection-only mode: all 89 tools are listed so you can evaluate the surface, and two public data tools (get_synth_daily / get_daily_readthrough — Argosvix's own daily AI digest and OSS readthrough) work with no key at all. Every other tool call returns instructions for getting a key at https://dashboard.argosvix.com/api-keys.

Notes on the public data tools: they are part of the default full profile only (not in ARGOSVIX_MCP_PROFILE=core), and like every other tool they honor ARGOSVIX_API_BASE — if you point the server at a different base, they fetch /v1/synth-daily / /v1/readthrough from that base without authentication.

Configure (Cursor)

Edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "argosvix": {
      "command": "argosvix-mcp",
      "env": {
        "ARGOSVIX_API_KEY": "argk_..."
      }
    }
  }
}

Tool profile (ARGOSVIX_MCP_PROFILE)

The default profile is full (all 89 tools). If your MCP client's context budget is tight, set ARGOSVIX_MCP_PROFILE=core to expose only the 11 essentials for day-to-day operations:

query_calls · aggregate_calls · get_cost_summary · get_percentiles · get_account_health · detect_anomaly · list_alerts · create_alert · silence_alert · unsilence_alert · get_deployed_prompt

{
  "mcpServers": {
    "argosvix": {
      "command": "argosvix-mcp",
      "env": {
        "ARGOSVIX_API_KEY": "argk_...",
        "ARGOSVIX_MCP_PROFILE": "core"
      }
    }
  }
}

Works in both stdio and HTTP transports. Unknown values fall back to full with a warning on stderr.

Description language (ARGOSVIX_MCP_LANG)

Tool, resource, and prompt descriptions returned by tools/list / resources/list / prompts/list are in English by default. Set ARGOSVIX_MCP_LANG=ja to get the original Japanese descriptions instead. Unset or unknown values fall back to en (with a warning on stderr for unknown values). Tool names, input schemas, and behavior are identical in both languages — only the human/agent-facing description text changes.

{
  "mcpServers": {
    "argosvix": {
      "command": "argosvix-mcp",
      "env": {
        "ARGOSVIX_API_KEY": "argk_...",
        "ARGOSVIX_MCP_LANG": "ja"
      }
    }
  }
}

Works in both stdio and HTTP transports.

Tools (highlights)

89 tools in total — the full list is returned by tools/list. A sample of the core read / write surface:

Tool

Purpose

Type

query_calls

Recent LLM call records, filterable by provider / model / time range

read

get_cost_summary

Aggregate cost / calls / tokens by provider or model

read

list_alerts

Configured alerts + recent trigger status

read

get_alert

Detail of a specific alert + recent trigger history

read

list_alert_events

Alert trigger events across the account (notification history)

read

silence_alert

Mute a specific alert (= temporary notification stop, default 24h)

write

unsilence_alert

Resume notifications for a previously muted alert

write

create_alert

Create a new alert rule (cost / error rate / latency / anomaly)

write

acknowledge_alert

Mark a specific alert event as acknowledged (idempotent, orthogonal to silence)

write

Resources

Resources expose read-only snapshots that AI agents can pull into context without an explicit tool call.

URI

Purpose

argosvix://account

Plan / quota / current-month record usage / retention snapshot (non-sensitive, Bearer-only)

argosvix://alerts/active

Snapshot of currently enabled alerts

argosvix://cost/today

Last-24h cost breakdown by provider (with response.total)

Resource templates

Resource templates let agents construct dynamic URIs from a known id. The server enforces account scope via PK lookup on the backend, so cross-account ids return 404.

URI template

Purpose

argosvix://calls/{id}

Single LLM call record (provider / model / tokens / cost / latency / tags / error / trace_id). Plug in any id from query_calls results.

argosvix://alerts/{id}

Single alert rule (name / type / threshold / window / channelKinds / sleep / enabled / silencedUntil) + recent 20 trigger events. Plug in any id from list_alerts results. channelTargets (notification destinations) is structurally dropped.

argosvix://traces/{id}

Single trace = all spans grouped by trace_id (LLM call time-series). Top 50 spans only (LLM context budget cap); errorDetails / requestMeta are structurally dropped. Plug in any traceId from query_calls results.

Prompts

Prompts are reusable templates the user can launch as slash commands.

Name

Purpose

cost_review

Compare 24h / 7d / 30d cost trends and flag anomalies

alert_audit

Audit current alert rules and propose improvements

incident_triage

Investigate recent error / latency anomalies (default last 24h)

Subscriptions (= v0.10, stdio only)

resources.subscribe capability is declared in stdio mode. Clients can subscribe to one or more of the static resources below; the server polls each subscribed resource every 60 seconds and emits notifications/resources/updated when the content hash changes.

Subscribable URIs (resource templates such as argosvix://calls/{id} are not subscribable):

  • argosvix://account

  • argosvix://alerts/active

  • argosvix://cost/today

HTTP transport (= argosvix-mcp --http) does not declare subscribe and rejects subscribe requests, since per-request stateless mode cannot keep a subscription set or deliver server-initiated notifications. Use stdio for live updates.

listChanged is intentionally not declared: the resource list is fixed for the server lifetime.

Implementation notes (v0.10):

  • Single-flight guard: a slow polling cycle does not start a concurrent next cycle (= no overlapping readResource calls).

  • Unsubscribe / shutdown race: per-URI re-check before fetch and before notify, plus an isShuttingDown flag, so notifications are not emitted for URIs removed mid-cycle.

  • Failure handling: fetch and notify failures are silent (next cycle retries). With ARGOSVIX_MCP_DEBUG=1 the server logs { uri, errorClass } to stderr — error messages are intentionally not logged to avoid leaking upstream payload text.

  • Tests: 150 unit tests (incl. overlap single-flight + unsubscribe / shutdown race + invalid URI → McpError(InvalidParams) + axis 4 Tier 1 dispatcher coverage).

Privacy

The MCP server sends queries to https://ingest.argosvix.com using your API key. No prompts or completions are exposed — only metadata (tokens, cost, latency, model name, your tags).

Development

npm install
npm run build
npm test

License

MIT © Yuto Makihara (Argosvix). See LICENSE.

HTTP transport

The server can also run as a remote MCP endpoint over HTTP, suitable for self-hosting or multi-tenant scenarios where API key is supplied per request.

# Start HTTP transport (default: 127.0.0.1:3000)
argosvix-mcp --http

# Bind to all interfaces with custom port + allowed Host headers
MCP_HTTP_HOST=0.0.0.0 \
MCP_HTTP_PORT=4000 \
MCP_HTTP_ALLOWED_HOSTS="mcp.example.com,localhost:4000" \
  argosvix-mcp --http

Endpoints

  • GET /health → 200 OK with server name/version (no auth)

  • POST /mcp → MCP JSON-RPC endpoint (auth required)

Client example

curl -X POST http://localhost:3000/mcp \
  -H "Authorization: Bearer argk_..." \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {}
  }'

Auth model

Each request must include Authorization: Bearer <api-key> with a valid Argosvix API key (issue at https://dashboard.argosvix.com/api-keys). The server uses stateless mode (no session ID), so each request is independent and may carry a different key.

Security notes

  • Default bind is 127.0.0.1 (localhost only). Use MCP_HTTP_HOST=0.0.0.0 to expose externally, but pair with a reverse proxy + TLS in production.

  • DNS rebinding protection is applied for localhost binds by checking the Host header against a known-localhost allow list. Use MCP_HTTP_ALLOWED_HOSTS (comma-separated) when binding non-locally.

  • Body size is capped at 1 MiB.

Debug logging

Backend error response bodies are not logged by default to keep production log aggregators free of backend-internal payloads. To enable raw body logging for a debugging session:

ARGOSVIX_MCP_DEBUG=1 argosvix-mcp           # stdio mode
ARGOSVIX_MCP_DEBUG=1 argosvix-mcp --http    # HTTP mode

Without the env var, error logs only include path, status, and x-request-id.

Available Tools

87 tools
acknowledge_alertA

Mark an individual alert firing (event) as handled / acknowledged. Unlike silence_alert (which temporarily mutes the whole alert rule), ack is a per-event receipt — future firings of the same rule are still delivered as usual. Pass the id obtained from list_alert_events as eventId. Re-acking an already acknowledged event does not overwrite the existing ack info (the first acknowledgedAt / acknowledgedBy) and returns 200 (idempotent; distinguishable via the alreadyAcknowledged flag).

Inputs: eventId (required).

aggregate_callsA

Get an aggregation cube over calls (POST /v1/query/aggregate). groupBy (provider / model / day / hour / minute / tag / error) x metric (cost / latency / tokens / input_tokens / output_tokens / cached_tokens / cache_savings / count / error_rate) — e.g. "aggregate this month's cost by model" in one call. tag mode requires tagKey (alphanumerics plus _ - only, e.g. 'env' / 'feature'). error mode aggregates only error rows by error string (which errors, how many; metric=count recommended). hour mode caps at 168h / minute mode at 60min (400 beyond). cost = SUM(cost_usd) / latency = AVG(latency_ms) / tokens = SUM(total_tokens) / input_tokens = SUM(prompt_tokens) / output_tokens = SUM(completion_tokens) / cached_tokens = SUM(cached_read_tokens) / cache_savings = SUM(cache_savings_usd) / count = COUNT(*) / error_rate = errors / total. Returns { groups: [{key, value, count}], total: {value, count} }.

Inputs: metric, tagKey, endTime, groupBy, +2 more.

apply_promo_code_to_customerA

Apply a user-facing promotion code already registered in Stripe (e.g. 'LAUNCH50') to your account's Stripe subscription (POST /v1/tier2/promo/apply). Founder-operations only (an internal support tool; general accounts get 403). It will not be opened up without terms covering economically impactful operations (timing undecided). 409 if an active discount already exists (structural defense against stacking), and 409 when the status is canceled / incomplete_expired. Redemption is delegated to Stripe via promotion_code (applying coupons directly is forbidden as a constraint bypass); dryRun must be passed explicitly, and idempotencyKey is required when dryRun=false. Re-calls with the same key return the cached result via the tier2_idempotency table, structurally serializing concurrent applies. dryRun=true previews resolution + the active-discount check + the estimated discount only (no Stripe mutation); dryRun=false applies the promotion code.

Inputs: dryRun (required), reason (required), promoCode (required), targetAccountId (required), +2 more.

auto_silence_noisy_alertA

Bulk-silence noisy alerts that fired repeatedly in the past hour (POST /v1/tier2/alerts/auto-silence). Finishes "this alert fired 50 times in the past hour — silence it for an hour" in one prompt. Specify exactly one of alertId (silence a single alert) or byVolumeThreshold (all alerts with N+ firings in the past hour). silenceDurationMinutes is 5-1440 (5 minutes to 24 hours), default 60. An optional reason can be attached. dryRun=true previews the targets with fireCount; dryRun=false UPDATEs alerts.silenced_until and emits an audit event per alert (tier2.auto_silence_noisy_alert). Because this is a reversible mutation (the existing unsilence_alert can undo it) with strict per-account scoping (other accounts' alerts are unaffected), there is no founder gate — paid Pro+ users can call it directly. Returns (dryRun=true) { dryRun: true, targetCount, silenceUntil, silenceDurationMinutes, lookbackStart, targets: [{alertId, name, fireCount}] }; (dryRun=false) { dryRun: false, targetCount, silenceUntil, silenceDurationMinutes, succeeded: string[], failed: [{alertId, reason}], skipped: string[], reason }. idempotencyId = sha1(endpoint+accountId+alertId+silenceUntil truncated to the minute), coalescing duplicate runs within the same minute.

Inputs: dryRun, reason, alertId, approvalId, +2 more.

bulk_delete_callsA

Bulk-delete the given call ids (max 100), scoped to your account (POST /v1/calls/bulk-delete). Useful for cleaning up garbage calls accumulated by dogfooding / dev tests. dryRun=true returns the matched count before deleting. The delete is one atomic SQL statement; a bulk_deleted event is recorded in the audit log. Per FK constraints, related traces / annotations / scores are cascade-deleted via ON DELETE.

Inputs: callIds (required), dryRun, approvalId.

classify_calls_batchA

Batch safety-classify unclassified calls on demand (via OpenAI Moderation, POST /v1/safety-assessments/scan-batch). Complements the cron (every 15 min, 50 records) with a "right now" path — an AI agent can finish "classify all of last week's calls" in one prompt. Pro+ only (Free relies on the cron); the backend enforces the plan gate and budget gate. maxRecords (1-100, default 50); returns { scanned, assessed, flagged, failures, skipped }. Recorded with source='mcp' (distinguished from cron entries, so the dashboard can visualize on-demand classification). Audit: emits a safety.scan_batch_run event to the audit log.

Inputs: maxRecords.

compare_eval_runsA

Compare two eval runs (baseline / candidate) and return per-criterion mean score deltas + the failed count delta + a verdict (GET /v1/eval-runs/compare). Lets an AI agent grasp "how did the candidate change relative to the baseline" in one call, for prompt-improvement measurement and regression detection. verdict = improved / regressed / mixed / unchanged. The failed count treats scores <= 2 as "failed". Same account only.

Inputs: baselineRunId (required), candidateRunId (required).

create_alertA

Create a new alert rule. Watches for cost / error rate / latency / anomaly threshold breaches and notifies the specified channels. Example: "notify me by email when daily cost exceeds $10". channelKinds is an array of channel kinds to enable; channelTargets is an object keyed by those kinds holding the destinations (e.g. channelKinds:["email"], channelTargets:{"email":"dev@example.com"}). Every kind listed in channelKinds must have a destination in channelTargets. anomaly_* types interpret thresholdValue as a standard-deviation multiplier (0.5-10, e.g. 3 = 3 sigma). The Free plan allows the email channel only and up to 3 alerts (the backend returns 403 beyond that).

Inputs: name (required), alertType (required), channelKinds (required), channelTargets (required), +8 more.

create_annotationA

Create a new annotation (human review / labeling) for an LLM call. Specify at least one of annotationText / label / qualityScore (an "empty annotation" gets 400 from the backend). Example phrasing: "Claude, label this call 'badly-summarized' with quality 2", or bulk-apply positive / negative labels for an eval loop. Combined with the eval baseline runner (run_eval), annotations can calibrate eval criteria as ground truth.

Inputs: callId (required), label, qualityScore, annotationText.

create_budget_gateA

Create a runtime budget gate (Pro+ only). Sets a monthly LLM spend limit (USD) for the account; the SDK (budgetGate opt-in) blocks over-limit calls before execution. Enforcement is optimistic (spend is cached for 60 seconds and in-flight calls pass, so the limit is a guideline that can be exceeded, not a strict hard cap). enforceMode = fail_open (default; calls pass when the backend is unreachable) / fail_closed (calls are blocked when unreachable; a cold start where the SDK has never fetched the config additionally requires the SDK-side failClosed opt-in). Omitting projectId = an account-wide gate (only one; 409 if one exists). Specifying projectId = a gate for that project only (ANDed with the account gate — the strictest limit wins; one per project). Specifying tagKey + tagValue = a gate for calls carrying that tag (e.g. tagKey=service / tagValue=checkout caps the monthly spend of service=checkout. ANDed with the account gate; one per (tagKey,tagValue)). tagKey/tagValue must be specified together and are mutually exclusive with projectId. Example phrasing: "create a budget gate at $50/month" / "cap project X at $10/month" / "cap the service=checkout tag at $20/month"

Inputs: monthlyLimitUsd (required), tagKey, enabled, tagValue, +2 more.

create_eval_criterionA

Create one custom eval criterion in your account (Pro+ only). name + rubric + scaleMin + scaleMax are required. Same name already existing in the account = 409. A name matching a global default is structurally allowed (UNIQUE (account_id, name) separates it from account_id IS NULL). type defaults to 'llm_judge' (judge LLM scoring). Specifying a deterministic evaluator type (exact_match / contains / regex / json_schema / json_path) scores without calling an LLM — free and instant (pass -> scaleMax / fail -> scaleMin). Deterministic types require config. The path an AI agent takes when it decides "add this criterion" during dogfood evals.

Inputs: name (required), rubric (required), scaleMax (required), scaleMin (required), +4 more.

create_eval_datasetA

Create a golden dataset (POST /v1/eval-datasets, Pro+ only). items can carry up to 20 test cases with expected outputs. Up to 50 datasets per account. frozen=true freezes the population (items can no longer be changed or unfrozen — fixing comparability for regression verdicts).

Inputs: name (required), items, frozen, description.

create_policy_gateA

Create a runtime policy gate (Pro+ only). Configures an account-wide model allowlist / PII block / secret block; the SDK (policyGate opt-in) blocks violating calls before execution. At least one rule (modelAllowlist / blockPii / blockSecrets) is required. One per account (409 if one exists). A redact mode is not supported (block only). Example phrasing: "only allow gpt-5.5 and claude-fable-5" / "block calls containing PII"

Inputs: enabled, blockPii, enforceMode, blockSecrets, +1 more.

create_projectA

Create a new project (POST /v1/projects). name = display name; slug = a short URL-safe identifier (/^[a-z][a-z0-9-]{0,31}$/). Pro caps at 5 projects, Team unlimited, Free cannot create (403). As a mutation, session-authenticated requests enforce Origin/Referer (dashboard-driven).

Inputs: name (required), slug (required).

create_promptA

Register one new prompt template (Pro+ only). name + version + template are required; variables / labels / description are optional. An existing (name, version) pair returns 409 (UNIQUE constraint). Used when an AI agent auto-registers templates for dogfood evals / experiments.

Inputs: name (required), version (required), template (required), labels, +2 more.

create_saved_viewA

Create a new saved view, or overwrite when the name exists (POST /v1/saved-views). name is unique within the account. filter follows the SavedViewFilter shape (startDate / endDate / provider / model / limit / preset / sortBy? / sortOrder?). Lets an AI agent save frequently used filters under a name — e.g. create a "last 7 days, GPT-4 only" view and recall it later.

Inputs: name (required), filter (required).

create_webhookA

Register one outbound event webhook (Pro+ only, POST /v1/webhooks). url (HTTPS required; SSRF defense rejects private/loopback) + optional secret (HMAC-SHA256 signing key) + eventTypes (array of event kinds to subscribe to; omitted / empty = subscribe to everything). Up to 10 per account. Delivery payload = { event, eventId, occurredAt, accountId, data }; with a secret set, an X-Argosvix-Signature header is attached.

Inputs: url (required), secret, enabled, eventTypes, +1 more.

delete_alertA

Delete an alert (DELETE /v1/alerts/:id). Related alert_events are CASCADE-deleted too. To guard against accidental deletion, checking the details with get_alert first is recommended. If you only want to pause an alert, prefer silence_alert (mute) or update_alert with enabled=false instead of delete (both are recoverable).

Inputs: alertId (required).

delete_annotationA

Delete an annotation (DELETE /v1/annotations/:id). No other rows depend on it, so there is no CASCADE impact. To guard against accidental deletion, checking the details with get_annotation first is recommended.

Inputs: annotationId (required).

delete_budget_gateA

Delete a runtime budget gate (Pro+ only). After deletion the SDK's pre-execution enforcement is disabled. To pause temporarily, prefer update_budget_gate with enabled: false.

Inputs: gateId (required).

delete_eval_criterionA

Delete a custom criterion in your account (Pro+ only, DELETE /v1/eval-criteria/:id, 204). Global defaults (account_id IS NULL) are structurally out of scope = 404; other accounts are 404 too. WARNING: all past eval_run score rows for this criterion (eval_scores) are physically deleted at the same time via ON DELETE CASCADE — historical comparisons and score trend analysis become permanently impossible. This is not a tool for an AI agent to call casually while tidying up criteria; only proceed when the user has explicitly confirmed the past run scores are not needed. If you only want to rename, using update_eval_criterion (full replace) with name + rubric + scaleMin + scaleMax preserves the history.

Inputs: criterionId (required).

delete_eval_datasetA

Delete a golden dataset (DELETE /v1/eval-datasets/:id, Pro+ only). Items are cascade-deleted. Past eval runs / scores remain.

Inputs: datasetId (required).

delete_policy_gateA

Delete a runtime policy gate (Pro+ only). To pause temporarily, prefer update_policy_gate with enabled: false.

Inputs: policyId (required).

delete_projectA

Soft-delete a project (DELETE /v1/projects/:id; sets archived_at for a logical delete). The default project cannot be deleted (400, keeping accounts.default_project_id referentially consistent). After archiving, calls / alerts remain as-is (past observations are kept); route new records to another project.

Inputs: projectId (required).

delete_promptA

Delete an existing prompt (Pro+ only, DELETE /v1/prompts/:id, 204 No Content). Scoped to your account (other accounts' ids return 404). WARNING: physical delete with no restore; past eval_runs' prompt_registry_id is SET NULL, losing the trace of which prompt template each run used (history comparisons can no longer be linked). Even when sunsetting an old version in a rotation, while past run traces remain it is safer to do a logical sunset via update_prompt with labels such as 'sunset'.

Inputs: promptId (required).

delete_saved_viewA

Delete the saved view with the given id (DELETE /v1/saved-views/:id). Scoped to your account.

Inputs: id (required).

delete_webhookA

Delete an outbound event webhook (Pro+ only, DELETE /v1/webhooks/:id). Other accounts' webhooks return 404. webhookId is the id from list_webhooks.

Inputs: webhookId (required).

deploy_promptA

Deploy a specific prompt version to a label (an environment such as production / staging) (Pro+ only, POST /v1/prompts/:id/deploy). If a deployment already exists, the prior version is kept as previous and rollback_prompt can revert in one step. Re-deploying the same version does not create a previous entry. Labels are per prompt name (each name has its own production version).

Inputs: label (required), promptId (required).

detect_anomalyA

Compare the current window against a baseline window (the immediately preceding window of the same length) and detect anomalies across 4 axes: cost / latency / error_rate / call_volume — lets an AI grasp "is anything off?" in one prompt. Sensitivity is tunable via threshold: sensitive (1.5x) / normal (2x, default) / conservative (3x). 0-4 detections, each with a narrative. Returns { window, threshold, current: {...}, baseline: {...}, anomalies: [{ axis, severity: 'minor'|'major'|'critical', current, baseline, ratio, narrative }] }. errorRate is evaluated and displayed as a percent (0-100), matching the backend aggregate unit. Insufficient baseline data (fewer than 10 records in the period) yields anomalies: [] plus a warning message.

Inputs: window, threshold.

export_callsA

Large-batch export of calls (POST /v1/query/export). Higher limit than query_calls (per-plan max records: Free 1000 / Pro 50000); available on all plans. Filter axes = startTime / endTime / provider / model plus limit. Example phrasing: "pull all of last month's GPT-4 calls and analyze the trends" — one call. The result format is the same JSON as query_calls (the AI can feed it straight into CSV / statistics).

Inputs: limit, model, endTime, provider, +1 more.

extend_customer_trialA

Extend your account's Stripe subscription trial by 1-30 days (POST /v1/tier2/trial/extend). Founder-operations only (an internal support tool; general accounts get 403). Trial extension directly affects revenue, so there is no plan to open it up. Cumulative cap of 60 days (aggregated from the last 30 days of audit logs); 409 unless status='trialing'. dryRun must be passed explicitly (guards against accidental mutation via an implicit false); when dryRun=false, idempotencyKey is also required (16-128 alphanumeric plus '_-'). Re-calling with the same key returns the cached result via the tier2_idempotency table (structurally preventing retry double-extends). dryRun=true previews previousTrialEnd / newTrialEnd / the cumulative total only (no Stripe call); dryRun=false performs the actual Stripe mutation plus the accounts_subscription sync update.

Inputs: dryRun (required), reason (required), extendDays (required), targetAccountId (required), +2 more.

get_account_healthA

Get a health summary of your LLM infrastructure in one call. Fetches 4 existing endpoints in parallel (aggregate_calls / get_percentiles / get_llm_budget / list_audit_log) and compresses them into one response. Returns { window, totals: {calls, costUsd, errorRate (percent 0-100)}, latency: {p50, p95, p99 (ms)}, budget: {used, limit, percentUsed (0-100)}, recentEvents: count, summary: 'ok' | 'warn' | 'critical' }. critical = errorRate>=10% / budget>=90% / p95>=10s; warn = >=3% / >=70% / >=3s. Example phrasing: "how is our LLM infra doing right now?" — answered in one prompt. Pure read aggregator (no new backend endpoint); individual endpoint failures return partial results (one axis timing out does not block the summary).

Inputs: window.

get_alertA

Return the detailed configuration of an alert and its recent trigger history. Pass the alertId obtained from list_alerts. Use it to check the threshold / notification channels / silence state / when it fired.

Inputs: alertId (required).

get_annotationA

Fetch one annotation by id (obtained from list_annotations_*). Includes annotationText / label / qualityScore / callId / createdAt / updatedAt / createdByUserId. Ids belonging to other accounts return 404 (structural defense).

Inputs: annotationId (required).

get_approvalA

Get the current state of an approval request. status = pending / approved / denied / expired. Do not perform the target operation unless the status is approved (default-deny). Dangerous mutation tools also support server-side consumption via their approvalId param (see the request_approval description).

Inputs: approvalId (required).

get_budget_gateA

Get the runtime budget gate settings (runtime control plane Phase 1) plus this month's LLM spend. Response = { gates: [{ id, projectId, monthlyLimitUsd, enforceMode, enabled, ... }], spentUsdThisMonth, monthStart, ttlSeconds }. monthStart is the UTC month start. The same source the SDK's budgetGate opt-in evaluates before execution. Distinct from get_llm_budget (which caps Argosvix's internal AI feature costs) — this one is a monthly cap on your own LLM spend. Example phrasing: "how much budget gate headroom is left this month?" / "is the gate set to fail_open?"

Inputs: no named parameters.

get_cost_summaryA

Return cost / call count / token aggregates per time range, with a per-provider breakdown. When groupBy="none" is specified, a per-provider breakdown is still returned for backend compatibility (check the response.total field for the overall sum).

Inputs: groupBy, rangePreset.

get_deployed_promptA

Resolve and return the prompt version currently deployed to the given environment (name + label) (GET /v1/prompts/resolve, available on Free). The main runtime path for an agent to fetch the "production prompt". Returns that version's template / variables / labels / version. 404 when nothing is deployed.

Inputs: name (required), label (required).

get_eval_criterionA

Fetch one criterion's detail (name / rubric / scaleMin / scaleMax / createdAt) by id. The id comes from list_eval_criteria.criteria[].id. Both global defaults (accountId NULL) and your account's custom criteria are accepted; other accounts' customs return 404 (structural defense).

Inputs: criterionId (required).

get_eval_datasetA

Fetch one dataset's detail plus all of its items (GET /v1/eval-datasets/:id). datasetId is list_eval_datasets.datasets[].id.

Inputs: datasetId (required).

get_eval_runA

Fetch one eval run's detail plus the list of per-(criterion x call) scores. Use runs[].id from list_eval_runs as-is. The scores array includes score (an integer within the criterion's scale) + reasoning (the judge's rationale). Same endpoint as the argosvix://eval-runs/{id} resource template.

Inputs: runId (required).

get_llm_budgetA

Get the current monthly LLM feature budget (the LLM cost cap covering the 3 axes: safety classifier + secondary PII audit + eval baseline runner). Response = { budgetUsd, spentUsd, remainingUsd, periodStart, defaultBudgetUsd, minBudgetUsd, maxBudgetUsd }. Readable on Free and Pro+ alike; used when an AI agent decides "have we hit 80% of budget?" / "should we raise it?". Default $5/month; auto-resets at month boundaries (per YYYY-MM).

Inputs: no named parameters.

get_percentilesA

Get percentile metrics over calls (POST /v1/query/percentiles). metric = 'latency' (ms) or 'cost' (USD); either a single value for the whole range, or a time series with groupBy='day'/'hour'/'minute'. Example phrasing: "daily p95 latency trend for last week". Computed with the nearest-rank method via window functions (D1 SQLite has no percentile_cont).

Inputs: model, metric, endTime, groupBy, +2 more.

get_policy_gateA

Get the runtime policy gate settings (runtime control plane Phase 2). Response = { policy: { id, modelAllowlist, blockPii, blockSecrets, enforceMode, enabled, ... } | null }. The config the SDK's policyGate opt-in evaluates locally before each LLM call (exact-match model allowlist + blocking on PII / secret detection). Example phrasing: "what model restrictions are active right now?" / "is PII blocking enabled?"

Inputs: no named parameters.

get_promptA

Fetch one prompt's detail by id. Use prompts[].id from list_prompts as-is. Includes template + variables + labels + description; scoped to your account (structurally enforced by a backend WHERE clause — other accounts' ids return 404). Same endpoint as the argosvix://prompts/{id} resource template.

Inputs: promptId (required).

get_proposal_threadA

Return the thread for a proposal (the questions asked so far and the AI's replies). Get proposalId from list_proposals.

Inputs: proposalId (required).

get_safety_assessmentA

Fetch one assessment's detail by id. Use assessments[].id from list_safety_assessments as-is. Includes labels (array of flagged categories) + score (max category score 0-1) + reasoning + classifier_id + source. Same endpoint as the argosvix://safety-assessments/{id} resource template.

Inputs: assessmentId (required).

list_alert_eventsA

Return alert trigger events, newest first. Account-wide (recent firings of all alerts) by default; pass alertId to narrow to one alert. Use for questions like "which alerts fired recently and how often?" or "when did the cost alert go off?". Each event's id can be passed directly to the acknowledge_alert tool. acknowledgedAt / acknowledgedBy are null if not yet acknowledged. Each event includes a snapshot of thresholdValue / windowMinutes / alertType at firing time (so the firing-time conditions survive later rule edits). For the next page, pass the last event's triggeredAt + id as beforeTriggeredAt + beforeId (keyset cursor).

Inputs: limit, alertId, beforeId, beforeTriggeredAt.

list_alertsA

Return the list of configured alerts plus trigger history within the last 24 hours.

Inputs: includeTriggered.

list_annotations_by_labelA

Return annotations carrying the given label, newest first (account-wide, up to 100). Use for things like collecting calls rated "good" or listing human reviews labeled "bug". Labels are ASCII letters / digits / underscore / hyphen only ([a-zA-Z0-9_-], up to 64 chars).

Inputs: label (required), limit.

list_annotations_for_callA

Return the annotations attached to an LLM call (records[].id from query_calls). An annotation is a user-authored evaluation (rating / comment / label); each annotation includes annotationText / label / qualityScore / createdAt / updatedAt. Use to check whether a call has human review attached or what past reviews said. Independent of the Pro+ plaintext feature (annotations work without plaintext storage enabled).

Inputs: callId (required).

list_approvalsA

List approval requests (latest 50). status filter = pending (default) / approved / denied / expired / all.

Inputs: status.

list_audit_logA

List the audit log (GET /v1/audit-log). Scoped to your account; admin role only (viewer/member get 403). Lets an AI agent autonomously review recent operation history such as invitations / API key revocations / project changes. Filters = eventType ('invitation.created' / 'api_key.revoked' etc.) / targetKind / actorUserId / from / to. Supports cursor pagination (nextCursor format = 'created_at|id'), max limit 200.

Inputs: to, from, limit, cursor, +3 more.

list_eval_criteriaA

Return the list of LLM-as-judge evaluation criteria. Includes the 5 global defaults (helpfulness / accuracy / relevance / safety / conciseness) plus the custom criteria created in your account. Each criterion has id / name / rubric (the instruction text for the judge) / scaleMin / scaleMax. Use before running an eval to see which axes are available. The Free plan can read all criteria (creating custom ones is Pro+ only, but existing rows stay visible after downgrade).

Inputs: no named parameters.

list_eval_datasetsA

List your account's golden datasets (GET /v1/eval-datasets). Each dataset has a name / description / item count / frozen state. A golden dataset is a fixed test set with expected outputs — the population run_eval_dataset pushes through a target model to measure regression A/B.

Inputs: no named parameters.

list_eval_runsA

List the eval baseline runner's run history. Scoped to your account, most recent first. Includes summary.scoredCount / failedCount / meanScoreByCriterion, so an AI agent can grasp recent eval result summaries and per-criterion score trends in one call. Free users can read past runs too.

Inputs: limit.

list_membersA

List a Team account's members (GET /v1/memberships, removed members excluded). Read-only tool returning each member's email / role (admin/member/viewer) / status / joined-at. Invitations, role changes, and removals are privilege operations and intentionally not exposed over MCP (use the dashboard, or a future approval-gate flow).

Inputs: no named parameters.

list_projectsA

List your account's active projects (GET /v1/projects, archived excluded). Supports per-environment observation such as dev / staging / prod. Pro allows 5 projects / Team unlimited; Free has the default project only.

Inputs: no named parameters.

list_prompt_deploymentsA

List the current deployment states (GET /v1/prompts/deployments, available on Free). Each row = { promptName, label, currentVersion, canRollback, deployedAt }. Narrow by name / label (omit both for everything).

Inputs: name, label.

list_promptsA

List the prompt templates the user has registered. Each prompt includes id / name / version / template / variables / labels / description / createdAt. Filter by a label such as "production" (?label=xxx), or fetch all versions of one name (?name=xxx). Up to 200 entries; sort = name ASC + created_at DESC. The main path for an AI agent to read and use prompts the user registered in the dashboard.

Inputs: name, label, limit.

list_proposalsA

Return the unresolved improvement proposals found by the Argosvix guardian (quality drift / reliability anomalies / cost switching / safety / silencing noisy alerts). Approving, dismissing, and executing happen in the dashboard inbox (agents can only read and converse).

Inputs: no named parameters.

list_safety_assessmentsA

List the assessments written by the safety classifier (OpenAI Moderation). source includes 'cron' (periodic batch) / 'mcp' (classify_calls_batch on-demand) / 'human_override' / 'api' / 'auto'. With callId = all classifier assessments for that call; without callId = account-wide, flagged first then most recent. In environments without OPENAI_API_KEY provisioned the cron does not run and this returns an empty array (classify_calls_batch also returns 503). Precondition: safety classification is disabled by default (founder-scoped / off-by-default); no assessments are generated until it is enabled. An empty array means "not enabled / nothing flagged", not a failure. AI agents use this to review recently flagged calls or to check policy-violation candidates for a specific call.

Inputs: limit, callId.

list_saved_viewsA

List the saved views (GET /v1/saved-views). A saved view is a named combination of frequently used /calls page filters (startDate/endDate/provider/model/limit). Enables phrasing like "show calls with my usual last-week OpenAI filter". Per account, max 20.

Inputs: no named parameters.

list_webhooksA

List the registered outbound event webhooks (GET /v1/webhooks). Each webhook includes id / url / hasSecret / enabled / eventTypes / lastStatus / consecutiveFailures etc. (the secret itself is never returned). This is the subscription surface that notifies external endpoints of account events (approval requests, proposal execution / reversal) via signed POSTs. Readable on Free.

Inputs: no named parameters.

propose_alert_rulesA

Analyze the call patterns over the past lookbackDays (7-30, default 14) and propose recommended alert rules for cost / latency / error_rate / anomaly as JSON. Applying them is a separate step via create_alert after customer confirmation (propose only — zero side effects). Only rules that do not overlap existing alerts are proposed (existing types are fetched via list_alerts). Returns { lookbackDays, baseline: {meanDailyCost (USD), p95Latency (ms), errorRate (percent 0-100), dailyCalls, totalCalls}, proposals: [{ name, alertType, thresholdValue, windowMinutes, reasoning }], skipped: [{ alertType, reason }] }. The thresholdValue of an error_rate proposal is also a percent (consistent with backend create_alert). What big-vendor dashboards show in UI, done MCP-first in one prompt.

Inputs: lookbackDays.

propose_eval_criteriaA

Have an LLM judge (gpt-4o-mini) propose eval criterion candidates from a one-line useCaseHint (e.g. "customer support bot") and optional sampleCallIds (representative calls from your account, up to 5) (POST /v1/eval-criteria/propose). An AI agent can finish "propose criteria to measure our prompt quality" in one prompt. Pro+ only (the backend enforces the plan gate + budget gate); nothing is INSERTed (propose only — adoption is a separate step via create_eval_criterion, structurally limiting LLM-hallucination impact). Decrypt failures for sampleCallIds are reported in partialFailures (the LLM call still runs without samples). Privacy note for prompt samples: with sampleCallIds, the backend decrypts those calls' prompt/response and sends excerpts (1500 chars each) to OpenAI gpt-4o-mini. This re-sends data your SDK originally sent to OpenAI/Anthropic, so no new vendor is added, but be aware it may reach an OpenAI model different from your own LLM calls. If that is a concern, run with useCaseHint only. Results are advisory: the returned criteria are LLM proposals and may include semantically weak rubrics (overuse of "helpful", duplicates) even when structurally valid. User review before adoption is recommended; do not feed them blindly into create_eval_criterion. Returns { criteria: [{ name (snake_case 32 chars), rubric (1-200), scaleMin (=1), scaleMax (5 or 10), reasoning (1-200) }], partialFailures: string[], budgetSpentUsd, proposedRawCount (raw count returned by the LLM), droppedCount (entries removed by the validator) }. Audit: emits an eval.propose_criteria event to the audit log.

Inputs: useCaseHint (required), maxCriteria, sampleCallIds.

purge_expired_plaintextA

Bulk-purge your account's plaintext records older than olderThanDays (POST /v1/tier2/plaintext/purge-expired). Consistent with the Terms of Service v2.1 "retainable up to 90 days" (automatic retention); an AI agent can finish "auto-purge plaintext older than 30 days" in one prompt. dryRun=true (the safe default to reach for) returns the count plus 5 sample call_ids; dryRun=false performs the actual UPDATE. Emit-then-UPDATE ordering plus a deterministic idempotencyId (sha1(endpoint+accountId+olderThanDays+cutoff_date)) gives webhook-retry-equivalent semantics. Pro+ plan only (Free gets 403). An actual purge (dryRun=false) requires approvalId — obtain human approval via request_approval (action: 'purge_expired_plaintext') first, because NULLing plaintext is irreversible. Only your own account is purged. Returns (dryRun=true) { dryRun: true, targetCount, cutoffTimestamp, olderThanDays, sampleTargetCallIds }; (dryRun=false) { dryRun: false, purgedCount, cutoffTimestamp, olderThanDays, purgedAt }. Audit: emits tier2.purge_expired_plaintext.

Inputs: dryRun, approvalId, olderThanDays.

query_callsA

Retrieve recent LLM call records captured by Argosvix. Filterable by provider / model / time range / tag. Defaults to the last 24 hours, 100 records.

Inputs: limit, model, beforeId, provider, +4 more.

raise_llm_budgetA

Raise or lower the monthly LLM feature budget (Pro+ only). Range $5 - $500 (hard cap against runaway spend), in $0.01 increments. Existing spend carries over; auto-resets at month boundaries. Example phrasing: "we hit 80% of the budget — raise it to $30 just for this month" / "we overspent — lower next month to $10". A new value below current spend is accepted (remaining simply becomes 0; counting restarts from 0 next month).

Inputs: budgetUsd (required).

rename_projectA

Update an existing project's name / slug (PATCH /v1/projects/:id). Specify either or both. slug keeps the URL-safe constraint (/^[a-z][a-z0-9-]{0,31}$/). Renaming the default project is allowed.

Inputs: projectId (required), name, slug.

rename_promptA

Change an existing prompt's name + version (Pro+ only, POST /v1/prompts/:id/rename). Main use is typo fixes ('customer_supprt' to 'customer_support'). Collision with an existing (name, version) in the account = 409. Since update_prompt never changes name/version by contract, rename is a separate tool for semantic separation.

Inputs: name (required), version (required), promptId (required).

reply_proposalA

Post a question about a proposal and get the AI's reply (same as the inbox conversation). Explanation only — nothing is executed. Get proposalId from list_proposals.

Inputs: body (required), proposalId (required).

request_approvalA

Create an approval request in the human approval gate (runtime control plane Phase 3; Pro+ only). Call it before dangerous operations (deletion / money transfer / account closure etc.); the account owner gets an email notification and a human approves or denies via the dashboard or the email link. Important: no MCP tool exists to approve or deny (an AI agent cannot self-approve its own request). Poll the result with get_approval. Expiry after timeoutSeconds (default 3600) counts as denied. Server-side consumption: passing approvalId to a dangerous mutation tool (bulk_delete_calls / purge_expired_plaintext / retry_failed_webhook / auto_silence_noisy_alert / extend_customer_trial / apply_promo_code_to_customer) makes the backend verify action match + approved + within expiry + unconsumed, and consume it on execution (1 approval = 1 execution). In that case create the request with an action exactly matching the target tool name. Example phrasing: "deleting user usr_123 is a dangerous operation — get human approval first"

Inputs: action (required), summary (required), metadata, timeoutSeconds.

retry_failed_webhookA

Mark failed Stripe webhook events (the billing_dead_letter table) for reprocessing in the audit log (POST /v1/tier2/webhook-events/retry). Finishes "retry all the Stripe webhooks that failed transiently last week" in one prompt. Select targets by eventIds (specific events, up to 100) or fromTimestamp/toTimestamp (range, 7-day cap). dryRun=true previews the list; dryRun=false records a 'marked_for_manual_redispatch' entry per event in the audit log (the founder performs the actual retry via wrangler / the Stripe dashboard; fully automatic re-dispatch is a later phase). Emits use a deterministic idempotencyId (sha1(endpoint+accountId+eventId)); duplicate runs with the same args are silently skipped. Founder-operations only (an internal billing-webhook recovery tool; general accounts get 403). billing_dead_letter is an internal cross-account table and actual re-dispatch stays manual, so there is no plan to open this up. Returns (dryRun=true) { dryRun: true, targetCount, events: [{eventId, eventType, reason, receivedAt}] }; (dryRun=false) { dryRun: false, targetCount, succeeded: string[], failed: [{eventId, reason}], skipped: string[], narrative, retriedAt }. Audit: emits tier2.retry_failed_webhook per event.

Inputs: dryRun, eventIds, approvalId, maxRetries, +2 more.

rollback_promptA

Revert the prompt deployed to a label to the previous version (Pro+ only, POST /v1/prompts/deployments/rollback). 409 when there is no previous version (first deployment only), and 409 when the previous version has already been deleted. After reverting, another rollback toggles back (current / previous swap).

Inputs: name (required), label (required).

run_evalA

Start a new eval run immediately (POST /v1/eval-runs). Scores the most recent N calls against the 5 default criteria (plus up to 8 custom criteria) using gpt-4o-mini. Pro+ only (Free gets 403); environments without OPENAI_API_KEY provisioned return 500 from the backend. Precondition: only calls with plaintext storage (the content-storage opt-in) ON are scored. With the opt-in OFF (the default) there are zero candidates and the run returns summary.scoredCount=0 with reason='no_plaintext_calls' (gating, not a failure). Cost: about $0.01 per run (20 calls x 5 criteria = 100 LLM calls); around 30 runs/month = $0.30 at founder-dogfood scale.

Inputs: name (required), label, recentCount, idempotencyKey, +1 more.

run_eval_datasetA

Run a golden dataset against a target model and produce a regression verdict (POST /v1/eval-datasets/:id/run, Pro+ only). Feeds each item's inputText to targetModel, has gpt-4o-mini score the outputs against the default criteria plus expectedOutput, and records eval_scores (regression A/B). Results can be compared across runs with compare_eval_runs. Run records are excluded from production cost / analytics / alert aggregation. Cost: item count x criteria count LLM calls. 503 in environments without OPENAI_API_KEY provisioned.

Inputs: datasetId (required), targetModel (required), judgeModel, idempotencyKey.

silence_alertA

Temporarily mute an alert (stops notification delivery). Defaults to 24 hours; pass an ISO-8601 timestamp as until for a custom expiry. Pass the alertId obtained from list_alerts.

Inputs: alertId (required), until.

test_webhookA

Send one fabricated alert to the given URL as a test delivery (Pro+ only). Main use: checking that a webhook URL is reachable before registering it. SSRF defense requires https and rejects private / loopback / cloud-metadata IPs. When secret is provided, an HMAC-SHA256 signature (X-Argosvix-Signature) is attached. Rate limit = 5/min per account (60s sliding window; may be exceeded across worker instances). response.delivered = whether the receiver returned 2xx within 5s; false means an invalid URL / timeout / 5xx / network error.

Inputs: url (required), secret, alertName.

unsilence_alertA

Unmute a currently silenced alert.

Inputs: alertId (required).

update_alertA

Update an existing alert's settings (PATCH /v1/alerts/:id). alertType (the watched metric type) is immutable — to change it, create a new alert and then delete the old one (completing the alert lifecycle). Threshold / evaluation window / notification channels / name / enabled flag / composite conditions can be partially updated (all fields optional). Example phrasing: "lower the monthly budget alert threshold from $100 to $50" / "add Slack as a notification channel".

Inputs: alertId (required), name, enabled, conditions, +7 more.

update_annotationA

Partially update an annotation's annotationText / label / qualityScore (PATCH /v1/annotations/:id). callId is immutable. For fixing a label or re-scoring quality from 4 to 5, etc. Pass annotations[].id obtained from list_annotations_for_call as annotationId.

Inputs: annotationId (required), label, qualityScore, annotationText.

update_budget_gateA

Update a runtime budget gate (Pro+ only). Partially updates any of monthlyLimitUsd / enforceMode / enabled. Example phrasing: "raise the limit to $100" / "disable the gate temporarily" / "switch to fail_closed"

Inputs: gateId (required), enabled, enforceMode, monthlyLimitUsd.

update_eval_criterionA

Update a custom criterion in your account with a full replace (Pro+ only, PATCH /v1/eval-criteria/:id). name + rubric + scaleMin + scaleMax are required (not a partial update — all fields are overwritten). type / config are also fully replaced (omitting them reverts to 'llm_judge' / no config). Deterministic types require config. Global defaults (account_id IS NULL) are structurally out of scope (404); other accounts' customs are 404 too. Name collision within the account = 409.

Inputs: name (required), rubric (required), scaleMax (required), scaleMin (required), +5 more.

update_policy_gateA

Update a runtime policy gate (Pro+ only). Partially updates modelAllowlist (null clears the restriction) / blockPii / blockSecrets / enforceMode / enabled. Example phrasing: "add gpt-4o-mini to the allowlist" / "enable secret blocking"

Inputs: policyId (required), enabled, blockPii, enforceMode, +2 more.

update_promptA

Partially update an existing prompt's template / variables / labels / description (Pro+ only, PATCH /v1/prompts/:id). name + version are immutable (change them via rename_prompt). promptId is required; only the fields you pass are updated. Used by AI agents for label moves (promoting 'staging' to 'production') and small patch edits.

Inputs: promptId (required), labels, template, variables, +1 more.

update_webhookA

Partially update an outbound event webhook (Pro+ only, PATCH /v1/webhooks/:id). Only the specified fields change (url / secret / eventTypes / description / enabled). Sending secret as null removes the signature; re-enabling with enabled=true also resets the consecutive-failure counter. Other accounts' webhooks return 404. webhookId is the id from list_webhooks.

Inputs: webhookId (required), url, secret, enabled, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 87 tools

    Disambiguation5/5

    Every tool has a clearly distinct purpose. For example, there are multiple alert-related tools (acknowledge_alert, auto_silence_noisy_alert, silence_alert, etc.) but each targets a unique action like acknowledging a single event, bulk-silencing, or muting. Descriptions are detailed enough to avoid ambiguity.

    Naming Consistency5/5

    All 87 tool names follow a consistent verb_noun pattern in snake_case (e.g., create_alert, list_alerts, delete_alert). Verbs like get, list, create, update, delete, propose, etc. are used uniformly, making naming predictable.

    Tool Count3/5

    With 87 tools, the count is very high and exceeds typical well-scoped ranges (3-15). However, the server covers a broad domain (calls, alerts, budgets, evaluations, prompts, projects, etc.) as a comprehensive admin interface, so the count is somewhat justified but still feels heavy.

    Completeness5/5

    The tool set covers core CRUD/lifecycle operations for each subdomain (alerts, calls, eval, prompts, webhooks, budgets, policies, projects). There are no obvious gaps; even advanced operations like automated silencing, proposal reply, and approval request are included.

    Maintenance

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers