@kelviq/mcp-server
v0.4.0
Published
Model Context Protocol server for Kelviq — typed tools for the Kelviq API plus searchable documentation resources.
Maintainers
Readme
@kelviq/mcp-server
A Model Context Protocol server for Kelviq, the SaaS monetization & subscription platform.
Gives any MCP-capable client (Claude Desktop, Claude Code, Cursor, Zed, …) two capabilities at once:
- Typed tools for the full Kelviq REST API — manage products, plans, features, entitlements, customers, subscriptions, checkout sessions, license keys, usage, promotions, and the customer portal.
- Searchable documentation — the entire Kelviq docs site is bundled
inside the package and exposed as MCP resources plus
docs_search/docs_readtools, so the LLM can ground its answers in the canonical docs.
45 tools across 9 domains, 69 resources including the full OpenAPI spec. Works offline for docs Q&A — only API tools require a key.
Install
npm install -g @kelviq/mcp-server
# or, no install needed:
npx -y @kelviq/mcp-serverConfigure your MCP client
Claude Code (CLI)
claude mcp add kelviq \
--env KELVIQ_SERVER_API_KEY=<your-server-key> \
--env KELVIQ_CLIENT_API_KEY=<your-client-key> \
-- npx -y @kelviq/mcp-serverThe
--separator is required: it tellsclaudethat everything after it is the command + its args, so flags like-yaren't intercepted by theclaudeCLI itself. Put all--envflags before the--.
Then /mcp in a new Claude Code session shows kelviq connected.
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"kelviq": {
"command": "npx",
"args": ["-y", "@kelviq/mcp-server"],
"env": {
"KELVIQ_SERVER_API_KEY": "server-...",
"KELVIQ_CLIENT_API_KEY": "client-..."
}
}
}
}Restart Claude Desktop. The hammer icon shows kelviq with all tools.
Cursor / Zed / other MCP clients
Any client that supports stdio MCP servers — point it at
npx -y @kelviq/mcp-server with the env vars above.
Get your API keys
app.kelviq.com/settings/api-keys.
The Server key is required for all API tools; the Client key is only
needed if you use promotion_get (it hits the edge endpoint with the public
key). Docs tools (docs_search, docs_read) work with no keys at all.
Never commit keys to git. Use
--env/ your MCP client's secrets mechanism, never inline them in shared config.
Environment variables
| Variable | Required | Default | Purpose |
|---|---|---|---|
| KELVIQ_SERVER_API_KEY | yes (for API tools) | — | Bearer token for api.kelviq.com |
| KELVIQ_CLIENT_API_KEY | only for promotion_get | — | Bearer token for the edge host |
| KELVIQ_ENV | no | production | sandbox switches both API hosts (base + edge) to their sandbox equivalents. Any other value fails fast at startup. |
| KELVIQ_BASE_URL | no | https://api.kelviq.com/api/v1 | Override (self-host, custom routing). Wins over KELVIQ_ENV. |
| KELVIQ_EDGE_URL | no | https://edge.api.kelviq.com/api/v1 | Override the edge host (entitlements + promotions). Wins over KELVIQ_ENV. |
Sandbox keys only work against the sandbox environment — the API enforces key↔host binding server-side, so a sandbox key against the production host (or vice versa) returns 403s rather than routing you anywhere useful.
To point at Kelviq sandbox:
KELVIQ_ENV=sandboxThis resolves KELVIQ_BASE_URL to https://sandboxapi.kelviq.com/api/v1 and
KELVIQ_EDGE_URL to https://edge.sandboxapi.kelviq.com/api/v1. To point at
a self-hosted or otherwise custom deployment, set KELVIQ_BASE_URL /
KELVIQ_EDGE_URL explicitly instead — they always take precedence over
KELVIQ_ENV.
Tools
Customers
customer_create— create a customercustomer_update— patch an existing customer
Checkout & Portal
checkout_create_session— create a hosted checkout sessionportal_session_create— mint a customer portal URL
Subscriptions
subscription_create— create a subscription directly (skip checkout)subscription_list— list subscriptions, filter by customersubscription_update— change plan / charge period / featuressubscription_cancel— immediately, at period end, or on a specific date
Entitlements, Licenses, Usage
entitlements_get— fetch a customer's entitlements (all, or by featureId)license_activate/license_deactivate/license_validate— license key lifecycleusage_report— report metered usage (SETorDELTA)
Offerings & Promotions
offering_get_product— public pricing scoped to a product UUIDpromotion_get— resolve the active promotion for the caller's location (uses Client API key, edge host)
Catalog: Products
product_list/product_create/product_retrieve/product_update/product_archiveproduct_settings_get/product_settings_update— VPN/Tor/proxy policy, default currency, product URLproduct_image_update/product_image_delete
Catalog: Features
feature_list/feature_create/feature_retrieve/feature_archive
Catalog: Plans
plan_list/plan_create/plan_retrieve/plan_update/plan_archiveplan_publish— release the latest draft, optionally migrate existing customersplan_discard_draft— drop the current draft, keep the published versionplan_prices_list— per-currency pricing on a planplan_entitlements_list/plan_entitlements_add/plan_entitlement_update/plan_entitlement_deleteplan_file_update/plan_file_delete/plan_file_download— plan-attached digital deliverables
Docs (no API key required)
docs_search— full-text search across the bundled docs; returns slugsdocs_read— fetch a single doc page by slug
Resources
kelviq://docs/{section}/{slug}— every conceptual page in the Kelviq docs (67 pages)kelviq://openapi.json— the full OpenAPI 3.0 spec (55 operations, all schemas)kelviq://README— top-level Kelviq overview
The OpenAPI spec is the source of truth for request/response shapes — for any endpoint detail the LLM can read it inline via the resource.
Try it
Once wired into your MCP client, try prompts like:
- "Search Kelviq docs for license keys" →
docs_search+docs_read - "List my Kelviq products" →
product_list - "Create a plan named 'Pro Monthly' under product UUID
…, then publish it" →plan_create→plan_publish - "What entitlements does customer
acme-42have forseats?" →entitlements_get - "Create a checkout session for plan
pro-monthly, success URLhttps://example.com/ok" →checkout_create_session - "What prices are configured on plan
pro-monthly?" →plan_prices_list
The LLM picks the tool from the description — you don't need to say "use the tool called X."
Test without an LLM
Use the MCP Inspector:
npx -y @modelcontextprotocol/inspector \
npx -y @kelviq/mcp-serverOpens a browser UI where you can browse all 45 tools, fill in arguments, and run them against the real Kelviq API. Pre-fill env vars by exporting them before the command:
KELVIQ_SERVER_API_KEY=<key> KELVIQ_CLIENT_API_KEY=<key> \
npx -y @modelcontextprotocol/inspector \
npx -y @kelviq/mcp-serverIf the Inspector opens but the Command field shows the default placeholder
(mcp-server-everything), fill in:
| Field | Value |
|---|---|
| Transport Type | STDIO |
| Command | npx |
| Arguments | -y @kelviq/mcp-server |
| Environment Variables | KELVIQ_SERVER_API_KEY=…, KELVIQ_CLIENT_API_KEY=… |
Then click Connect.
Troubleshooting
Claude Code: Executable not found in $PATH: "node"
GUI/launcher processes don't source ~/.zshrc, so nvm's node isn't on the
PATH. Either:
Symlink node into a system path:
sudo ln -s "$(which node)" /usr/local/bin/nodeOne-time fix for every MCP server you'll ever add.
Use the absolute path in the
claude mcp addcommand:claude mcp add kelviq \ --env KELVIQ_SERVER_API_KEY=... \ -- /Users/you/.nvm/versions/node/v20.19.0/bin/node \ $(npm root -g)/@kelviq/mcp-server/dist/server.jsInstall node via Homebrew (
brew install node) so it lives on the system PATH.
Tool returns {"error": {"status": "Configuration error", …}}
Means a required env var is missing. The error message names which one. Set it in your MCP client config and reconnect.
API tool returns {"error": {"status": "Bad request", "message": "Invalid product identifier"}}
Your API key works but the plan/product/feature identifier doesn't exist on
this account. Common cause: server key is for production but the
identifier exists only in staging (or vice versa). Check
KELVIQ_BASE_URL.
Develop locally
git clone https://github.com/kelviq/kelviq-mcp-server.git
cd kelviq-mcp-server
npm install # also installs husky git hooks
npm run snapshot # snapshot ../docs into src/docs/ (expects sibling kelviq/docs repo)
npm run build # tsc -> dist/
npm run dev # tsx src/server.ts (no build needed)
npm run inspect # launch MCP Inspector against the dev server
npm run typecheck
npm run lint # eslint
npm run lint:fix # eslint --fixCommit conventions
This repo uses Conventional Commits — enforced by commitlint via a husky commit-msg hook. Format:
<type>(optional scope): <subject>Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert.
Examples:
feat(plans): add plan_publish tool
fix(http): handle non-JSON 500 responses
docs: clarify env-var precedence
chore(deps): bump @modelcontextprotocol/sdk to 1.30The pre-commit hook runs lint-staged, which auto-fixes staged .ts / .js files via ESLint.
Don't want to remember the format? Use commitizen instead of git commit:
git add .
npm run commit # interactive prompt walks you through type, scope, subjectThe prompt is generated from this repo's commitlint.config.js, so it'll never let you build a message commitlint would reject.
The snapshot step expects the kelviq/docs repo
checked out as a sibling directory of mcp-server/. The published npm package
ships the snapshot inline, so end-users never need the docs repo.
To add a new tool:
- Add a zod schema to
src/schemas/kelviq.ts. - Add a
register…Tools(server, http)call in a new (or existing) file undersrc/tools/. - Wire it into
src/tools/index.ts. npm run build && npm run inspectto verify.
Architecture
src/
├── server.ts # MCP server bootstrap (stdio transport)
├── config.ts # env loading
├── http/ # fetch wrapper + normalized errors
├── schemas/kelviq.ts # zod schemas derived from openapi.json
├── tools/ # one file per domain — registerXxxTools(server, http)
├── resources/ # docs index + ListResources / ReadResource handlers
└── docs/ # snapshot of ../docs + openapi.json (built at npm publish)The HTTP client routes between two hosts based on each tool's host / auth
arguments:
api.kelviq.com— main API (Server key)edge.api.kelviq.com— entitlements (Server key) and promotions (Client key)
All API responses are passed through as JSON text content; errors are
returned as { error: { status, message } } with isError: true rather than
thrown, so the LLM can react to them.
License
MIT — see LICENSE.
Support
- Kelviq docs: docs.kelviq.com
- Email: [email protected]
- Issues: github.com/kelviq/kelviq-mcp-server/issues
