cost-calc

Connect your AI agent to the cost calculator

Let an AI agent size and price self-hosted infrastructure for you. The calculator is available as a remote MCP server and as a REST API. The agent picks a product, reads its parameters, sends a workload, and gets back a monthly cost with line items, assumptions, price sources, the price snapshot date and a link to a human-readable result.

What you can ask

Quick start

  1. Create an API key. Sign in on the calculator with your email, open Agent keys, and create a key. It looks like ope_live_ followed by 64 hex characters and is shown once, so copy it then.
  2. Add the server to your client. Use the URL https://calc-api.onpremeasy.com/mcp and send the key as Authorization: Bearer <key>. Copy-paste setups for common clients are below.
  3. Ask. For example: "Use the onpremeasy tools to estimate the monthly cost of Kafka with 3 brokers and 1000 GB retained data."

You can skip step 1 to try the free read-only tools: list_products and describe_product need no key. estimate needs a key at the moment (see Limits).

Connect your client

The server uses streamable HTTP, is stateless, and authenticates with a bearer key in the Authorization header. It has no OAuth flow. A client therefore has to be able to send a fixed header. Clients that only offer OAuth or no authentication cannot send the key, see Clients that cannot send a key.

In the examples, replace ope_live_YOUR_KEY with your key. Prefer the environment-variable forms where a client supports them, so the key does not end up in a committed file or in shell history.

Claude Code

Terminal
claude mcp add --transport http onpremeasy https://calc-api.onpremeasy.com/mcp \
  --header "Authorization: Bearer ope_live_YOUR_KEY"

This stores the key in your Claude Code configuration. To keep it out of the command line, put the server in a project .mcp.json and read the key from an environment variable you set yourself (Claude Code expands ${VAR} in headers). Avoid variable names Claude Code treats specially, such as ANTHROPIC_API_KEY.

.mcp.json
{
  "mcpServers": {
    "onpremeasy": {
      "type": "http",
      "url": "https://calc-api.onpremeasy.com/mcp",
      "headers": {
        "Authorization": "Bearer ${ONPREMEASY_API_KEY}"
      }
    }
  }
}

Do not run /mcp to sign in to this server: it uses a header, not OAuth. Use /mcp only to check that it is connected.

Cursor

Add this to .cursor/mcp.json in a project, or ~/.cursor/mcp.json for all projects. Cursor reads ${env:NAME} in headers.

.cursor/mcp.json
{
  "mcpServers": {
    "onpremeasy": {
      "url": "https://calc-api.onpremeasy.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:ONPREMEASY_API_KEY}"
      }
    }
  }
}

VS Code with GitHub Copilot

Add this to .vscode/mcp.json in the workspace. VS Code uses the key servers (not mcpServers). The inputs entry makes VS Code ask for the key once and hide what you type, so nothing secret is in the file.

.vscode/mcp.json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "onpremeasy-key",
      "description": "onpremeasy API key",
      "password": true
    }
  ],
  "servers": {
    "onpremeasy": {
      "type": "http",
      "url": "https://calc-api.onpremeasy.com/mcp",
      "headers": {
        "Authorization": "Bearer ${input:onpremeasy-key}"
      }
    }
  }
}

You can also run MCP: Add Server from the Command Palette and choose HTTP. Organisations that manage Copilot may have MCP servers switched off by policy.

Codex CLI

Add this to ~/.codex/config.toml (shared by the Codex CLI, IDE extension and desktop app). bearer_token_env_var names an environment variable; Codex sends its value as the bearer token. The codex mcp add --url command exists but, per the docs, has no flag for a bearer token, so edit the file.

~/.codex/config.toml
[mcp_servers.onpremeasy]
url = "https://calc-api.onpremeasy.com/mcp"
bearer_token_env_var = "ONPREMEASY_API_KEY"

Setting the environment variable

Terminal
export ONPREMEASY_API_KEY=ope_live_YOUR_KEY

Set it in the shell that launches the client, or in your shell profile. A desktop client started from a launcher may not see variables from a terminal.

Clients that cannot send a key

Some chat apps add MCP servers as "connectors" and only offer OAuth or no sign-in. They cannot send our bearer key, and this server has no OAuth. What works instead:

Try it with curl (MCP)

This is the raw protocol, useful to check your key. Send both Accept types. The server is stateless: each request stands alone, with no session id.

initialize
curl -sS https://calc-api.onpremeasy.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $ONPREMEASY_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
tools/list
curl -sS https://calc-api.onpremeasy.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $ONPREMEASY_API_KEY" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
tools/call: describe_product (free, no key needed)
curl -sS https://calc-api.onpremeasy.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"describe_product","arguments":{"product":"kafka-cluster"}}}'
tools/call: estimate (key needed, uses one daily slot)
curl -sS https://calc-api.onpremeasy.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H "Authorization: Bearer $ONPREMEASY_API_KEY" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"estimate","arguments":{"product":"kafka-cluster","workload":{"broker_count":3,"retained_data_gb":1000,"partition_count":100}}}}'

Tools

ToolWhat it doesKeyQuota
list_productsLists every product the calculator can size, with its id, category, a short summary and the names of the workload fields estimate needs. Call it first.NoNone
describe_productReturns one product's workload parameters (type, minimum, default, units), topology templates with minimum node counts, and dependency products.NoNone
estimateReturns the monthly cost of a workload: recommended servers per component, monthly price per line item and in total, assumptions, price sources, the price snapshot date and a result link.Yes, currently1 slot per fresh estimate

Typical flow: list_products, then describe_product to learn the exact parameter names and units, then estimate. Unknown workload fields are rejected, and rejected requests are free.

REST API and OpenAPI

The same data is available over plain HTTP under https://calc-api.onpremeasy.com/agent/v1. The machine-readable description is the OpenAPI document. Crawlers and agents that read documentation can start from llms.txt, llms-full.txt or the Markdown version of any product page, for example /product/kafka-cluster.md.

EndpointKeyPurpose
GET /agent/v1/productsNoList products
GET /agent/v1/products/{id}NoParameters, topologies, dependencies and a reference price range
GET /agent/v1/referenceNoProviders, currencies and the current billing and quota facts
POST /agent/v1/estimateYes, currentlyEstimate a workload (JSON body, 16 KiB maximum)
List products (no key)
curl -sS https://calc-api.onpremeasy.com/agent/v1/products
Estimate (key needed)
curl -sS https://calc-api.onpremeasy.com/agent/v1/estimate \
  -H "Authorization: Bearer $ONPREMEASY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"product":"kafka-cluster","workload":{"broker_count":3,"retained_data_gb":1000,"partition_count":100}}'

Optional body fields are provider and currency. Keyed callers may also send an Idempotency-Key header so a retried request is not counted twice.

What an estimate contains

Prices are indicative. They are generated automatically from public price lists and are not quotes. Check the snapshot date, and confirm with the provider before you buy.

Limits and fair use

Troubleshooting

SymptomMeaning and fix
401 authentication_requiredestimate was called without a key. Add the Authorization header.
401 invalid_api_keyThe key is wrong, revoked or malformed. Check that the whole ope_live_ key is there, with Bearer in front and no extra spaces. Create a new key at Agent keys if needed. A bad key never falls back to keyless access.
402 payment_requiredYour account used its free estimates for today. The body gives quota_resets_at (00:00 UTC), retry_after_seconds, and a contact address. Wait for the reset; do not retry in a loop. Cached answers do not help once the quota is spent, because the slot is reserved before the lookup.
503 capacity_reachedThe service-wide daily cap is used up. Retry-After and quota_resets_at say when to try again. Free read-only tools keep working.
429 rate_limitedToo many requests in a minute. Wait for Retry-After.
422 or invalid_requestA workload field is missing, unknown or out of range. problems names it. Call describe_product and use its names and units.
Timeout or llm_unavailableA fresh estimate calls a language model and can take a while, or be temporarily unavailable. Allow a generous timeout, then retry later. A failed estimate is not charged.
Server shows as connected but no tools appearRestart the client and check the URL ends in /mcp. Make sure the client supports streamable HTTP (not only SSE or local commands).

Privacy

Each tool call is logged for operations and abuse control: which tool, the product, the result status, timing, and a salted hash that stands in for the client. The log has no raw IP address, no key material and no request body. Keys are stored only as a hash. See the Privacy Policy. Do not put secrets or personal data in workload fields.

Contact

Questions, a client that does not work, or a need for more capacity: [email protected].