# ninedot MCP server: your stack in any agent

ninedot is an MCP server. Connect it to Claude.ai, ChatGPT, Claude Code or Cursor and ask about any product's stack, costs, revenue, uptime and alerts. Read-only by default; adding and editing is opt-in per agent; removals always wait for a person. Agents never see tokens and can never change a provider account.

Try asking: "What's in my stack and what does each product cost and earn?", "Why did costs go up this month?", "Is anything down or about to expire?", "How much did I spend on OpenAI per product?", "Give me my weekly review."

## MCP server

- Endpoint: https://ninedot.app/api/mcp (Streamable HTTP, JSON responses, POST only). Protocol versions 2025-11-25, 2025-06-18, 2025-03-26.
- Server card: https://ninedot.app/api/mcp/server-card (also https://ninedot.app/.well-known/mcp/server-card.json).
- Two ways to sign in:
  - **OAuth** (Claude.ai, ChatGPT and other connectors): add https://ninedot.app/api/mcp as a custom connector. The client discovers the authorization server from https://ninedot.app/.well-known/oauth-protected-resource, registers itself and sends the person to a ninedot consent screen where they pick what it may do.
  - **Agent key** (Claude Code, Cursor, scripts): create one at https://ninedot.app/agents and send `Authorization: Bearer nd_…`.
- Claude Code: `claude mcp add --transport http ninedot https://ninedot.app/api/mcp --header "Authorization: Bearer nd_…"` (or omit the header to sign in with OAuth).
- Cursor (`~/.cursor/mcp.json`): `{ "mcpServers": { "ninedot": { "url": "https://ninedot.app/api/mcp", "headers": { "Authorization": "Bearer nd_…" } } } }`
- Limits: 120 requests a minute per agent, 300 a minute per IP, 64 KB per request, 10 messages per batch.
- Errors: 401 with `WWW-Authenticate` when the key or token is missing or invalid; tool problems come back as results with `isError: true` and a sentence saying what to do.

### Scopes

- `read_stack`: See products, services, status and alerts
- `read_costs`: See costs, revenue and margin
- `manage`: Add and edit products and services (removals need your approval)

### Tools

| Tool | Scope | What it does |
|---|---|---|
| `get_stack` | read_stack | Products and the services each one runs on: id, provider, category, plan, status and links. Use the ids with other tools. |
| `get_costs` | read_costs | Monthly cost per service and product, MRR and margin, each verified (exact or measured) with where it came from. Plan list prices and hand-typed costs are never included. Quote the trust level when you report a figure. |
| `get_portfolio` | read_costs | One screen for the whole workspace: MRR, monthly cost, margin, uptime and AI spend across every product, which products need attention, and what's connected. Start here for "how are things going" questions. |
| `get_product` | read_stack | Everything about one product on one call: figures with trust levels (costs and revenue only with read_costs), every service with status and facts, uptime, recent events, pending suggestions and renewal dates. |
| `get_service` | read_stack | One service in detail: provider, plan, status, cost and revenue with trust (read_costs), the facts in its drawer (region, last deploy, subscriptions, spend by model, ...), notes, and when it last synced. |
| `list_events` | read_stack | What happened: outages and recoveries, failed and recovered services, failed payments, chargebacks, expiring certificates and domains, over the last 30 days (newest first). Use it to answer "what changed" and "when did X break". |
| `search` | read_stack | Find products and services by name, provider, category or domain (case-insensitive, partial match). Returns ids and slugs to use with the other tools. |
| `list_integrations` | read_stack | The catalogue of providers ninedot connects to (Vercel, Railway, Netlify, Supabase, Neon, Stripe, Resend, Cloudflare, OpenAI, Anthropic): what each reads, which figures are exact or measured, the kind of key needed and whether it can be read-only, and which ones this workspace has connected. Use it to tell a person what connecting an account would give them. |
| `get_history` | read_costs | Daily MRR and monthly cost for one product over the last 7 to 365 days, from the figures recorded on each sync of connected accounts (costs typed by hand aren't included). Use it to answer "how has this changed". |
| `get_status` | read_stack | Health of each product: 30-day uptime from ninedot's pings, the last check, service statuses and recent events. Services added by hand have status not_monitored: nothing checks them. |
| `list_alerts` | read_stack | Everything that needs attention now: sites down, services failing or degraded, and connections whose sync failed. |
| `list_connections` | read_stack | Provider accounts connected in the Vault (read-only): id, provider, label, sync status and how many resources each found. Never returns tokens. Connecting a new account is done by a person in ninedot. |
| `list_linkable` | read_stack | Resources found in connected accounts (Vercel projects, Supabase projects, Stripe products, ...) and which product each is on, if any. |
| `list_requests` | read_stack | Removal requests and whether a person approved, denied or hasn't decided yet. |
| `suggest_products` | read_stack | Products ninedot can set up from connected accounts: hosting projects grouped by domain or name, with the matching database, email domain and Stripe products. Each service says why it matched. Read-only: nothing is created by listing them. |
| `create_product` | manage | Add a product: any digital business (app, YouTube channel, newsletter, online store or community). Apps and stores with a public https URL get uptime checks every five minutes. A YouTube channel URL (youtube.com/@name) makes a channel instead: followed by its subscribers and views, not pinged. Returns the new slug. |
| `update_product` | manage | Rename a product, change its public URL or its kind. To make it a YouTube channel, pass kind "channel" with the channel URL as url; its other services stay. Pass url "" to remove the URL (stops uptime checks). |
| `link_service` | manage | Put a resource from a connected account on a product. Its status, cost and revenue then come from the provider. A Stripe account is linked whole or product by product, never both. |
| `assign_services` | manage | Put several services from one connected account on businesses at once. Each item names a service by externalId and a target: a business slug, "new:<suggestion key>" to create that suggested business (created once, however many services go to it), or "" to leave it for now. Services already on a business are left alone. |
| `add_manual_service` | manage | Add a service ninedot can't connect to yet, e.g. a domain or an AI API. A monthly cost given here is only a suggestion: it stays an estimate, not counted, until the owner confirms it in ninedot. |
| `add_youtube_channel` | manage | Follow a YouTube channel on a product: subscribers, total views, uploads and recent views from YouTube's public statistics, read twice a day. Nothing to connect. Suits a SaaS with its own channel. A channel can also be a product of its own, created with its channel URL. |
| `set_service_notes` | manage | Replace the notes on a service (plan details, renewal dates, gotchas). Pass an empty string to clear. |
| `sync_connection` | manage | Refresh a connected account's resources and figures now. Limited to 6 syncs per connection every 10 minutes. |
| `accept_suggestion` | manage | Create the suggested product (or add to the existing one) and link its services. Pass services to take only some of them, or product to put them on a different business you already have. |
| `dismiss_suggestion` | manage | Mark a suggestion as not a product so it isn't suggested again. |
| `request_removal` | manage | Ask a person to remove a service from a product, or delete a product. Nothing changes until they approve it in ninedot. |

### Resources and prompts

- Resources (`resources/list`, `resources/read`): `ninedot://docs` (this document), `ninedot://integrations` (the catalogue as markdown), `ninedot://stack` (the workspace's products and services as markdown, for context windows).
- Prompts (`prompts/list`, `prompts/get`): `weekly_review`, `whats_at_risk`, `why_did_costs_change` (argument: product), `set_up_stack`. Each one tells the model which tools to call and how to report figures with their trust level.

### Rules agents can rely on

- Every money figure is verified (exact or measured) and has a source. Quote it.
- Agents never see tokens or secrets, only names and status.
- Nothing an agent does can change a provider account. Removals wait for a person.
- Every call is logged and visible to the workspace owner.

Human-readable version: https://ninedot.app/mcp · Integrations: https://ninedot.app/integrations.md · Sign up: https://ninedot.app/sign-in
