npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cogitx-ai/mcp-server

v0.1.0

Published

MCP server for the CogitX platform — build, inspect and run workflows and agents from any MCP-capable coding agent.

Readme

CogitX Platform MCP Server

An MCP server that lets any MCP-capable coding agent — Claude Code, Cursor, Windsurf, Zed, a custom client — create projects and build, inspect, run and delete CogitX workflows and agents.

It speaks stdio to the coding agent and HTTPS to the platform's /mcp/v1 surface.

Every call acts as a real platform user. The credential you configure resolves to a user, and that user's RBAC decides what the agent can reach — the same @ResourceAccess checks the web app goes through. A credential carries no permissions of its own, so an agent can never do something you couldn't do yourself in the UI.


1. Choose a credential

These are two different services. Personal access tokens and login live on identity ($IDENTITY_URL); MCP client credentials and the /mcp/v1 surface live on project ($PROJECT_URL). COGITX_BASE_URL points at the project service.

Three work. Pick by how long it needs to live and how much it should reach.

| | Reaches | Lives | Use for | |---|---|---|---| | Platform JWT | everything the user can | JWT_EXPIRATION (2h) | a quick test — no setup at all | | Personal access token | everything the user can | until revoked or expired | a developer's own machine | | Client credential | one project, narrowed scopes | until revoked | CI, shared runners, contractors |

A. Platform JWT — zero setup

Any token from your normal login works immediately:

COGITX_TOKEN=$(curl -s -X POST "$IDENTITY_URL/identity/login" \
  -H 'content-type: application/json' \
  -d '{"email":"...","password":"..."}' | jq -r .token)

Good for confirming the connection works. It stops working in two hours, so don't put it in a config file you intend to keep.

B. Personal access token — the normal choice

Long-lived, revocable, and scoped to you. Mint one with any valid session:

curl -X POST "$IDENTITY_URL/personal-access-tokens" \
  -H "Authorization: Bearer $JWT" \
  -H 'content-type: application/json' \
  -d '{ "name": "Claude Code — laptop", "expiresInDays": 90 }'
{
  "id": "...",
  "token": "cxp_… — shown once, store it now",
  "tokenPrefix": "cxp_a1b2c3d4",
  "expiresAt": "2026-12-02T…",
  "isRevoked": false
}

expiresInDays is optional (max 365); omit it for a token that does not expire. List yours with GET $IDENTITY_URL/personal-access-tokens — only the non-secret prefix and lastUsedAt come back, so you can tell devices apart. Revoke with DELETE $IDENTITY_URL/personal-access-tokens/:id.

Only the SHA-256 digest is stored, so the token cannot be recovered from the database — if you lose it, revoke and mint another.

C. Project-pinned client credential — least privilege

Bound to one project, cannot create projects, and can be narrowed with scopes. Mint it as a user holding project:update on that project:

curl -X POST "$PROJECT_URL/projects/$PROJECT_ID/mcp-clients" \
  -H "Authorization: Bearer $JWT" \
  -H 'content-type: application/json' \
  -d '{
        "clientName": "CI — nightly workflow sync",
        "scopes": ["catalog:read","workflow:read","workflow:write","execution:run","execution:read"]
      }'

Returns clientId and a clientSecret shown once. Rotate with POST /projects/:projectId/mcp-clients/:clientId/rotate-secret, revoke with DELETE /projects/:projectId/mcp-clients/:clientId.

It still acts as the user who minted it — so RBAC applies on top — but can never leave its project.

Scopes

Scopes only ever narrow what RBAC already allows; they never grant anything. A token with no scopes is unrestricted, meaning "whatever this user may do".

| Scope | Grants | |---|---| | catalog:read | node type catalog | | project:read / project:write | list, read, create, update projects | | workflow:read | list/get/validate/export workflows | | workflow:write | create/update/import workflows | | workflow:delete | soft-delete workflows | | agent:read / agent:write / agent:delete | agent CRUD | | execution:run / execution:read | run a workflow, read run status |


2. Install it

Published to npm, so there is nothing to build or check out:

npx -y @cogitx-ai/mcp-server        # verifies it runs; exits without credentials

Every client config below invokes it the same way — npx -y @cogitx-ai/mcp-server — which always fetches the current release. Pin a version if you would rather control upgrades: npx -y @cogitx-ai/[email protected].

cd mcp
pnpm install
pnpm build          # -> dist/index.js

Then use "command": "node" with "args": ["/absolute/path/to/mcp/dist/index.js"] in place of the npx invocation.

Environment variables

Set either COGITX_TOKEN or the client credential pair. Every client below passes these the same way — only the file they live in differs.

| Variable | Required | Notes | |---|---|---| | COGITX_TOKEN | one of | A cxp_… personal access token, or a platform JWT | | COGITX_CLIENT_ID + COGITX_CLIENT_SECRET | one of | The project-pinned pair | | COGITX_BASE_URL | no | Default http://localhost:3000 | | COGITX_PROJECT_ID | no | Default project, so tools can omit projectId | | COGITX_REQUEST_TIMEOUT_MS | no | Default 60000 |

COGITX_PROJECT_ID is worth setting when you mostly work in one project: tools take an optional projectId, and without either the agent has to call list_projects first. A pinned client credential supplies it automatically.


3. Connect your coding agent

This is a stdio MCP server: a client launches it as a subprocess and talks over stdin/stdout. Almost every MCP client accepts the same JSON block —

{
  "mcpServers": {
    "cogitx": {
      "command": "npx",
      "args": ["-y", "@cogitx-ai/mcp-server"],
      "env": {
        "COGITX_BASE_URL": "https://api.your-platform.com",
        "COGITX_TOKEN": "cxp_9f2c..."
      }
    }
  }
}

— so for most clients the only question is which file it goes in.

npx needs Node on the client's PATH. GUI clients (Claude Desktop, Cursor) do not always inherit a shell PATH — if the server shows as "failed to start", use the absolute path to your Node binary (which node) as command, with args: ["-y", "@cogitx-ai/mcp-server"] handled by an absolute npx path too.

Where the config lives

| Client | File | Top-level key | |---|---|---| | Claude Desktop | macOS ~/Library/Application Support/Claude/claude_desktop_config.jsonWindows %APPDATA%\Claude\claude_desktop_config.json | mcpServers | | Cursor | ~/.cursor/mcp.json (global) or .cursor/mcp.json (per repo) | mcpServers | | Windsurf | ~/.codeium/windsurf/mcp_config.json | mcpServers | | Cline (VS Code) | cline_mcp_settings.json — open via MCP Servers → Configure | mcpServers | | Gemini CLI | ~/.gemini/settings.json | mcpServers | | LM Studio | mcp.json — Program → Install → Edit mcp.json | mcpServers | | JetBrains AI Assistant | Settings → Tools → AI Assistant → MCP (accepts the same JSON) | mcpServers | | Warp | Settings → AI → MCP Servers → Add (accepts the same JSON) | mcpServers |

Three clients differ from the shared shape — covered below.


Claude Code

Use the CLI rather than editing a file:

claude mcp add cogitx \
  --env COGITX_BASE_URL=https://api.your-platform.com \
  --env COGITX_TOKEN=cxp_9f2c... \
  -- npx -y @cogitx-ai/mcp-server

Scope controls who gets it:

| Flag | Stored in | Use for | |---|---|---| | -s local (default) | your user settings, this project only | personal credential | | -s user | your user settings, all projects | personal credential | | -s project | .mcp.json, committed to the repo | shared team config — see the secrets note below |

Verify and manage:

claude mcp list          # health of every configured server
claude mcp get cogitx    # resolved command, args and env
claude mcp remove cogitx

Inside a session, /mcp shows connection status and the tools each server exposes.


VS Code (GitHub Copilot agent mode)

VS Code uses servers, not mcpServers, and can prompt for the secret instead of storing it in the file. Put this in .vscode/mcp.json:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "cogitx-token",
      "description": "CogitX personal access token",
      "password": true
    }
  ],
  "servers": {
    "cogitx": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cogitx-ai/mcp-server"],
      "env": {
        "COGITX_BASE_URL": "https://api.your-platform.com",
        "COGITX_TOKEN": "${input:cogitx-token}"
      }
    }
  }
}

VS Code prompts once and stores the value in its secret storage, so this file is safe to commit. Then open the Chat view, switch to Agent mode, and the tools appear under the tools picker.


OpenAI Codex CLI

TOML, in ~/.codex/config.toml:

[mcp_servers.cogitx]
command = "npx"
args = ["-y", "@cogitx-ai/mcp-server"]

[mcp_servers.cogitx.env]
COGITX_BASE_URL = "https://api.your-platform.com"
COGITX_TOKEN = "cxp_9f2c..."

Zed

Zed calls MCP servers context servers, configured in settings.json (cmd-,):

{
  "context_servers": {
    "cogitx": {
      "source": "custom",
      "command": "npx",
      "args": ["-y", "@cogitx-ai/mcp-server"],
      "env": {
        "COGITX_BASE_URL": "https://api.your-platform.com",
        "COGITX_TOKEN": "cxp_9f2c..."
      }
    }
  }
}

Zed's context-server schema has changed across releases — if this is rejected, check Zed's current docs for the context_servers shape and keep the command / args / env values as above.


Goose

~/.config/goose/config.yaml:

extensions:
  cogitx:
    enabled: true
    type: stdio
    cmd: npx
    args:
      - -y
      - "@cogitx-ai/mcp-server"
    envs:
      COGITX_BASE_URL: https://api.your-platform.com
      COGITX_TOKEN: "cxp_9f2c..."

Any other MCP client

If it accepts a stdio server, it needs three things:

  • command — npx
  • args — ["-y", "@cogitx-ai/mcp-server"]
  • env — COGITX_TOKEN (or the client pair) and COGITX_BASE_URL

Nothing else is required: no port, no URL, no OAuth callback.


Remote / hosted clients

Clients that only accept a remote URL — ChatGPT connectors, Claude.ai custom connectors, and similar — cannot use this server today. It speaks stdio only. Supporting them means adding a Streamable HTTP transport in front of the same tool definitions and terminating the client-credential headers there; the /mcp/v1 backend surface already works over HTTPS, so only the transport layer in src/index.ts would change.


4. Keeping the secret out of your repo

The credential is bearer-style: whoever holds it has its full scope on that project. Three options, best first:

  1. Prompted secret storage — VS Code inputs (above). The config file carries no secret and can be committed.

  2. Shell indirection — point the config at a wrapper that reads from your keychain, so the JSON holds no literal:

    #!/usr/bin/env bash
    # ~/bin/cogitx-mcp-launch
    export COGITX_TOKEN="$(security find-generic-password -s cogitx-mcp -w)"
    export COGITX_BASE_URL="https://api.your-platform.com"
    exec npx -y @cogitx-ai/mcp-server

    Then "command": "/Users/you/bin/cogitx-mcp-launch" with no env block.

  3. Literal in a user-scoped file — acceptable for ~/.cursor/mcp.json or claude mcp add -s user, never for a committed .mcp.json or .cursor/mcp.json.

Issue one token per person per machine, so revoking one never disrupts anyone else — lastUsedAt and the cxp_ prefix in GET /personal-access-tokens tell you which is which. For anything unattended (CI, a shared runner, a contractor) prefer a project-pinned client credential with narrow scopes over a personal token: it cannot leave its project and cannot create new ones.


5. Verify the connection

Ask the agent:

Use the cogitx tools to show my context, then list my projects.

A healthy setup answers with your user id and auth mode, then your projects. If not:

| Symptom | Cause | Fix | |---|---|---| | Server not listed / "failed to start" | npx/Node not on the client's PATH | use absolute paths for command (which npx) | | No credentials configured | no env block, or a misspelled key | set COGITX_TOKEN, or both client vars | | 401 Invalid or expired authentication token | JWT older than 2h | mint a cxp_ personal access token instead | | 401 Invalid or expired access token | token revoked or past expiresAt | check GET /personal-access-tokens, mint a new one | | 401 Credential is not authorized for MCP access | you used a workflow REST API export client id | mint an MCP credential (section 1C) | | 403 ... missing required scope(s): workflow:write | scopes too narrow | PATCH /projects/:projectId/mcp-clients/:clientId | | 403 naming a permission like workflow:create | RBAC — the user lacks it | grant the role in the platform; the token cannot bypass this | | 403 This credential is restricted to project … | pinned credential used elsewhere | use a personal access token | | 403 A project-pinned credential cannot create a project | by design | use a personal access token | | No project specified | no projectId, no COGITX_PROJECT_ID, unpinned credential | pass projectId or set the env var | | Requests time out | wrong COGITX_BASE_URL, or platform unreachable | curl $COGITX_BASE_URL/mcp/v1/context with the same auth header |

A 403 naming a permission is real authorization, not a misconfiguration — the fix is granting that user the role, not changing the token.

The server logs to stderr, which every client surfaces in its MCP logs (Claude Code: claude mcp list; VS Code and Cursor: the MCP output channel). stdout carries the protocol and never contains diagnostics.


6. Tools

Catalog — get_context, list_node_types, get_node_type

Projects — list_projects, get_project, create_project, update_project

Workflows — list_workflows, get_workflow, validate_workflow_draft, create_workflow, update_workflow, delete_workflow, validate_workflow, export_workflow_definition, import_workflow_definition

Executions — execute_workflow, get_run_status

Agents — list_agents, get_agent, create_agent, update_agent, delete_agent

Every project-scoped tool takes an optional projectId, falling back to COGITX_PROJECT_ID and then to a pinned credential's project.


7. The authoring loop

The server's instructions steer the model through this sequence, and it is what makes one-shot authoring of a complex graph reliable:

get_context             -> confirm who you are acting as, and any limits
list_projects           -> pick a project (skip if COGITX_PROJECT_ID is set)
list_node_types         -> learn valid `type` strings and configSchemas
validate_workflow_draft -> check the graph, read errors, fix, repeat
create_workflow         -> persist once it validates
execute_workflow        -> run it
get_run_status          -> per-node results, timings, errors

validate_workflow_draft is the important one: it runs the platform's real WorkflowValidationService against a candidate graph without saving, so the agent iterates against genuine engine errors rather than guessing.

Graph shape

A workflow is a directed acyclic graph.

  • Nodes connect via next arrays, or explicit edges.
  • For routing nodes (conditional, parallel_router, loop) the index within next is the branch index; the matching edge uses sourceHandle: "branch-N".
  • join nodes take slotted inputs via targetHandle: "input-N".
  • Cycles are rejected. Use a loop node for iteration.
  • nodeTypeId is resolved server-side from type — the agent never handles Mongo ObjectIds.
  • Omit edges and they are derived from next.

Minimal example the agent can emit:

{
  "name": "User Intent Routing",
  "nodes": [
    { "id": "in",   "type": "json_input",  "next": ["detect"] },
    { "id": "detect","type": "agent",      "next": ["route"],
      "config": { "provider": "openai", "model": "gpt-4o-mini",
                  "message": "{{ nodes.in.payload.user_text }}" } },
    { "id": "route","type": "conditional", "next": ["order", "faq"],
      "config": { "conditions": [
        { "name": "Order",  "expression": "nodes.detect.payload.intent_type === 'order_info'", "outputIndex": 0 },
        { "name": "FAQ",    "expression": "nodes.detect.payload.intent_type === 'faq'",        "outputIndex": 1 }
      ], "defaultOutput": 1 } },
    { "id": "order","type": "json_output" },
    { "id": "faq",  "type": "json_output" }
  ]
}

8. Security notes

  • RBAC is the authorization boundary. Every credential resolves to a user, and each MCP route carries the same @ResourceAccess check as its human-facing equivalent. Nothing here can exceed what that user can do in the UI, and scopes only narrow further.
  • Writes are attributed to that user, so version history and audit logs show a real person, not an anonymous machine.
  • Personal access tokens are stored only as a SHA-256 digest, compared in constant time, and carry a non-secret cxp_ prefix so a leaked secret is greppable and identifiable in listings.
  • A project-pinned credential is checked against the request path before RBAC runs, and cannot create projects — the narrower limit is enforced first.
  • A workflow REST API export credential cannot be reused here: the guard requires metadata.source = "mcp-client". Without that check, a credential minted only to invoke a workflow would gain authoring rights.
  • Client secrets are scrypt-hashed with a per-secret salt; rate limiting is per client id.
  • Every authentication attempt is written to the security audit log as mcp_authenticate, with the auth mode and the acting user.