{"_id":"@cogitx-ai/mcp-server","name":"@cogitx-ai/mcp-server","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@cogitx-ai/mcp-server","version":"0.1.0","description":"MCP server for the CogitX platform — build, inspect and run workflows and agents from any MCP-capable coding agent.","license":"SEE LICENSE IN LICENSE.md","type":"module","bin":{"cogitx-mcp":"dist/index.js"},"main":"dist/index.js","engines":{"node":">=20"},"scripts":{"build":"tsc -p tsconfig.json","dev":"tsc -p tsconfig.json --watch","start":"node dist/index.js","typecheck":"tsc -p tsconfig.json --noEmit","test":"node --test dist/**/*.test.js","prepublishOnly":"npm run build"},"dependencies":{"@modelcontextprotocol/sdk":"^1.20.0","zod":"^3.25.76"},"devDependencies":{"@types/node":"^22.10.0","typescript":"^5.9.3"},"keywords":["mcp","model-context-protocol","cogitx","workflow","agents","claude","cursor","ai"],"homepage":"https://github.com/CogitX/platform-backend/tree/main/mcp#readme","repository":{"type":"git","url":"git+https://github.com/CogitX/platform-backend.git","directory":"mcp"},"bugs":{"url":"https://github.com/CogitX/platform-backend/issues"},"publishConfig":{"access":"public"},"_id":"@cogitx-ai/mcp-server@0.1.0","gitHead":"afb04fb9adbe123b9087cb55cc815688de787427","types":"./dist/index.d.ts","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-D+Gvw0CDL2NUpmsS7jic8ig6xqBsbOltoiidlMPH0IDRDMHfwnPFameG8TnLKMkMyIUqrTaD2jqd5kMYM0ki6g==","shasum":"7d81d5b4968115fb5047974ccb52ea8b13f66643","tarball":"https://registry.npmjs.org/@cogitx-ai/mcp-server/-/mcp-server-0.1.0.tgz","fileCount":30,"unpackedSize":74053,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCMGqaA2GhwuBOfOzSs5+ud8TycjlR76R8EWvw//XE1IgIhAMkdi5bLy9u+HME4vXhDBgK4Ywyr3df3NjZqSKI+AE89"}]},"_npmUser":{"name":"adarsh-cogitx","email":"adarsh@cogitx.ai"},"directories":{},"maintainers":[{"name":"adarsh-cogitx","email":"adarsh@cogitx.ai"},{"name":"kushan-cogitx","email":"kushan@cogitx.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-server_0.1.0_1788414696400_0.3773776496677288"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-03T05:51:36.150Z","0.1.0":"2026-09-03T05:51:36.536Z","modified":"2026-09-03T05:51:36.825Z"},"maintainers":[{"name":"adarsh-cogitx","email":"adarsh@cogitx.ai"},{"name":"kushan-cogitx","email":"kushan@cogitx.ai"}],"description":"MCP server for the CogitX platform — build, inspect and run workflows and agents from any MCP-capable coding agent.","homepage":"https://github.com/CogitX/platform-backend/tree/main/mcp#readme","keywords":["mcp","model-context-protocol","cogitx","workflow","agents","claude","cursor","ai"],"repository":{"type":"git","url":"git+https://github.com/CogitX/platform-backend.git","directory":"mcp"},"bugs":{"url":"https://github.com/CogitX/platform-backend/issues"},"license":"SEE LICENSE IN LICENSE.md","readme":"# CogitX Platform MCP Server\n\nAn [MCP](https://modelcontextprotocol.io) server that lets any MCP-capable coding\nagent — Claude Code, Cursor, Windsurf, Zed, a custom client — create projects and\nbuild, inspect, run and delete CogitX workflows and agents.\n\nIt speaks **stdio** to the coding agent and **HTTPS** to the platform's\n`/mcp/v1` surface.\n\n**Every call acts as a real platform user.** The credential you configure\nresolves to a user, and that user's RBAC decides what the agent can reach — the\nsame `@ResourceAccess` checks the web app goes through. A credential carries no\npermissions of its own, so an agent can never do something you couldn't do\nyourself in the UI.\n\n---\n\n## 1. Choose a credential\n\n> These are two different services. Personal access tokens and login live on\n> **identity** (`$IDENTITY_URL`); MCP client credentials and the `/mcp/v1`\n> surface live on **project** (`$PROJECT_URL`). `COGITX_BASE_URL` points at the\n> project service.\n\nThree work. Pick by how long it needs to live and how much it should reach.\n\n| | Reaches | Lives | Use for |\n|---|---|---|---|\n| **Platform JWT** | everything the user can | `JWT_EXPIRATION` (**2h**) | a quick test — no setup at all |\n| **Personal access token** | everything the user can | until revoked or expired | a developer's own machine |\n| **Client credential** | **one project**, narrowed scopes | until revoked | CI, shared runners, contractors |\n\n### A. Platform JWT — zero setup\n\nAny token from your normal login works immediately:\n\n```bash\nCOGITX_TOKEN=$(curl -s -X POST \"$IDENTITY_URL/identity/login\" \\\n  -H 'content-type: application/json' \\\n  -d '{\"email\":\"...\",\"password\":\"...\"}' | jq -r .token)\n```\n\nGood for confirming the connection works. It stops working in two hours, so\ndon't put it in a config file you intend to keep.\n\n### B. Personal access token — the normal choice\n\nLong-lived, revocable, and scoped to you. Mint one with any valid session:\n\n```bash\ncurl -X POST \"$IDENTITY_URL/personal-access-tokens\" \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H 'content-type: application/json' \\\n  -d '{ \"name\": \"Claude Code — laptop\", \"expiresInDays\": 90 }'\n```\n\n```json\n{\n  \"id\": \"...\",\n  \"token\": \"cxp_… — shown once, store it now\",\n  \"tokenPrefix\": \"cxp_a1b2c3d4\",\n  \"expiresAt\": \"2026-12-02T…\",\n  \"isRevoked\": false\n}\n```\n\n`expiresInDays` is optional (max 365); omit it for a token that does not\nexpire. List yours with `GET $IDENTITY_URL/personal-access-tokens` — only the\nnon-secret prefix and `lastUsedAt` come back, so you can tell devices apart.\nRevoke with `DELETE $IDENTITY_URL/personal-access-tokens/:id`.\n\nOnly the SHA-256 digest is stored, so the token cannot be recovered from the\ndatabase — if you lose it, revoke and mint another.\n\n### C. Project-pinned client credential — least privilege\n\nBound to one project, cannot create projects, and can be narrowed with scopes.\nMint it as a user holding `project:update` on that project:\n\n```bash\ncurl -X POST \"$PROJECT_URL/projects/$PROJECT_ID/mcp-clients\" \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H 'content-type: application/json' \\\n  -d '{\n        \"clientName\": \"CI — nightly workflow sync\",\n        \"scopes\": [\"catalog:read\",\"workflow:read\",\"workflow:write\",\"execution:run\",\"execution:read\"]\n      }'\n```\n\nReturns `clientId` and a `clientSecret` shown once. Rotate with\n`POST /projects/:projectId/mcp-clients/:clientId/rotate-secret`, revoke with\n`DELETE /projects/:projectId/mcp-clients/:clientId`.\n\nIt still acts as the user who minted it — so RBAC applies on top — but can\nnever leave its project.\n\n### Scopes\n\nScopes only ever **narrow** what RBAC already allows; they never grant\nanything. A token with no scopes is unrestricted, meaning \"whatever this user\nmay do\".\n\n| Scope | Grants |\n|---|---|\n| `catalog:read` | node type catalog |\n| `project:read` / `project:write` | list, read, create, update projects |\n| `workflow:read` | list/get/validate/export workflows |\n| `workflow:write` | create/update/import workflows |\n| `workflow:delete` | soft-delete workflows |\n| `agent:read` / `agent:write` / `agent:delete` | agent CRUD |\n| `execution:run` / `execution:read` | run a workflow, read run status |\n\n---\n\n## 2. Install it\n\nPublished to npm, so there is nothing to build or check out:\n\n```bash\nnpx -y @cogitx-ai/mcp-server        # verifies it runs; exits without credentials\n```\n\nEvery client config below invokes it the same way — `npx -y @cogitx-ai/mcp-server`\n— which always fetches the current release. Pin a version if you would rather\ncontrol upgrades: `npx -y @cogitx-ai/mcp-server@0.1.0`.\n\n<details>\n<summary>Running from a checkout instead (contributors)</summary>\n\n```bash\ncd mcp\npnpm install\npnpm build          # -> dist/index.js\n```\n\nThen use `\"command\": \"node\"` with `\"args\": [\"/absolute/path/to/mcp/dist/index.js\"]`\nin place of the npx invocation.\n</details>\n\n### Environment variables\n\nSet **either** `COGITX_TOKEN` **or** the client credential pair. Every client\nbelow passes these the same way — only the file they live in differs.\n\n| Variable | Required | Notes |\n|---|---|---|\n| `COGITX_TOKEN` | one of | A `cxp_…` personal access token, or a platform JWT |\n| `COGITX_CLIENT_ID` + `COGITX_CLIENT_SECRET` | one of | The project-pinned pair |\n| `COGITX_BASE_URL` | no | Default `http://localhost:3000` |\n| `COGITX_PROJECT_ID` | no | Default project, so tools can omit `projectId` |\n| `COGITX_REQUEST_TIMEOUT_MS` | no | Default `60000` |\n\n`COGITX_PROJECT_ID` is worth setting when you mostly work in one project: tools\ntake an optional `projectId`, and without either the agent has to call\n`list_projects` first. A pinned client credential supplies it automatically.\n\n---\n## 3. Connect your coding agent\n\nThis is a **stdio** MCP server: a client launches it as a subprocess and talks\nover stdin/stdout. Almost every MCP client accepts the same JSON block —\n\n```json\n{\n  \"mcpServers\": {\n    \"cogitx\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@cogitx-ai/mcp-server\"],\n      \"env\": {\n        \"COGITX_BASE_URL\": \"https://api.your-platform.com\",\n        \"COGITX_TOKEN\": \"cxp_9f2c...\"\n      }\n    }\n  }\n}\n```\n\n— so for most clients the only question is *which file* it goes in.\n\n> `npx` needs Node on the client's PATH. GUI clients (Claude Desktop, Cursor)\n> do not always inherit a shell PATH — if the server shows as \"failed to start\",\n> use the absolute path to your Node binary (`which node`) as `command`, with\n> `args: [\"-y\", \"@cogitx-ai/mcp-server\"]` handled by an absolute `npx` path too.\n\n### Where the config lives\n\n| Client | File | Top-level key |\n|---|---|---|\n| **Claude Desktop** | macOS `~/Library/Application Support/Claude/claude_desktop_config.json`<br>Windows `%APPDATA%\\Claude\\claude_desktop_config.json` | `mcpServers` |\n| **Cursor** | `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per repo) | `mcpServers` |\n| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` | `mcpServers` |\n| **Cline** (VS Code) | `cline_mcp_settings.json` — open via *MCP Servers → Configure* | `mcpServers` |\n| **Gemini CLI** | `~/.gemini/settings.json` | `mcpServers` |\n| **LM Studio** | `mcp.json` — *Program → Install → Edit mcp.json* | `mcpServers` |\n| **JetBrains AI Assistant** | *Settings → Tools → AI Assistant → MCP* (accepts the same JSON) | `mcpServers` |\n| **Warp** | *Settings → AI → MCP Servers → Add* (accepts the same JSON) | `mcpServers` |\n\nThree clients differ from the shared shape — covered below.\n\n---\n\n### Claude Code\n\nUse the CLI rather than editing a file:\n\n```bash\nclaude mcp add cogitx \\\n  --env COGITX_BASE_URL=https://api.your-platform.com \\\n  --env COGITX_TOKEN=cxp_9f2c... \\\n  -- npx -y @cogitx-ai/mcp-server\n```\n\nScope controls who gets it:\n\n| Flag | Stored in | Use for |\n|---|---|---|\n| `-s local` (default) | your user settings, this project only | personal credential |\n| `-s user` | your user settings, all projects | personal credential |\n| `-s project` | `.mcp.json`, **committed to the repo** | shared team config — see the secrets note below |\n\nVerify and manage:\n\n```bash\nclaude mcp list          # health of every configured server\nclaude mcp get cogitx    # resolved command, args and env\nclaude mcp remove cogitx\n```\n\nInside a session, `/mcp` shows connection status and the tools each server exposes.\n\n---\n\n### VS Code (GitHub Copilot agent mode)\n\nVS Code uses `servers`, **not** `mcpServers`, and can prompt for the secret\ninstead of storing it in the file. Put this in `.vscode/mcp.json`:\n\n```json\n{\n  \"inputs\": [\n    {\n      \"type\": \"promptString\",\n      \"id\": \"cogitx-token\",\n      \"description\": \"CogitX personal access token\",\n      \"password\": true\n    }\n  ],\n  \"servers\": {\n    \"cogitx\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@cogitx-ai/mcp-server\"],\n      \"env\": {\n        \"COGITX_BASE_URL\": \"https://api.your-platform.com\",\n        \"COGITX_TOKEN\": \"${input:cogitx-token}\"\n      }\n    }\n  }\n}\n```\n\nVS Code prompts once and stores the value in its secret storage, so this file\nis safe to commit. Then open the Chat view, switch to **Agent** mode, and the\ntools appear under the tools picker.\n\n---\n\n### OpenAI Codex CLI\n\nTOML, in `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.cogitx]\ncommand = \"npx\"\nargs = [\"-y\", \"@cogitx-ai/mcp-server\"]\n\n[mcp_servers.cogitx.env]\nCOGITX_BASE_URL = \"https://api.your-platform.com\"\nCOGITX_TOKEN = \"cxp_9f2c...\"\n```\n\n---\n\n### Zed\n\nZed calls MCP servers **context servers**, configured in `settings.json`\n(`cmd-,`):\n\n```json\n{\n  \"context_servers\": {\n    \"cogitx\": {\n      \"source\": \"custom\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@cogitx-ai/mcp-server\"],\n      \"env\": {\n        \"COGITX_BASE_URL\": \"https://api.your-platform.com\",\n        \"COGITX_TOKEN\": \"cxp_9f2c...\"\n      }\n    }\n  }\n}\n```\n\nZed's context-server schema has changed across releases — if this is rejected,\ncheck Zed's current docs for the `context_servers` shape and keep the\n`command` / `args` / `env` values as above.\n\n---\n\n### Goose\n\n`~/.config/goose/config.yaml`:\n\n```yaml\nextensions:\n  cogitx:\n    enabled: true\n    type: stdio\n    cmd: npx\n    args:\n      - -y\n      - \"@cogitx-ai/mcp-server\"\n    envs:\n      COGITX_BASE_URL: https://api.your-platform.com\n      COGITX_TOKEN: \"cxp_9f2c...\"\n```\n\n---\n\n### Any other MCP client\n\nIf it accepts a stdio server, it needs three things:\n\n- **command** — `npx`\n- **args** — `[\"-y\", \"@cogitx-ai/mcp-server\"]`\n- **env** — `COGITX_TOKEN` (or the client pair) and `COGITX_BASE_URL`\n\nNothing else is required: no port, no URL, no OAuth callback.\n\n---\n\n### Remote / hosted clients\n\nClients that only accept a **remote URL** — ChatGPT connectors, Claude.ai\ncustom connectors, and similar — cannot use this server today. It speaks stdio\nonly. Supporting them means adding a Streamable HTTP transport in front of the\nsame tool definitions and terminating the client-credential headers there; the\n`/mcp/v1` backend surface already works over HTTPS, so only the transport layer\nin `src/index.ts` would change.\n\n---\n\n## 4. Keeping the secret out of your repo\n\nThe credential is bearer-style: whoever holds it has its full scope on that\nproject. Three options, best first:\n\n1. **Prompted secret storage** — VS Code `inputs` (above). The config file\n   carries no secret and can be committed.\n2. **Shell indirection** — point the config at a wrapper that reads from your\n   keychain, so the JSON holds no literal:\n\n   ```bash\n   #!/usr/bin/env bash\n   # ~/bin/cogitx-mcp-launch\n   export COGITX_TOKEN=\"$(security find-generic-password -s cogitx-mcp -w)\"\n   export COGITX_BASE_URL=\"https://api.your-platform.com\"\n   exec npx -y @cogitx-ai/mcp-server\n   ```\n\n   Then `\"command\": \"/Users/you/bin/cogitx-mcp-launch\"` with no `env` block.\n3. **Literal in a user-scoped file** — acceptable for `~/.cursor/mcp.json` or\n   `claude mcp add -s user`, never for a committed `.mcp.json` or\n   `.cursor/mcp.json`.\n\nIssue **one token per person per machine**, so revoking one never disrupts\nanyone else — `lastUsedAt` and the `cxp_` prefix in `GET /personal-access-tokens`\ntell you which is which. For anything unattended (CI, a shared runner, a\ncontractor) prefer a project-pinned client credential with narrow scopes over a\npersonal token: it cannot leave its project and cannot create new ones.\n\n---\n## 5. Verify the connection\n\nAsk the agent:\n\n> Use the cogitx tools to show my context, then list my projects.\n\nA healthy setup answers with your user id and auth mode, then your projects. If\nnot:\n\n| Symptom | Cause | Fix |\n|---|---|---|\n| Server not listed / \"failed to start\" | `npx`/Node not on the client's PATH | use absolute paths for `command` (`which npx`) |\n| `No credentials configured` | no `env` block, or a misspelled key | set `COGITX_TOKEN`, or both client vars |\n| `401 Invalid or expired authentication token` | JWT older than 2h | mint a `cxp_` personal access token instead |\n| `401 Invalid or expired access token` | token revoked or past `expiresAt` | check `GET /personal-access-tokens`, mint a new one |\n| `401 Credential is not authorized for MCP access` | you used a **workflow REST API export** client id | mint an MCP credential (section 1C) |\n| `403 ... missing required scope(s): workflow:write` | scopes too narrow | `PATCH /projects/:projectId/mcp-clients/:clientId` |\n| `403` naming a permission like `workflow:create` | **RBAC** — the user lacks it | grant the role in the platform; the token cannot bypass this |\n| `403 This credential is restricted to project …` | pinned credential used elsewhere | use a personal access token |\n| `403 A project-pinned credential cannot create a project` | by design | use a personal access token |\n| `No project specified` | no `projectId`, no `COGITX_PROJECT_ID`, unpinned credential | pass `projectId` or set the env var |\n| Requests time out | wrong `COGITX_BASE_URL`, or platform unreachable | curl `$COGITX_BASE_URL/mcp/v1/context` with the same auth header |\n\nA `403` naming a *permission* is real authorization, not a misconfiguration —\nthe fix is granting that user the role, not changing the token.\n\nThe server logs to **stderr**, which every client surfaces in its MCP logs\n(Claude Code: `claude mcp list`; VS Code and Cursor: the MCP output channel).\nstdout carries the protocol and never contains diagnostics.\n\n---\n\n## 6. Tools\n\n**Catalog** — `get_context`, `list_node_types`, `get_node_type`\n\n**Projects** — `list_projects`, `get_project`, `create_project`,\n`update_project`\n\n**Workflows** — `list_workflows`, `get_workflow`, `validate_workflow_draft`,\n`create_workflow`, `update_workflow`, `delete_workflow`, `validate_workflow`,\n`export_workflow_definition`, `import_workflow_definition`\n\n**Executions** — `execute_workflow`, `get_run_status`\n\n**Agents** — `list_agents`, `get_agent`, `create_agent`, `update_agent`,\n`delete_agent`\n\nEvery project-scoped tool takes an optional `projectId`, falling back to\n`COGITX_PROJECT_ID` and then to a pinned credential's project.\n\n---\n\n## 7. The authoring loop\n\nThe server's instructions steer the model through this sequence, and it is what\nmakes one-shot authoring of a complex graph reliable:\n\n```\nget_context             -> confirm who you are acting as, and any limits\nlist_projects           -> pick a project (skip if COGITX_PROJECT_ID is set)\nlist_node_types         -> learn valid `type` strings and configSchemas\nvalidate_workflow_draft -> check the graph, read errors, fix, repeat\ncreate_workflow         -> persist once it validates\nexecute_workflow        -> run it\nget_run_status          -> per-node results, timings, errors\n```\n\n`validate_workflow_draft` is the important one: it runs the platform's real\n`WorkflowValidationService` against a candidate graph **without saving**, so the\nagent iterates against genuine engine errors rather than guessing.\n\n### Graph shape\n\nA workflow is a directed acyclic graph.\n\n- Nodes connect via `next` arrays, or explicit `edges`.\n- For routing nodes (`conditional`, `parallel_router`, `loop`) the index within\n  `next` is the branch index; the matching edge uses `sourceHandle: \"branch-N\"`.\n- `join` nodes take slotted inputs via `targetHandle: \"input-N\"`.\n- **Cycles are rejected.** Use a `loop` node for iteration.\n- `nodeTypeId` is resolved server-side from `type` — the agent never handles\n  Mongo ObjectIds.\n- Omit `edges` and they are derived from `next`.\n\nMinimal example the agent can emit:\n\n```json\n{\n  \"name\": \"User Intent Routing\",\n  \"nodes\": [\n    { \"id\": \"in\",   \"type\": \"json_input\",  \"next\": [\"detect\"] },\n    { \"id\": \"detect\",\"type\": \"agent\",      \"next\": [\"route\"],\n      \"config\": { \"provider\": \"openai\", \"model\": \"gpt-4o-mini\",\n                  \"message\": \"{{ nodes.in.payload.user_text }}\" } },\n    { \"id\": \"route\",\"type\": \"conditional\", \"next\": [\"order\", \"faq\"],\n      \"config\": { \"conditions\": [\n        { \"name\": \"Order\",  \"expression\": \"nodes.detect.payload.intent_type === 'order_info'\", \"outputIndex\": 0 },\n        { \"name\": \"FAQ\",    \"expression\": \"nodes.detect.payload.intent_type === 'faq'\",        \"outputIndex\": 1 }\n      ], \"defaultOutput\": 1 } },\n    { \"id\": \"order\",\"type\": \"json_output\" },\n    { \"id\": \"faq\",  \"type\": \"json_output\" }\n  ]\n}\n```\n\n---\n\n## 8. Security notes\n\n- **RBAC is the authorization boundary.** Every credential resolves to a user,\n  and each MCP route carries the same `@ResourceAccess` check as its\n  human-facing equivalent. Nothing here can exceed what that user can do in the\n  UI, and scopes only narrow further.\n- Writes are attributed to that user, so version history and audit logs show a\n  real person, not an anonymous machine.\n- Personal access tokens are stored only as a SHA-256 digest, compared in\n  constant time, and carry a non-secret `cxp_` prefix so a leaked secret is\n  greppable and identifiable in listings.\n- A project-pinned credential is checked against the request path before RBAC\n  runs, and cannot create projects — the narrower limit is enforced first.\n- A workflow REST API export credential **cannot** be reused here: the guard\n  requires `metadata.source = \"mcp-client\"`. Without that check, a credential\n  minted only to *invoke* a workflow would gain authoring rights.\n- Client secrets are scrypt-hashed with a per-secret salt; rate limiting is per\n  client id.\n- Every authentication attempt is written to the security audit log as\n  `mcp_authenticate`, with the auth mode and the acting user.\n","readmeFilename":"README.md","_rev":"1-0c0469400f2eecc137433f1de57cc7f8"}