capsulemcp 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # capsulemcp
2
2
 
3
+ [![capsulemcp MCP server](https://glama.ai/mcp/servers/soil-dev/capsulemcp/badges/score.svg)](https://glama.ai/mcp/servers/soil-dev/capsulemcp)
4
+
3
5
  A [Model Context Protocol](https://modelcontextprotocol.io) server for [Capsule CRM](https://capsulecrm.com). Connect Claude (Desktop, Code, or web Projects via Custom Connector) to your CRM and let it answer natural-language questions across the full record graph: contacts, organisations, opportunities, projects, tasks, and timeline activity. Beyond the basics it covers structured filters with field/operator conditions, saved searches with sort, workflow tracks (templates and instances), file attachments (read + write), audit of deleted records, and batch fetches up to 10 records per call.
4
6
 
5
7
  - **81 tools** across the Capsule resource graph (49 in read-only mode) — full read coverage plus careful, confirm-gated writes
@@ -31,7 +33,7 @@ For most individual users the install is a single JSON snippet pasted into Claud
31
33
  "mcpServers": {
32
34
  "capsule": {
33
35
  "command": "npx",
34
- "args": ["-y", "github:soil-dev/capsulemcp#v1.0.0"],
36
+ "args": ["-y", "capsulemcp"],
35
37
  "env": {
36
38
  "CAPSULE_API_TOKEN": "<paste token here>",
37
39
  "CAPSULE_MCP_READONLY": "1"
@@ -43,7 +45,7 @@ For most individual users the install is a single JSON snippet pasted into Claud
43
45
 
44
46
  3. Restart Claude Desktop. The Capsule tools appear in the tool picker.
45
47
 
46
- That's it. The first launch takes ~30 seconds while npx clones and builds; subsequent launches are fast. See [INSTALL.md](INSTALL.md) for the Claude Code path, manual install, and troubleshooting.
48
+ That's it. The first launch fetches the package from npm (a few seconds); subsequent launches are instant from the npx cache. To pin a specific version, use `"capsulemcp@1.0.1"` in `args`. If you're tracking a fork or an unreleased branch, use the GitHub-ref form instead: `"github:soil-dev/capsulemcp#v1.0.1"` — same arguments, just installs from a git clone rather than the npm registry. See [INSTALL.md](INSTALL.md) for the Claude Code path, manual install, and troubleshooting.
47
49
 
48
50
  ## Tools
49
51
 
package/dist/http.js CHANGED
@@ -979,8 +979,8 @@ function validateWebsiteAddress(data, ctx) {
979
979
  return;
980
980
  }
981
981
  const parsed = new URL(data.address);
982
- const BLOCKED = /* @__PURE__ */ new Set(["javascript:", "data:", "vbscript:"]);
983
- if (BLOCKED.has(parsed.protocol)) {
982
+ const ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
983
+ if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) {
984
984
  ctx.addIssue({
985
985
  code: "custom",
986
986
  path: ["address"],
@@ -2395,7 +2395,7 @@ function createCapsuleMcpServer() {
2395
2395
  const readOnly = isReadOnly();
2396
2396
  const server = new McpServer({
2397
2397
  name: "capsulemcp",
2398
- version: "1.0.0",
2398
+ version: "1.0.1",
2399
2399
  description: "Read and (optionally) modify Capsule CRM data \u2014 parties, opportunities, projects, tasks, timeline entries, pipelines, tags.",
2400
2400
  websiteUrl: "https://github.com/soil-dev/capsulemcp",
2401
2401
  icons: ICONS
@@ -2431,14 +2431,14 @@ function createCapsuleMcpServer() {
2431
2431
  registerTool(
2432
2432
  server,
2433
2433
  "list_party_opportunities",
2434
- "List all opportunities linked to a given party.",
2434
+ "List opportunities linked to a given party. Returns the same record shape as get_opportunity, filtered to one party \u2014 use this to answer 'what deals do we have with X?' without enumerating all opportunities. Accepts optional embed (e.g. 'tags,fields') to include those in one round-trip.",
2435
2435
  listPartyOpportunitiesSchema,
2436
2436
  listPartyOpportunities
2437
2437
  );
2438
2438
  registerTool(
2439
2439
  server,
2440
2440
  "list_party_projects",
2441
- "List all projects (cases) linked to a given party.",
2441
+ "List projects (cases) linked to a given party. Returns the same record shape as get_project, filtered to one party \u2014 use this to answer 'what cases is X involved in?' without enumerating all projects. Accepts optional embed (e.g. 'tags,fields'). For the opportunity-side analogue, use list_party_opportunities.",
2442
2442
  listPartyProjectsSchema,
2443
2443
  listPartyProjects
2444
2444
  );
@@ -2566,7 +2566,7 @@ function createCapsuleMcpServer() {
2566
2566
  registerTool(
2567
2567
  server,
2568
2568
  "get_opportunity",
2569
- "Fetch a single opportunity by its numeric ID.",
2569
+ "Fetch a single opportunity by its numeric id. Returns the full record including value, milestone, owner, party, and any embedded tags/custom fields. Use embed='tags,fields' to include those in one round-trip. For batch fetches of up to 10 opportunities at once, use get_opportunities instead.",
2570
2570
  getOpportunitySchema,
2571
2571
  getOpportunity
2572
2572
  );
@@ -2594,7 +2594,7 @@ function createCapsuleMcpServer() {
2594
2594
  registerTool(
2595
2595
  server,
2596
2596
  "list_associated_projects",
2597
- "List projects (cases) associated with a given opportunity. The inverse direction (project \u2192 opportunity) is on each project's `opportunity` field directly.",
2597
+ "List projects (cases) associated with a given opportunity. Returns the same record shape as list_projects, filtered to one opportunity. The inverse direction (project \u2192 opportunity) is on each project's `opportunity` field directly, so this tool is only needed for opportunity \u2192 projects discovery \u2014 use list_party_projects for party \u2192 projects.",
2598
2598
  listAssociatedProjectsSchema,
2599
2599
  listAssociatedProjects
2600
2600
  );
@@ -2602,7 +2602,7 @@ function createCapsuleMcpServer() {
2602
2602
  registerTool(
2603
2603
  server,
2604
2604
  "create_opportunity",
2605
- "Create a new opportunity linked to a party and a pipeline milestone.",
2605
+ "Create a new opportunity linked to a party. Requires partyId and milestoneId (which pins the deal to a specific pipeline stage \u2014 pipeline is inferred from the milestone). Value is optional but if amount is set, currency must be set too (3-letter ISO 4217 code, e.g. 'USD'). Discover valid milestone ids via list_pipelines + list_milestones first. For multi-party deals, use add_additional_party after creation.",
2606
2606
  createOpportunitySchema,
2607
2607
  createOpportunity
2608
2608
  );
@@ -2660,7 +2660,7 @@ function createCapsuleMcpServer() {
2660
2660
  registerTool(
2661
2661
  server,
2662
2662
  "create_project",
2663
- "Create a new project (case) in Capsule CRM linked to a party.",
2663
+ "Create a new project (case) in Capsule CRM linked to a party. Requires partyId and name; description, status, owner, and starting board/stage are optional. To pin a project to a specific board+stage on creation, pass stageId (which uniquely identifies a stage within a board). Discover valid ids via list_boards + list_stages. Returns the created project including its assigned id.",
2664
2664
  createProjectSchema,
2665
2665
  createProject
2666
2666
  );
@@ -2724,7 +2724,7 @@ function createCapsuleMcpServer() {
2724
2724
  registerTool(
2725
2725
  server,
2726
2726
  "get_task",
2727
- "Fetch a single task by its numeric ID.",
2727
+ "Fetch a single task by its numeric id. Returns the task's description, due date, owner, completion state, and the entity it's attached to (party / opportunity / project, if any \u2014 standalone tasks not tied to a record are also valid). For batch fetches of up to 10 tasks at once, use get_tasks instead.",
2728
2728
  getTaskSchema,
2729
2729
  getTask
2730
2730
  );
@@ -2775,14 +2775,14 @@ function createCapsuleMcpServer() {
2775
2775
  registerTool(
2776
2776
  server,
2777
2777
  "list_opportunity_entries",
2778
- "List timeline entries (notes, captured emails, completed-task records) for an opportunity.",
2778
+ "List timeline entries (notes, captured emails, completed-task records) for an opportunity. Returns entries newest-first. Each entry has a type ('note', 'email', 'task'), free-text content, and timestamps. Use this to answer 'what's the latest on deal X?' For party or project timelines, use list_party_entries or list_project_entries respectively.",
2779
2779
  listOpportunityEntriesSchema,
2780
2780
  listOpportunityEntries
2781
2781
  );
2782
2782
  registerTool(
2783
2783
  server,
2784
2784
  "list_project_entries",
2785
- "List timeline entries (notes, captured emails, completed-task records) for a project (case).",
2785
+ "List timeline entries (notes, captured emails, completed-task records) for a project (case). Returns entries newest-first. Each entry has a type ('note', 'email', 'task'), free-text content, and timestamps. Use this to answer 'what's the latest on case X?' For party or opportunity timelines, use list_party_entries or list_opportunity_entries respectively.",
2786
2786
  listProjectEntriesSchema,
2787
2787
  listProjectEntries
2788
2788
  );
@@ -2910,21 +2910,21 @@ function createCapsuleMcpServer() {
2910
2910
  registerTool(
2911
2911
  server,
2912
2912
  "list_pipelines",
2913
- "List all sales pipelines defined in Capsule CRM.",
2913
+ "List all sales pipelines defined in Capsule CRM. Returns each pipeline's id, name, and milestones (deal stages, ordered by position). Use this to discover the pipelineId when creating an opportunity, then pick a milestone from the same pipeline via list_milestones. Pipelines are stable per Capsule account \u2014 list once and cache; they rarely change.",
2914
2914
  listPipelinesSchema,
2915
2915
  listPipelines
2916
2916
  );
2917
2917
  registerTool(
2918
2918
  server,
2919
2919
  "list_milestones",
2920
- "List all milestones (stages) within a specific opportunity pipeline.",
2920
+ "List milestones (deal stages) within a specific opportunity pipeline. Returns each milestone's id, name, probability, and position. Used when creating opportunities (pass milestoneId to create_opportunity) or moving them across stages (set milestoneId in update_opportunity). Discover the pipelineId first via list_pipelines. Milestones are pipeline-scoped \u2014 not interchangeable across pipelines.",
2921
2921
  listMilestonesSchema,
2922
2922
  listMilestones
2923
2923
  );
2924
2924
  registerTool(
2925
2925
  server,
2926
2926
  "list_boards",
2927
- "List all project (kase) boards defined in Capsule. A board is a grouping of stages that projects flow through \u2014 the project equivalent of an opportunity pipeline.",
2927
+ "List all project (case) boards defined in Capsule. A board is a grouping of stages that projects flow through \u2014 the project equivalent of an opportunity pipeline. Returns each board's id, name, and stages. Use this to discover boardId when creating a project, then pick a starting stage via list_stages. Like pipelines, boards are stable per account.",
2928
2928
  listBoardsSchema,
2929
2929
  listBoards
2930
2930
  );
@@ -2952,7 +2952,7 @@ function createCapsuleMcpServer() {
2952
2952
  registerTool(
2953
2953
  server,
2954
2954
  "list_activitytypes",
2955
- "List all configured activity types (e.g. Call, Meeting, Email). These are the categories used when logging timeline entries.",
2955
+ "List all configured activity types (e.g. Call, Meeting, Email). These are the categories used when logging timeline entries via add_note. Returns each type's id and name. The set is account-configured rather than a fixed enum, so call this to discover valid values before referencing an activityType in entry creation.",
2956
2956
  listActivityTypesSchema,
2957
2957
  listActivityTypes
2958
2958
  );
@@ -3015,7 +3015,7 @@ function createCapsuleMcpServer() {
3015
3015
  registerTool(
3016
3016
  server,
3017
3017
  "list_tags",
3018
- "List all tags available for a given entity type (parties, opportunities, or kases).",
3018
+ "List all tags available for a given entity type (parties, opportunities, or kases). Returns each tag's id, name, and any data-tag field schema. Tags are entity-specific \u2014 a party tag is not interchangeable with an opportunity tag. Use this to discover valid tag ids before calling add_tag, or to display the tag catalogue to the user when they ask 'what tags do we use?'",
3019
3019
  listTagsSchema,
3020
3020
  listTags
3021
3021
  );
@@ -3038,7 +3038,7 @@ function createCapsuleMcpServer() {
3038
3038
  registerTool(
3039
3039
  server,
3040
3040
  "list_users",
3041
- "List all users in the Capsule account.",
3041
+ "List all users in the Capsule account. Returns each user's id, username, optional first/last name, role, and party reference. Some users may have null first/last name fields (only username set) \u2014 fall back to username for display. Use this to discover user ids for owner-filtered queries against opportunities, projects, and tasks, or to map a user to their party record via user.party.id.",
3042
3042
  listUsersSchema,
3043
3043
  listUsers
3044
3044
  );
package/dist/index.js CHANGED
@@ -499,8 +499,8 @@ function validateWebsiteAddress(data, ctx) {
499
499
  return;
500
500
  }
501
501
  const parsed = new URL(data.address);
502
- const BLOCKED = /* @__PURE__ */ new Set(["javascript:", "data:", "vbscript:"]);
503
- if (BLOCKED.has(parsed.protocol)) {
502
+ const ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
503
+ if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) {
504
504
  ctx.addIssue({
505
505
  code: "custom",
506
506
  path: ["address"],
@@ -1915,7 +1915,7 @@ function createCapsuleMcpServer() {
1915
1915
  const readOnly = isReadOnly();
1916
1916
  const server2 = new McpServer({
1917
1917
  name: "capsulemcp",
1918
- version: "1.0.0",
1918
+ version: "1.0.1",
1919
1919
  description: "Read and (optionally) modify Capsule CRM data \u2014 parties, opportunities, projects, tasks, timeline entries, pipelines, tags.",
1920
1920
  websiteUrl: "https://github.com/soil-dev/capsulemcp",
1921
1921
  icons: ICONS
@@ -1951,14 +1951,14 @@ function createCapsuleMcpServer() {
1951
1951
  registerTool(
1952
1952
  server2,
1953
1953
  "list_party_opportunities",
1954
- "List all opportunities linked to a given party.",
1954
+ "List opportunities linked to a given party. Returns the same record shape as get_opportunity, filtered to one party \u2014 use this to answer 'what deals do we have with X?' without enumerating all opportunities. Accepts optional embed (e.g. 'tags,fields') to include those in one round-trip.",
1955
1955
  listPartyOpportunitiesSchema,
1956
1956
  listPartyOpportunities
1957
1957
  );
1958
1958
  registerTool(
1959
1959
  server2,
1960
1960
  "list_party_projects",
1961
- "List all projects (cases) linked to a given party.",
1961
+ "List projects (cases) linked to a given party. Returns the same record shape as get_project, filtered to one party \u2014 use this to answer 'what cases is X involved in?' without enumerating all projects. Accepts optional embed (e.g. 'tags,fields'). For the opportunity-side analogue, use list_party_opportunities.",
1962
1962
  listPartyProjectsSchema,
1963
1963
  listPartyProjects
1964
1964
  );
@@ -2086,7 +2086,7 @@ function createCapsuleMcpServer() {
2086
2086
  registerTool(
2087
2087
  server2,
2088
2088
  "get_opportunity",
2089
- "Fetch a single opportunity by its numeric ID.",
2089
+ "Fetch a single opportunity by its numeric id. Returns the full record including value, milestone, owner, party, and any embedded tags/custom fields. Use embed='tags,fields' to include those in one round-trip. For batch fetches of up to 10 opportunities at once, use get_opportunities instead.",
2090
2090
  getOpportunitySchema,
2091
2091
  getOpportunity
2092
2092
  );
@@ -2114,7 +2114,7 @@ function createCapsuleMcpServer() {
2114
2114
  registerTool(
2115
2115
  server2,
2116
2116
  "list_associated_projects",
2117
- "List projects (cases) associated with a given opportunity. The inverse direction (project \u2192 opportunity) is on each project's `opportunity` field directly.",
2117
+ "List projects (cases) associated with a given opportunity. Returns the same record shape as list_projects, filtered to one opportunity. The inverse direction (project \u2192 opportunity) is on each project's `opportunity` field directly, so this tool is only needed for opportunity \u2192 projects discovery \u2014 use list_party_projects for party \u2192 projects.",
2118
2118
  listAssociatedProjectsSchema,
2119
2119
  listAssociatedProjects
2120
2120
  );
@@ -2122,7 +2122,7 @@ function createCapsuleMcpServer() {
2122
2122
  registerTool(
2123
2123
  server2,
2124
2124
  "create_opportunity",
2125
- "Create a new opportunity linked to a party and a pipeline milestone.",
2125
+ "Create a new opportunity linked to a party. Requires partyId and milestoneId (which pins the deal to a specific pipeline stage \u2014 pipeline is inferred from the milestone). Value is optional but if amount is set, currency must be set too (3-letter ISO 4217 code, e.g. 'USD'). Discover valid milestone ids via list_pipelines + list_milestones first. For multi-party deals, use add_additional_party after creation.",
2126
2126
  createOpportunitySchema,
2127
2127
  createOpportunity
2128
2128
  );
@@ -2180,7 +2180,7 @@ function createCapsuleMcpServer() {
2180
2180
  registerTool(
2181
2181
  server2,
2182
2182
  "create_project",
2183
- "Create a new project (case) in Capsule CRM linked to a party.",
2183
+ "Create a new project (case) in Capsule CRM linked to a party. Requires partyId and name; description, status, owner, and starting board/stage are optional. To pin a project to a specific board+stage on creation, pass stageId (which uniquely identifies a stage within a board). Discover valid ids via list_boards + list_stages. Returns the created project including its assigned id.",
2184
2184
  createProjectSchema,
2185
2185
  createProject
2186
2186
  );
@@ -2244,7 +2244,7 @@ function createCapsuleMcpServer() {
2244
2244
  registerTool(
2245
2245
  server2,
2246
2246
  "get_task",
2247
- "Fetch a single task by its numeric ID.",
2247
+ "Fetch a single task by its numeric id. Returns the task's description, due date, owner, completion state, and the entity it's attached to (party / opportunity / project, if any \u2014 standalone tasks not tied to a record are also valid). For batch fetches of up to 10 tasks at once, use get_tasks instead.",
2248
2248
  getTaskSchema,
2249
2249
  getTask
2250
2250
  );
@@ -2295,14 +2295,14 @@ function createCapsuleMcpServer() {
2295
2295
  registerTool(
2296
2296
  server2,
2297
2297
  "list_opportunity_entries",
2298
- "List timeline entries (notes, captured emails, completed-task records) for an opportunity.",
2298
+ "List timeline entries (notes, captured emails, completed-task records) for an opportunity. Returns entries newest-first. Each entry has a type ('note', 'email', 'task'), free-text content, and timestamps. Use this to answer 'what's the latest on deal X?' For party or project timelines, use list_party_entries or list_project_entries respectively.",
2299
2299
  listOpportunityEntriesSchema,
2300
2300
  listOpportunityEntries
2301
2301
  );
2302
2302
  registerTool(
2303
2303
  server2,
2304
2304
  "list_project_entries",
2305
- "List timeline entries (notes, captured emails, completed-task records) for a project (case).",
2305
+ "List timeline entries (notes, captured emails, completed-task records) for a project (case). Returns entries newest-first. Each entry has a type ('note', 'email', 'task'), free-text content, and timestamps. Use this to answer 'what's the latest on case X?' For party or opportunity timelines, use list_party_entries or list_opportunity_entries respectively.",
2306
2306
  listProjectEntriesSchema,
2307
2307
  listProjectEntries
2308
2308
  );
@@ -2430,21 +2430,21 @@ function createCapsuleMcpServer() {
2430
2430
  registerTool(
2431
2431
  server2,
2432
2432
  "list_pipelines",
2433
- "List all sales pipelines defined in Capsule CRM.",
2433
+ "List all sales pipelines defined in Capsule CRM. Returns each pipeline's id, name, and milestones (deal stages, ordered by position). Use this to discover the pipelineId when creating an opportunity, then pick a milestone from the same pipeline via list_milestones. Pipelines are stable per Capsule account \u2014 list once and cache; they rarely change.",
2434
2434
  listPipelinesSchema,
2435
2435
  listPipelines
2436
2436
  );
2437
2437
  registerTool(
2438
2438
  server2,
2439
2439
  "list_milestones",
2440
- "List all milestones (stages) within a specific opportunity pipeline.",
2440
+ "List milestones (deal stages) within a specific opportunity pipeline. Returns each milestone's id, name, probability, and position. Used when creating opportunities (pass milestoneId to create_opportunity) or moving them across stages (set milestoneId in update_opportunity). Discover the pipelineId first via list_pipelines. Milestones are pipeline-scoped \u2014 not interchangeable across pipelines.",
2441
2441
  listMilestonesSchema,
2442
2442
  listMilestones
2443
2443
  );
2444
2444
  registerTool(
2445
2445
  server2,
2446
2446
  "list_boards",
2447
- "List all project (kase) boards defined in Capsule. A board is a grouping of stages that projects flow through \u2014 the project equivalent of an opportunity pipeline.",
2447
+ "List all project (case) boards defined in Capsule. A board is a grouping of stages that projects flow through \u2014 the project equivalent of an opportunity pipeline. Returns each board's id, name, and stages. Use this to discover boardId when creating a project, then pick a starting stage via list_stages. Like pipelines, boards are stable per account.",
2448
2448
  listBoardsSchema,
2449
2449
  listBoards
2450
2450
  );
@@ -2472,7 +2472,7 @@ function createCapsuleMcpServer() {
2472
2472
  registerTool(
2473
2473
  server2,
2474
2474
  "list_activitytypes",
2475
- "List all configured activity types (e.g. Call, Meeting, Email). These are the categories used when logging timeline entries.",
2475
+ "List all configured activity types (e.g. Call, Meeting, Email). These are the categories used when logging timeline entries via add_note. Returns each type's id and name. The set is account-configured rather than a fixed enum, so call this to discover valid values before referencing an activityType in entry creation.",
2476
2476
  listActivityTypesSchema,
2477
2477
  listActivityTypes
2478
2478
  );
@@ -2535,7 +2535,7 @@ function createCapsuleMcpServer() {
2535
2535
  registerTool(
2536
2536
  server2,
2537
2537
  "list_tags",
2538
- "List all tags available for a given entity type (parties, opportunities, or kases).",
2538
+ "List all tags available for a given entity type (parties, opportunities, or kases). Returns each tag's id, name, and any data-tag field schema. Tags are entity-specific \u2014 a party tag is not interchangeable with an opportunity tag. Use this to discover valid tag ids before calling add_tag, or to display the tag catalogue to the user when they ask 'what tags do we use?'",
2539
2539
  listTagsSchema,
2540
2540
  listTags
2541
2541
  );
@@ -2558,7 +2558,7 @@ function createCapsuleMcpServer() {
2558
2558
  registerTool(
2559
2559
  server2,
2560
2560
  "list_users",
2561
- "List all users in the Capsule account.",
2561
+ "List all users in the Capsule account. Returns each user's id, username, optional first/last name, role, and party reference. Some users may have null first/last name fields (only username set) \u2014 fall back to username for display. Use this to discover user ids for owner-filtered queries against opportunities, projects, and tasks, or to map a user to their party record via user.party.id.",
2562
2562
  listUsersSchema,
2563
2563
  listUsers
2564
2564
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capsulemcp",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Model Context Protocol server for Capsule CRM. Lets Claude (Desktop, Code, or web Projects via Custom Connector) read and write your CRM in plain English. Covers contacts, opportunities, projects, tasks, timeline activity, structured filters, saved filters with sort, workflow tracks, file attachments, audit, and batch fetches.",
5
5
  "keywords": [
6
6
  "mcp",