ninjapipe-mcp
v1.0.2
Published
MCP server for NinjaPipe - contacts, companies, deals, pipelines, forms, projects, tasks, invoices; workspace-scoped via API key
Maintainers
Readme
NinjaPipe MCP Server
MCP server that exposes NinjaPipe CRM data and actions to AI assistants (Cursor, Claude Desktop, Claude Code, etc.). Access is strictly limited to the workspace tied to your API key; no workspace ID is ever accepted from the client.
Changelog
1.0.2
- Fix: Remove invalid
required: trueon property subschemas in toolinputSchemadefinitions (JSON Schema requiresrequiredas a top-level array). Fixes MCP clients that reject the server on schema validation. - Add: Invoice tools (
list_invoices,get_invoice,create_invoice,update_invoice,get_invoice_settings_schema). - Add:
pipeline_slugresolution for pipeline tools (paste app URLs without UUID). - Fix: Drop
"type": "module"so the CommonJS entrypoint runs correctly undernpx.
Tools
- list_contacts – List contacts (optional:
search,limit,page). - get_contact – Get one contact by ID (required:
idUUID). - create_contact – Create a contact in the workspace (at least
first_nameorlast_name; optional:email,phone,status,owner_id,company_id,fields). Requires API key with write permission. - update_contact – Update a contact by ID (required:
id; optional:first_name,last_name,email,phone,status,owner_id,company_id,fields). Only provided fields are updated. Requires API key with write permission. - list_companies – List companies (optional:
page,limit,search,status,owner_id). 1:1 with Companies.js. - get_company – Get one company by ID (required:
id). 1:1 with CompanyDetailsPage. - create_company – Create a company (required:
name; optional:industry,website,phone,email,status,owner_id,fields). 1:1 with Companies / CompanyDetailsPage. Requires write permission. - update_company – Update a company by ID (required:
id; optional:name,industry,website,phone,email,status,owner_id,fields). 1:1 with CompanyDetailsPage. Requires write permission. - list_deals – List deals (optional:
page,limit,search,status,owner_id,sort_by,sort_order). 1:1 with Deals.js. - get_deal – Get one deal by ID (required:
id). 1:1 with Deals.js. - create_deal – Create a deal (required:
name; optional:value,status,owner_id,contact_id,company_id,fields). 1:1 with Deals.js. Requires write permission. - update_deal – Update a deal by ID (required:
id; optional:name,value,status,owner_id,contact_id,company_id,fields). 1:1 with Deals.js. Requires write permission. - list_projects – List task projects (optional:
page,limit,search,status,priority,sort_by,sort_order). 1:1 with Tasks.js. - get_project – Get one task project by ID (required:
id). 1:1 with Tasks.js / ProjectTasks.js. - create_project – Create a task project (required:
name; optional:description,status,priority,due_date,team,tags). 1:1 with Tasks.js. Requires write permission. - update_project – Update a task project (required:
id; optional:name,description,status,priority,due_date,team,tags). 1:1 with Tasks.js / ProjectTasks.js. Requires write permission. - list_tasks – List tasks in a project (required:
project_id; optional:status,priority,parent_id,sort_by,sort_order). 1:1 with ProjectTasks.js. - get_task – Get one task by project_id and task_id (required:
project_id,task_id). 1:1 with ProjectTasks.js. - create_task – Create a task in a project (required:
project_id,title; optional:description,status,priority,due_date,estimated_hours,actual_hours,tags,parent_id,order_index,settings_json). 1:1 with ProjectTasks.js / CreateTaskModal. Requires write permission. - update_task – Update a task (required:
project_id,task_id; optional:title,description,status,priority,due_date,estimated_hours,actual_hours,tags,parent_id,order_index,settings_json). 1:1 with ProjectTasks.js. Requires write permission. - list_forms – List forms (optional:
page,limit,search,status,sort_by,sort_order). 1:1 with Forms.js. - get_form – Get one form by ID (required:
id). 1:1 with Forms.js / FormDesigner.js. - create_form – Create a form (required:
name; optional:description,slug,status,fields_json,settings_json). Slug auto-generated from name if omitted. 1:1 with Forms.js / CreateFormModal. Requires write permission. - update_form – Update a form (required:
id; optional:name,description,slug,status,fields_json,settings_json). 1:1 with Forms.js / FormDesigner.js. Requires write permission. - list_pipelines – List pipelines (optional:
page,limit,type[contacts|deals|general],archived). - get_pipeline – Get one pipeline by ID (required:
id). - create_pipeline – Create a pipeline (required:
name,pipeline_type[contacts|deals|general],stagesarray of{ id, name, color }; optional:description). Requires API key with write permission. - update_pipeline – Update a pipeline by ID (required:
id; optional:name,description,stages,settings_json). Requires API key with write permission. - list_pipeline_items – List pipeline items (cards) in a pipeline (required:
pipeline_id; optional:stage_id). 1:1 with ViewPipeline. - get_pipeline_item – Get one pipeline item by pipeline ID and item ID (required:
pipeline_id,item_id). 1:1 with ViewPipeline. - create_pipeline_item – Add a pipeline item (card) to a pipeline (required:
pipeline_id,title,stage_id; optional: subtitle, description, item_type, reference_id, priority, value, assigned_to, due_date, tags, avatar, company, phone, email, order_index, checklist, custom_fields, comments, attachments, metadata). 1:1 with AddPipelineItemModal / ViewPipeline. Requires write permission. - update_pipeline_item – Update a pipeline item (required:
pipeline_id,item_id; optional: title, subtitle, description, stage_id, item_type, reference_id, priority, value, assigned_to, due_date, tags, avatar, company, phone, email, order_index, last_activity, metadata, checklist, custom_fields, comments, attachments). 1:1 with ViewPipeline card save. Requires write permission.
Prerequisites
- Node.js 18+
- A NinjaPipe API key (create one in your NinjaPipe workspace: Settings → API keys). The key is bound to a single workspace. Use read for list/get only; use write to also create contacts.
Environment
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| NINJAPIPE_API_KEY | Yes | — | Your NinjaPipe API key (e.g. np_...). |
| NINJAPIPE_API_URL | No | https://ninjapipe.app | NinjaPipe API base URL (no trailing slash). Use http://localhost:3001 only for local development. |
Use in Cursor
Get your NinjaPipe API key
In NinjaPipe: open your workspace → Settings (or Account) → API keys → create a key (read and/or write). Copy the key (starts withnp_).Add the MCP server in Cursor
- Open Cursor Settings → MCP (or Features → MCP).
- Add a new MCP server.
- Using the npm package (recommended):
{ "mcpServers": { "ninjapipe": { "command": "npx", "args": ["-y", "ninjapipe-mcp"], "env": { "NINJAPIPE_API_KEY": "np_YOUR_KEY_HERE", "NINJAPIPE_API_URL": "https://ninjapipe.app" } } } }Replace
np_YOUR_KEY_HEREwith your real key. You can omitNINJAPIPE_API_URLto use the default production API (https://ninjapipe.app).Local development: To point at your own API (e.g.
http://localhost:3001), setNINJAPIPE_API_URLto that base URL.Restart Cursor (or reload the window) so it picks up the new MCP server.
Use it in chat
In a Cursor chat, ask e.g.: “List my NinjaPipe contacts” or “Get NinjaPipe contact with id …”. The model will calllist_contactsorget_contact; the server will call the NinjaPipe API with your key and return only that workspace’s data.
Security
- Access is limited to the workspace tied to your API key. The server never sends or accepts a workspace ID; the key alone determines the workspace.
- Do not share your API key. Store it only in your local MCP config (env) and never commit it.
No dependencies
This server uses only Node.js built-ins (readline, fetch). No npm install is required to run it.
Troubleshooting
"No server info found" / "Server not yet created"
Cursor may use Content-Length (LSP-style) framing; the server now auto-detects it and responds in the same format. Ensure:- Path is absolute in your MCP config (e.g.
/Users/you/.../scripts/ninjapipe-mcp/index.js). - Env is set in the MCP config:
NINJAPIPE_API_KEYand optionallyNINJAPIPE_API_URL. - Node 18+ is on your PATH when Cursor runs (needed for
fetch).
To debug, set
NINJAPIPE_MCP_DEBUG=1in the server env and check Cursor’s MCP log (or run the server manually and pipe a message to see stderr).- Path is absolute in your MCP config (e.g.
Manual test
From a terminal (defaults to production API; setNINJAPIPE_API_URLtohttp://localhost:3001for local dev):npx -y ninjapipe-mcp # or with env: export NINJAPIPE_API_KEY=np_your_key export NINJAPIPE_API_URL=https://ninjapipe.app export NINJAPIPE_MCP_DEBUG=1 echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | npx -y ninjapipe-mcpYou should see a JSON-RPC response with
serverInfoandcapabilitieson stdout.
