# ninedot > Every product. One screen. Your stack, costs and revenue, watched by Nine. Last updated: 2026-10-25 ninedot is mission control for indie builders: every product's services, monthly costs and revenue on one screen, watched by Nine, an AI agent that never changes anything without your approval. ## What it answers - **Is it working?** Live status of every service in each product's stack. - **What does it cost?** Monthly spend per service, rolled up per product. - **What does it earn?** Revenue, MRR and net margin, pulled from the payment provider. ## Features - **Portfolio.** Totals across every product (MRR, monthly spend, net margin) with one row per product. - **Product map.** Each product opens on a live architecture map of its services, with status and monthly cost on every node. - **Service drawer.** Plan, usage against limits, cost trend and key metrics for any single service, without leaving the map. - **Trust signal.** Every figure shows where it came from, how exact it is (exact or measured) and how fresh it is. Only figures read from providers are ever counted. - **Uptime and outage emails.** Every product's public URL is checked every five minutes, with an email when it goes down and when it's back. - **Alerts that matter.** Emails when a deploy or service fails, when Stripe payments start failing, and before an SSL certificate or domain expires. Each kind can be turned off. - **Weekly summary.** A Monday-morning email with MRR, spend and margin against last week, uptime per product and anything that needs you. - **AI spend per product.** Connect OpenAI or Anthropic and each project or workspace's API spend over the last 30 days sits on the product that uses it, next to hosting and database costs. - **Channels.** A YouTube channel can be a product of its own, or sit on a SaaS next to its stack. ninedot reads subscribers, views and uploads from public stats twice a day: nothing to connect. - **History.** Each product charts MRR and monthly cost over time from every sync, so you can see what changed and when. - **Nine.** The built-in agent. Her mood shows each product's state at a glance. Connect your own AI model (Claude, OpenAI or any model through OpenRouter) and she answers questions from your live stack, citing where each figure came from. She can only read. - **MCP server.** Claude, ChatGPT, Cursor and other agents connect with OAuth or an agent key to read each product's stack, status, costs and alerts, and add or edit products if allowed. - **Approvals queue.** Anything an agent wants removed is a request with a reason and impact, which you approve or deny. Agents never change a provider account. ## Integrations - Available now (read-only): Vercel, Railway, Netlify, Supabase, Neon, Stripe, Resend, Cloudflare, OpenAI, Anthropic, YouTube. Details per provider: https://ninedot.app/integrations (markdown: /integrations.md, /md/integrations/) - Planned: Lemon Squeezy - Anything else can be added as a manual service. A monthly cost the owner enters counts in their totals, labelled "Confirmed by you", and is never shown as verified. All read-only. Every figure carries a trust level: exact (read from the provider), measured (derived from usage or a rolling window) or estimated (plan list price). Connect an account once in ninedot → Vault and use it across every product. ## Vercel · hosting Deploy status, domains and what each project really costs. Reads: Your projects, their production deploy status and custom domains, and the team's billing export. Gives you: - Production deploy status per project (failed deploys raise an alert) (live status) - Cost per project over the last 30 days, from Vercel's own billing data (measured) - Team plan and seats, counted once so nothing is double-counted (measured) - Custom domains, used to match the rest of a product's stack automatically (exact) Limits: - Tokens from a role without billing access can't prove cost: ninedot suggests the plan's list price for you to confirm. - Nothing is ever changed in Vercel. Key: Access token. Vercel tokens can't be made read-only; ninedot only ever reads. Create it at https://vercel.com/account/settings/tokens. Steps: https://ninedot.app/integrations/vercel ## Railway · hosting Every service and its latest deploy. Reads: Projects, services and the state of each service's latest deploy. Gives you: - Deploy status per service: deployed, deploying, crashed, sleeping (live status) Limits: - Railway's API doesn't expose dollar cost per project, so cost is left blank rather than guessed. - Nothing is ever changed in Railway. Key: Account token. Railway tokens can't be made read-only; ninedot only ever reads. Create it at https://railway.com/account/tokens. Steps: https://ninedot.app/integrations/railway ## Netlify · hosting Sites, custom domains and production deploys. Reads: Sites, their custom domains, the latest production deploy and your account plan. Gives you: - Production deploy status per site (live status) - Custom domains, used to match a product's other services (exact) - Account plan name (exact) Limits: - Netlify doesn't report plan prices through its API, so cost is left blank. - Nothing is ever changed in Netlify. Key: Personal access token. Netlify tokens can't be made read-only; ninedot only ever reads. Create it at https://app.netlify.com/user/applications#personal-access-tokens. Steps: https://ninedot.app/integrations/netlify ## Supabase · database Project health and your plan. Reads: Projects, their health status and your organisation's plan. Gives you: - Project health: healthy, paused, unhealthy, restoring (live status) - Plan list price per organisation, shown only to you (estimate to confirm) Limits: - Supabase doesn't report what it bills, so ninedot suggests a list-price estimate for you to confirm; it's never shown as verified. - Nothing is ever changed in Supabase. Key: Scoped access token (read-only). Give it Read access to Organizations, Organization Settings and Projects (account-wide), nothing else. Create it at https://supabase.com/dashboard/account/tokens. Steps: https://ninedot.app/integrations/supabase ## Neon · database Postgres projects across your organisations. Reads: Projects, their region and Postgres version, and each organisation's plan. Gives you: - Projects with region and Postgres version (exact) - Plan name per organisation (exact) Limits: - Neon only reports usage costs on its higher plans, so cost is left blank. - Nothing is ever changed in Neon. Key: API key. Neon keys can't be made read-only; ninedot only lists projects. Create it at https://console.neon.tech/app/settings/api-keys. Steps: https://ninedot.app/integrations/neon ## Stripe · payments MRR per product, fees, refunds and chargebacks. Reads: Subscriptions, products, balance transactions, charges and disputes, read-only. Gives you: - MRR per Stripe product and for the whole account (exact) - Stripe's fees, counted as a cost so margin is net of fees (measured) - Collected, net landed, refunds and one-off sales over the last 30 days (measured) - New, cancelled and trialing subscriptions in the last 30 days (exact) - Failed payments and new chargebacks raise an email alert (live status) Limits: - Discounted or metered subscriptions make MRR measured rather than exact. - Currencies aren't converted: a product in USD and one in AUD aren't added together. - Nothing is ever changed in Stripe. Key: Restricted key (read-only) (read-only). Read access to Subscriptions, Products, Balance, Charges and Disputes. Everything else stays off. Create it at https://dashboard.stripe.com/apikeys/create. Steps: https://ninedot.app/integrations/stripe ## Resend · email Sending domains and their DNS status. Reads: Sending domains and whether their DNS records are verified. Gives you: - Domain verification status (a domain failing DNS checks raises an alert) (live status) - Sending domain, used to match a product's other services (exact) Limits: - Resend doesn't report plan or cost through its API. - Nothing is ever changed in Resend. Key: API key (full access). Resend's sending-only keys can't list domains; ninedot only reads. Create it at https://resend.com/api-keys. Steps: https://ninedot.app/integrations/resend ## Cloudflare · dns Domains, plans and Pages projects. Reads: Zones with their status and plan, and Pages projects with their latest deploy. Gives you: - Zone status (active, pending nameservers, moved) (live status) - Zone plan list price, as an estimate for you to confirm (estimate to confirm) - Pages production deploy status and custom domains (live status) Limits: - Pages needs the token's Pages Read permission; without it domains still work. - Nothing is ever changed in Cloudflare. Key: API token (read-only) (read-only). Zone Read, Cloudflare Pages Read and Account Settings Read, scoped to the zones you choose. Create it at https://dash.cloudflare.com/profile/api-tokens. Steps: https://ninedot.app/integrations/cloudflare ## OpenAI · ai API spend per project, on the product that uses it. Reads: Projects and what each spent on the API over the last 30 days, from the organisation Costs API. Gives you: - Spend per project, last 30 days, with the last 7 days and the biggest model (measured) Limits: - Needs an organisation admin key with Read only permissions; project keys can't read costs. - Spend is a rolling 30-day window, not a calendar-month invoice. Key: Admin key (read-only) (read-only). Created by an organisation owner with Permissions set to Read only. Create it at https://platform.openai.com/settings/organization/admin-keys. Steps: https://ninedot.app/integrations/openai ## Anthropic · ai Claude API spend per workspace, on the product that uses it. Reads: Workspaces (including the default one) and what each spent over the last 30 days, from the cost report. Gives you: - Spend per workspace, last 30 days, with the last 7 days and the biggest model (measured) Limits: - Needs an organisation Admin API key; individual accounts have no Admin API. - Anthropic admin keys can't be limited to read-only; ninedot only calls the workspace list and cost report. Key: Admin API key. Created under Settings → Admin keys by an organisation admin. Create it at https://platform.claude.com/settings/admin-keys. Steps: https://ninedot.app/integrations/anthropic ## YouTube · audience Subscribers, views and uploads for every channel you run. Reads: A channel's public statistics: subscribers, total views, video count, its latest uploads and their views. Gives you: - Subscribers, as YouTube shows them publicly (rounded to three figures) (measured) - Total channel views and number of videos (exact) - Last upload, and average views across the latest five (exact) - Subscriber history, kept from every read (measured) Limits: - Public figures only: watch time, revenue and analytics need YouTube's private API, which isn't connected yet. - Read twice a day, not live. - A channel that hides its subscriber count shows views only. Nothing to connect: public figures. Steps: https://ninedot.app/integrations/youtube ## 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:" 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. ## FAQ ### What is ninedot? ninedot puts every product you run on one screen: what it runs on, what it costs, what it earns and whether it's up. It connects to your hosting, database, payment and email providers, and Nine, the built-in AI agent, flags anything that breaks. ### Who is it for? Solo builders and small teams running two to ten products, including makers who build with AI coding tools and freelancers who run client apps across many accounts. ### How much does it cost? It's free during the beta, with no card needed. Pricing isn't set yet, and we'll tell you well before anything changes. ### What can I connect? Vercel, Railway, Netlify, Supabase, Neon, Stripe, Resend, Cloudflare, OpenAI and Anthropic today, all read-only. OpenAI and Anthropic show each project's or workspace's API spend over the last 30 days, so AI costs land on the product that runs them. Anything else can be added by hand, with what you pay; it counts in your totals marked as confirmed by you. Lemon Squeezy is planned. ### Does ninedot change anything in my accounts? No. Connections are read-only and use the narrowest access each provider offers. When Nine can suggest fixes, every change will wait in an approvals queue until you say yes. ### How are my API keys stored? Keys are encrypted at rest, only read by our servers and never sent to your browser or to agents. Disconnecting a provider deletes its key straight away. ### How accurate are the numbers? Every figure that counts is read from the provider, never typed in by hand: exact (from billing) or measured (from usage), with its source and how fresh it is. Where a provider can't report a bill, ninedot suggests an estimate and you confirm what you actually pay; those figures count in your own totals, labelled “Confirmed by you”, and are never shown as verified or shared. ### How is it different from Stripe's dashboard or a revenue tool? Revenue tools show what you earn. ninedot adds what each product runs on and what each service costs, across every provider, so you see health and margin per product in one place. ### Can AI agents use ninedot? Yes. In Claude.ai or ChatGPT, add https://ninedot.app/api/mcp as a connector and sign in. For Claude Code, Cursor or scripts, create a key on the Agents page. Agents read each product's stack, status and alerts, plus costs and adding or editing products if you allow it. Anything they want removed waits for your approval, they never see your secrets, and they can't change your provider accounts. ## Links - Website: https://ninedot.app - Short summary for language models: https://ninedot.app/llms.txt