@kadoa/mcp
v0.5.9
Published
Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients
Readme
Kadoa MCP Server
Use Kadoa from ChatGPT, Claude.ai, Claude Code, Cursor, and other MCP clients.
Remote Server (no install needed)
A hosted MCP server is available at https://mcp.kadoa.com/mcp. Connect from any MCP client — no local install needed. You sign in with your Kadoa account via OAuth.
Claude Code
claude mcp add kadoa --transport http https://mcp.kadoa.com/mcpChatGPT
- Go to Settings → Connectors → Add MCP server
- Enter the URL:
https://mcp.kadoa.com/mcp - Choose OAuth authentication and sign in with your Kadoa account (Google)
Claude.ai
- Go to Settings → Connectors → Add custom MCP
- Enter the URL:
https://mcp.kadoa.com/mcp - Sign in with your Kadoa account via OAuth
Cursor
Add to .cursor/mcp.json:
{
"mcpServers": {
"kadoa": {
"type": "http",
"url": "https://mcp.kadoa.com/mcp"
}
}
}Any MCP Client
Point your client to https://mcp.kadoa.com/mcp with OAuth authentication.
Tools
| Tool | Description |
|------|-------------|
| create_workflow | Create an agentic navigation workflow from a prompt |
| list_workflows | List all workflows with status |
| get_workflow | Get detailed workflow information |
| get_workflow_history | Get the workflow's configuration revision history (audit log) — who changed it, when, from which channel, and a changedFields summary per revision |
| run_workflow | Execute a workflow |
| fetch_data | Get extracted data from a workflow |
| delete_workflow | Delete a workflow |
| approve_workflow | Approve and activate a workflow |
| pause_workflow | Pause an active workflow |
| update_workflow | Update workflow configuration and schema |
| whoami | Show current user details, auth method, and team memberships |
| team_list | List all teams you belong to and see which is active |
| team_switch | Switch the active team by name or ID |
Usage Examples
Once the MCP server is configured, you can manage the full workflow lifecycle through natural conversation. Here are a few common operations shown as Claude Code sessions.
Create and run a workflow
> You: Create a workflow to extract product names, prices, and ratings
from https://example-shop.com/products
Claude calls create_workflow and returns the workflow ID, proposed
navigation steps, and data schema for your review.
> You: The schema looks good. Approve it and kick off a run.
Claude calls approve_workflow to activate the workflow, then
run_workflow to start extraction.
> You: Is the run done? Show me the results.
Claude checks the run status with get_workflow, then calls fetch_data
to retrieve the extracted records and display them as a table.Create a workflow from a template
> You: Use my "Product Scraper" template to scrape https://example-shop.com.
Claude calls list_templates to find the matching template, then
create_workflow with `templateId` and `urls` only — the prompt and
schema are inherited from the template version. Returns the workflow
ID for follow-up with get_workflow or fetch_data.Update a workflow and re-run
> You: List my workflows.
Claude calls list_workflows and shows all workflows with their
current status (complete, running, failed, paused, scheduled, etc.).
> You: Update wf_abc123 — add an "availability" field to the schema
and rename "cost" to "price".
Claude calls update_workflow with the new schema, confirms the
changes, and shows the updated field list.
> You: Run it again with the new schema.
Claude calls run_workflow and waits for completion, then fetches
the latest data with fetch_data so you can verify the changes.Monitor and clean up
> You: Show me all active workflows and their last run results.
Claude calls list_workflows, filters to active ones, then calls
fetch_data for each to summarize the latest extraction results.
> You: Delete the ones that haven't produced data in the last week.
Claude identifies stale workflows from the results and calls
delete_workflow for each, confirming before proceeding.Troubleshooting
Claude says "I don't have access to Kadoa"
- Verify the MCP server is configured correctly
- Restart your MCP client
- Re-authenticate via OAuth if prompted
Releases
This repo ships two surfaces, and a "release" usually touches both:
- npm package
@kadoa/mcp— stdio CLI users install locally (npx @kadoa/mcp). Cut by Release Please from Conventional Commits onmain. - Hosted server at
mcp.kadoa.com— Docker container on GKE, built and deployed from thekadoa-backendmonorepo, which pins a specific@kadoa/mcpversion.
Relevant files in kadoa-backend:
infra/docker/mcp/Dockerfile.mcp-server— image definitioninfra/docker/mcp/package.json— pinned@kadoa/mcpversioninfra/cdk8s/mcp/charts/Server.ts— k8s manifest source (prod chart only; the test deployment is provisioned ad hoc — see below)
Production release
- Merge PRs to
mainusing Conventional Commits (feat:,fix:, etc.). Release Please opens/maintains achore(main): release mcp x.y.zPR. - Merge the release PR. The
release-please.ymlworkflow tags, drafts a GitHub Release, and publishes to npm (latestdist-tag). - In
kadoa-backend, bumpinfra/docker/mcp/package.json@kadoa/mcpto the new version, runbun installto refreshbun.lock, open a PR. - Merge to
main. CI (main-build-deploy.yml) builds and pusheseurope-west3-docker.pkg.dev/oceanic-base-310208/kadoa-artifacts/mcp-server:<IMAGE_TAG>(tag shown in the build summary). - Trigger the Deploy to Production workflow (
deploy-prod.yml) with:- Target cluster:
gcp - Deployment scope:
mcp - Image tag: the tag from step 4
- Method:
kubectl
- Target cluster:
RC / test release
Use this when you want to validate a change end-to-end against real clients (Claude Desktop, Cursor, ChatGPT) before promoting to latest / prod. The flow mirrors the prod one, but every step targets rc channels.
There are two ways to consume an RC:
- Local stdio:
npx @kadoa/mcp@rc— installs from thercdist-tag on npm. Good for quick sanity checks where the bug doesn't depend on the hosted OAuth flow. - Hosted
mcp-server-test: a separate k8s deployment alongside prod in the same GKE cluster. Required when you need to validate the OAuth callback, Redis token store, multi-tenant session behavior, etc.
Publish an RC to npm
Manual — Release Please only cuts stable versions today.
# from a branch on kadoa-mcp
bun install && bun run build
# bump version to a prerelease, e.g. 0.5.7-rc.1
npm version 0.5.7-rc.1 --no-git-tag-version
npm publish --tag rc --access publicVerify: npm view @kadoa/mcp dist-tags. The rc tag should now point to your version. Existing tags today: latest, rc, next.
Promote later with: npm dist-tag add @kadoa/[email protected] latest (run after the matching stable version has been published the normal way).
Deploy the RC to mcp-server-test
In
kadoa-backend, setinfra/docker/mcp/package.json@kadoa/mcpto the RC version,bun install, push to a branch and merge tomain. CI builds themcp-server:<IMAGE_TAG>image as usual.Update the test deployment to the new image:
gcloud container clusters get-credentials kadoa-prod \ --region=europe-west3 --project=oceanic-base-310208 kubectl set image deployment/mcp-server-test \ mcp-server=europe-west3-docker.pkg.dev/oceanic-base-310208/kadoa-artifacts/mcp-server:<IMAGE_TAG>Port-forward to reach it (the test deployment has no public ingress by design):
kubectl port-forward svc/mcp-server-test 3000:3000Point your MCP client at
http://localhost:3000/mcpand exercise the change.
Auth gotcha: auth.kadoa.com enforces an ALLOWED_CALLBACK_ORIGINS allowlist (app.kadoa.com, mcp.kadoa.com, kadoa.com) plus a loopback bypass for 127.0.0.1 when NODE_ENV !== production. localhost is not treated the same as 127.0.0.1 by that check. The test pod is configured with MCP_SERVER_URL=http://localhost:3000 so the port-forwarded session resolves correctly. If you change the local port, update the deployment env var too:
kubectl set env deployment/mcp-server-test MCP_SERVER_URL=http://localhost:<PORT>Promotion checklist
Before flipping latest / deploying to prod:
- [ ] RC consumed locally (
npx @kadoa/mcp@rc) — stdio tools work - [ ] RC consumed via
mcp-server-test— OAuth login succeeds end-to-end - [ ] No new errors in the test pod's logs (
kubectl logs deployment/mcp-server-test -f) - [ ] Release Please PR open with the stable version
Development
bun install
bun run dev # Run locally
bun run test # Run tests
bun run build # Build for distributionConnecting to local services
To develop and test against a local Kadoa backend (instead of the production API), point the MCP at your local public-api service using the KADOA_PUBLIC_API_URI environment variable.
Prerequisites: the public-api service must be running locally (default port 12380).
Run the MCP server locally:
KADOA_PUBLIC_API_URI=http://localhost:12380 bun run devThe server starts in HTTP mode. You authenticate via OAuth the same way as with the remote server.
Contributing
A typical feature touches three repos — kadoa-backend → kadoa-sdks → kadoa-mcp. The same surgery on three layers; same operation, different audience above it.
Architecture
| Layer | Repo / path | Role |
|---|---|---|
| Backend endpoint | kadoa-backend/ | The HTTP API. Source of truth; the OpenAPI spec is generated from here. |
| SDK low-level | kadoa-sdks/sdks/node/src/generated/api/* | Auto-generated axios client. Raw HTTP, typed from the OpenAPI spec. Do not hand-edit. |
| SDK domain (high-level) | kadoa-sdks/sdks/node/src/domains/<thing>/<thing>.service.ts | Thin domain wrapper over the generated client. client.<thing>.<action>(...). This is what callers use. |
| CLI | kadoa-cli/src/commands/<thing>.ts | Commander action: flag parsing, spinner, table/json output. Calls SDK domain. |
| MCP (this repo) | kadoa-mcp/src/tools.ts | Zod input schema + tool description tuned for LLMs. Calls SDK domain. |
Mental model:
- SDK = pure function over HTTP.
- CLI = SDK + human UX (flags, table output).
- MCP = SDK + LLM UX (zod schema, prose description).
CLI and MCP both call identical SDK domain methods. A new feature added to the SDK is picked up by both clients for free — as long as we keep the layering honest.
Adding a new feature
Backend (
kadoa-backend)- Add or modify the HTTP endpoint.
- Make sure the OpenAPI spec reflects the change (paths, request/response schemas).
SDK (
kadoa-sdks) — always do this before MCP/CLI work (the SDK-first rule). No bandaidaxioscalls in MCP.- Regenerate the low-level client:
(Swap the endpoint forbun kadoa-codegen fetch-spec -e https://api.kadoa.com/openapi -f bun kadoa-codegen generate -e https://api.kadoa.com/openapi --fetch-latest -fhttp://localhost:12380/openapiwhen developing against a local backend.) - Add or extend the domain service in
sdks/node/src/domains/<thing>/<thing>.service.ts. Keep it typed, noany. - Commit
specs/separately from generated/domain code so the API diff is reviewable. - Open a PR. On merge, a new
@kadoa/node-sdkversion is released.
- Regenerate the low-level client:
MCP (this repo)
- Bump
@kadoa/node-sdkinpackage.jsonto the new version,bun install. - Add the tool in
src/tools.ts:- Zod input schema (use coercion helpers in
src/coercion.tswhere needed — LLM clients sometimes send strings for numbers/bools). - Description string written for the LLM: when to call it, what inputs mean, what the response shape is.
- Implementation calls
ctx.client.<thing>.<action>(...)— never raw HTTP.
- Zod input schema (use coercion helpers in
- Add a unit test under
tests/unit/. - Use a Conventional Commit message (
feat(mcp): ...,fix(mcp): ...). Release Please will cut the next version on merge tomain.
- Bump
CLI (
kadoa-cli), if the feature is user-facing on the command line: mirror the MCP step insrc/commands/<thing>.ts. Same SDK call, different UX.
Anti-patterns
- ❌ Raw
axioscalls or hand-rolled HTTP insrc/tools.ts. Always go throughctx.client.<thing>. - ❌ Putting tool-shaped logic (input validation, response shaping) in the MCP layer when the SDK should expose it. If two clients would need the same logic, it belongs in the SDK.
- ❌ Editing files under
sdks/node/src/generated/by hand. They get overwritten bykadoa-codegen generate. - ❌ Bundling a spec update and an SDK feature in the same commit — keep
specs/PRs separate from domain-method PRs for clean review.
Where to find things in this repo
src/tools.ts— every MCP tool. Single file by design; search for the tool name.src/auth.ts— OAuth flow, JWT verification, team selection.src/client.ts— wires@kadoa/node-sdkper request, injects bearer token.src/http.ts— Express server, transport adapter, session handling.src/redis-store.ts— token store for the hosted server.tests/unit/— bun tests; run withbun run test.
License
MIT
