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
- "How much does it cost to host Kafka on-prem? We need 3 brokers and about 1 TB retained."
- "Compare the monthly cost of a small PostgreSQL HA setup and a Qdrant vector store for our RAG prototype."
- "Which products can you price for self-hosted search, and what workload numbers do you need from me?"
Quick start
- 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. - Add the server to your client. Use the URL
https://calc-api.onpremeasy.com/mcpand send the key asAuthorization: Bearer <key>. Copy-paste setups for common clients are below. - 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
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.
{
"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.
{
"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.
{
"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.
[mcp_servers.onpremeasy]
url = "https://calc-api.onpremeasy.com/mcp"
bearer_token_env_var = "ONPREMEASY_API_KEY"Setting the environment variable
export ONPREMEASY_API_KEY=ope_live_YOUR_KEYSet 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:
- claude.ai custom connectors. Anthropic documents a Request headers section for API keys and bearer tokens (choose "No sign-in", add a header named
authorizationwith the valueBearer ope_live_YOUR_KEY). Anthropic describes it as a beta available to a limited set of organisations, so it may not appear in your account. We have not tested it. See Anthropic: add a connector by URL. If you do not see it, use Claude Code or another client above. - ChatGPT connectors. As far as we could verify, OpenAI documents OAuth, no authentication, or a mixed mode for custom MCP apps, and no field for a fixed bearer key. We have not tested it, and we do not claim support. A connector set to no authentication can use the free
list_productsanddescribe_producttools only;estimatewill answer 401. - Any agent that can make HTTP calls. Use the REST API with the same key. It is the same data and the same limits.
- Other MCP clients. Use the server URL and send the header
Authorization: Bearer ope_live_YOUR_KEYwherever the client allows custom headers. For clients that only launch local commands, a bridge such asmcp-remotecan pass a header; we have not tested one.
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.
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"}}}'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":{}}'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"}}}'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
| Tool | What it does | Key | Quota |
|---|---|---|---|
list_products | Lists 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. | No | None |
describe_product | Returns one product's workload parameters (type, minimum, default, units), topology templates with minimum node counts, and dependency products. | No | None |
estimate | Returns 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, currently | 1 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.
| Endpoint | Key | Purpose |
|---|---|---|
GET /agent/v1/products | No | List products |
GET /agent/v1/products/{id} | No | Parameters, topologies, dependencies and a reference price range |
GET /agent/v1/reference | No | Providers, currencies and the current billing and quota facts |
POST /agent/v1/estimate | Yes, currently | Estimate a workload (JSON body, 16 KiB maximum) |
curl -sS https://calc-api.onpremeasy.com/agent/v1/productscurl -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
line_itemsandtotals: the recommended server configuration per component with its monthly price, and the total.assumptions: what the calculator assumed about your workload.price_sourcesandprice_snapshot_date: which public price lists were used and the date of the snapshot.result_url: a link a person can open to see the full result.billing: whether the answer came from the cache and how many daily slots it used.
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
- Free read-only tools. Listing, describing and reading reference data need no key and use no quota.
- 20 fresh estimates per account per UTC day. The count is shared by all keys of one account and resets at 00:00 UTC. You can have up to 5 active keys.
- Cache hits are free. An identical repeated request (same product, workload, provider and currency) is served from the cache and uses no slot. Failed estimates are not counted.
- Keyless estimates. An anonymous quota exists in the server but is switched off, so
estimatewithout a key answers 401 today. This may change. - Service-wide daily cap. A cap on fresh estimates across all callers protects the service. When it is reached,
estimateanswers 503 until 00:00 UTC. - Rate limits. 30 requests per minute per key and 10 per minute per IP for keyless calls (429 with
Retry-After). - These numbers can change.
GET /agent/v1/referenceshows the current facts, and the 402 and 503 bodies state the reset time.
Troubleshooting
| Symptom | Meaning and fix |
|---|---|
401 authentication_required | estimate was called without a key. Add the Authorization header. |
401 invalid_api_key | The 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_required | Your 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_reached | The 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_limited | Too many requests in a minute. Wait for Retry-After. |
422 or invalid_request | A workload field is missing, unknown or out of range. problems names it. Call describe_product and use its names and units. |
Timeout or llm_unavailable | A 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 appear | Restart 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].