@critical-path/mcp 0.1.0

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 ADDED
@@ -0,0 +1,180 @@
1
+ # @critical-path/mcp
2
+
3
+ > **Model Context Protocol (MCP) and Client-Side WebMCP Integration for Critical Path**
4
+ > Connect AI coding agents, background workers, and in-browser copilots directly to your project management workflows.
5
+
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ---
9
+
10
+ ## 💡 Overview
11
+
12
+ `@critical-path/mcp` bridges the **Critical Path** headless project management framework with AI agents via two complementary protocols:
13
+
14
+ 1. **Standard Server MCP (`@critical-path/mcp/server`)**:
15
+ Standard [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server implementation using `@modelcontextprotocol/sdk`. Runs over **stdio** or **streamable HTTP/SSE**, allowing external AI assistants (such as Claude Desktop, Cursor, and Antigravity) to manage projects, tasks, sprints, deliverables, and comments.
16
+ 2. **Client-Side WebMCP (`@critical-path/mcp/web`)**:
17
+ In-browser tool registration following the **W3C Web Machine Learning Community Group WebMCP specification**. Registers structured tools directly on `document.modelContext` / `navigator.modelContext` with ambient project scoping, enabling in-browser AI assistants and page copilots to actuate project state without fragile DOM scraping.
18
+
19
+ ---
20
+
21
+ ## 📦 Installation
22
+
23
+ ```bash
24
+ pnpm add @critical-path/mcp
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 🚀 Standard Server MCP (Claude Desktop, Cursor, CLI)
30
+
31
+ ### Running via CLI
32
+
33
+ You can spin up an MCP server over stdio instantly against a local SQLite database, in-memory store, or a remote Critical Path REST API:
34
+
35
+ ```bash
36
+ # Against a local SQLite database
37
+ npx @critical-path/mcp --db ./path/to/critical-path.db
38
+
39
+ # Against a remote Next.js or SvelteKit route handler
40
+ npx @critical-path/mcp --api http://localhost:3000/api/critical-path
41
+
42
+ # Temporary in-memory store (for testing)
43
+ npx @critical-path/mcp
44
+ ```
45
+
46
+ ### Claude Desktop Configuration
47
+
48
+ Add the following to your `claude_desktop_config.json`:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "critical-path": {
54
+ "command": "npx",
55
+ "args": ["-y", "@critical-path/mcp", "--db", "/absolute/path/to/critical-path.db"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Programmatic Server Creation
62
+
63
+ ```typescript
64
+ import { createCriticalPathMcpServer, startStdioServer } from '@critical-path/mcp/server';
65
+ import { CriticalPathEngine, SQLiteStore } from '@critical-path/core';
66
+
67
+ const engine = new CriticalPathEngine({
68
+ store: new SQLiteStore({ filename: 'projects.db' })
69
+ });
70
+
71
+ const server = createCriticalPathMcpServer({
72
+ engine,
73
+ name: 'my-project-pm'
74
+ });
75
+
76
+ await startStdioServer(server);
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 🌐 Client-Side WebMCP (In-Browser Copilots)
82
+
83
+ WebMCP exposes client-side tools directly in the browser's JavaScript environment without scraping DOM elements.
84
+
85
+ ### React Integration (`useWebMCP`)
86
+
87
+ ```tsx
88
+ import { useWebMCP } from '@critical-path/react';
89
+
90
+ export function ProjectDashboard({ projectId }: { projectId: string }) {
91
+ // Automatically registers tools scoped to the active project
92
+ // and cleans up on unmount or project change via AbortController
93
+ const { registered, tools } = useWebMCP({
94
+ projectId,
95
+ tools: ['create_task', 'list_tasks', 'update_task', 'add_comment']
96
+ });
97
+
98
+ return (
99
+ <div>
100
+ <h1>Project View</h1>
101
+ {registered && <p>AI Copilot Active ({tools.length} tools available)</p>}
102
+ </div>
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### Svelte 5 Integration (`WebMcpState` / `createWebMcpState`)
108
+
109
+ ```svelte
110
+ <script lang="ts">
111
+ import { createCriticalPathClient, createWebMcpState } from '@critical-path/svelte';
112
+
113
+ const client = createCriticalPathClient({ baseUrl: '/api/critical-path' });
114
+ const mcp = createWebMcpState(client, { projectId: 'proj-123' });
115
+ </script>
116
+
117
+ <div>
118
+ {#if mcp.registered}
119
+ <span>🤖 In-browser AI assistant enabled for project {mcp.activeProjectId}</span>
120
+ {/if}
121
+ </div>
122
+ ```
123
+
124
+ ### Vanilla / Framework-Agnostic WebMCP
125
+
126
+ ```typescript
127
+ import { registerWebMcpTools } from '@critical-path/mcp/web';
128
+ import { CriticalPathClient } from '@critical-path/client';
129
+
130
+ const client = new CriticalPathClient({ baseUrl: '/api/critical-path' });
131
+
132
+ const handle = registerWebMcpTools({
133
+ client,
134
+ projectId: 'proj-main',
135
+ onToolExecuted: (name, input, result) => {
136
+ console.log(`[WebMCP] Executed ${name}:`, input, result);
137
+ }
138
+ });
139
+
140
+ // To clean up and unregister:
141
+ handle.unregister();
142
+ ```
143
+
144
+ ---
145
+
146
+ ## 🛠️ Supported Tools
147
+
148
+ | Tool Name | Description | Key Parameters |
149
+ | :--- | :--- | :--- |
150
+ | `list_projects` | List all projects in the workspace | `{}` |
151
+ | `get_project` | Get project details by ID | `{ id }` |
152
+ | `create_project` | Create a new project workspace | `{ name, description?, key? }` |
153
+ | `list_tasks` | List tasks with filters | `{ projectId?, status?, priority?, assigneeId? }` |
154
+ | `get_task` | Get single task details | `{ id }` |
155
+ | `create_task` | Create a new task (auto-scoped in WebMCP) | `{ projectId?, title, description?, priority?, status? }` |
156
+ | `update_task` | Update task status, priority, or fields | `{ id, title?, status?, priority?, assigneeId? }` |
157
+ | `delete_task` | Delete a task (requires confirmation) | `{ id }` |
158
+ | `list_deliverables` | List project milestone deliverables | `{ projectId? }` |
159
+ | `create_deliverable` | Create a milestone deliverable | `{ projectId?, title, dueDate? }` |
160
+ | `list_comments` | Retrieve task comments | `{ taskId }` |
161
+ | `add_comment` | Post a comment to a task | `{ taskId, content, authorId }` |
162
+
163
+ ---
164
+
165
+ ## 📚 Resources & Prompts (Standard MCP Server)
166
+
167
+ ### Resources
168
+ - `criticalpath://projects`: Live JSON stream of all projects.
169
+ - `criticalpath://tasks`: Live JSON stream of all tasks.
170
+ - `criticalpath://tasks/{id}`: Detailed JSON payload of a specific task.
171
+
172
+ ### Prompts
173
+ - `summarize_project`: Executive summary of project health, completion rates, and blockers.
174
+ - `triage_task`: AI-guided triage analyzing priority, estimation, and acceptance criteria.
175
+
176
+ ---
177
+
178
+ ## 📄 License
179
+
180
+ MIT © [Jack James](https://github.com/Pixerate)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ import { CriticalPathEngine, SQLiteStore, InMemoryStore } from '@critical-path/core';
3
+ import { CriticalPathClient } from '@critical-path/client';
4
+ import { createCriticalPathMcpServer, startStdioServer } from '../server/index.js';
5
+ function parseArgs(args) {
6
+ const options = {};
7
+ for (let i = 0; i < args.length; i++) {
8
+ const arg = args[i];
9
+ if (arg === '--help' || arg === '-h') {
10
+ options.help = true;
11
+ }
12
+ else if (arg === '--db' && args[i + 1]) {
13
+ options.db = args[++i];
14
+ }
15
+ else if (arg === '--api' && args[i + 1]) {
16
+ options.api = args[++i];
17
+ }
18
+ }
19
+ return options;
20
+ }
21
+ function showHelp() {
22
+ console.log(`
23
+ Critical Path MCP Server (Stdio)
24
+
25
+ Usage:
26
+ npx @critical-path/mcp [options]
27
+
28
+ Options:
29
+ --db <path> Path to SQLite database file (uses SQLiteStore)
30
+ --api <url> Base URL of remote Critical Path server (uses CriticalPathClient)
31
+ --help, -h Display this help message
32
+
33
+ Examples:
34
+ # Run against local SQLite database
35
+ npx @critical-path/mcp --db ./critical-path.db
36
+
37
+ # Run against remote Next.js or SvelteKit route handler
38
+ npx @critical-path/mcp --api http://localhost:3000/api/critical-path
39
+
40
+ # Run with in-memory store (for testing)
41
+ npx @critical-path/mcp
42
+ `);
43
+ }
44
+ async function main() {
45
+ const args = process.argv.slice(2);
46
+ const options = parseArgs(args);
47
+ if (options.help) {
48
+ showHelp();
49
+ process.exit(0);
50
+ }
51
+ let server;
52
+ if (options.api) {
53
+ const client = new CriticalPathClient({ baseUrl: options.api });
54
+ server = createCriticalPathMcpServer({ client, name: 'critical-path-api-mcp' });
55
+ console.error(`[Critical Path MCP] Connecting to remote API at ${options.api} over stdio...`);
56
+ }
57
+ else if (options.db) {
58
+ const store = new SQLiteStore({ filename: options.db });
59
+ const engine = new CriticalPathEngine({ store });
60
+ server = createCriticalPathMcpServer({ engine, name: 'critical-path-sqlite-mcp' });
61
+ console.error(`[Critical Path MCP] Loaded SQLite database from "${options.db}" over stdio...`);
62
+ }
63
+ else {
64
+ const store = new InMemoryStore();
65
+ const engine = new CriticalPathEngine({ store });
66
+ server = createCriticalPathMcpServer({ engine, name: 'critical-path-inmemory-mcp' });
67
+ console.error('[Critical Path MCP] Initialized in-memory store over stdio...');
68
+ }
69
+ await startStdioServer(server);
70
+ }
71
+ main().catch((err) => {
72
+ console.error('[Critical Path MCP] Fatal error:', err);
73
+ process.exit(1);
74
+ });
75
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './tools/definitions.js';
2
+ export * from './server/index.js';
3
+ export * from './web/index.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './tools/definitions.js';
2
+ export * from './server/index.js';
3
+ export * from './web/index.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { CriticalPathEngine, InMemoryStore } from '@critical-path/core';
3
+ import { ALL_TOOLS, TOOL_MAP, createCriticalPathMcpServer, registerWebMcpTools, ensureModelContextShim } from './index.js';
4
+ describe('@critical-path/mcp', () => {
5
+ let engine;
6
+ beforeEach(() => {
7
+ engine = new CriticalPathEngine({ store: new InMemoryStore() });
8
+ });
9
+ describe('Tool Definitions', () => {
10
+ it('registers all core project management tools', () => {
11
+ const toolNames = ALL_TOOLS.map((t) => t.name);
12
+ expect(toolNames).toContain('list_projects');
13
+ expect(toolNames).toContain('get_project');
14
+ expect(toolNames).toContain('create_project');
15
+ expect(toolNames).toContain('list_tasks');
16
+ expect(toolNames).toContain('get_task');
17
+ expect(toolNames).toContain('create_task');
18
+ expect(toolNames).toContain('update_task');
19
+ expect(toolNames).toContain('delete_task');
20
+ expect(toolNames).toContain('list_deliverables');
21
+ expect(toolNames).toContain('create_deliverable');
22
+ expect(toolNames).toContain('list_comments');
23
+ expect(toolNames).toContain('add_comment');
24
+ });
25
+ it('executes project and task workflows through tool definitions', async () => {
26
+ // 1. Create project
27
+ const createProjTool = TOOL_MAP.get('create_project');
28
+ const project = await createProjTool.execute({ name: 'Core Engine Dev', key: 'CED' }, engine);
29
+ expect(project.id).toBeDefined();
30
+ expect(project.name).toBe('Core Engine Dev');
31
+ // 2. List projects
32
+ const listProjTool = TOOL_MAP.get('list_projects');
33
+ const projects = await listProjTool.execute({}, engine);
34
+ expect(projects).toHaveLength(1);
35
+ expect(projects[0].id).toBe(project.id);
36
+ // 3. Create task
37
+ const createTaskTool = TOOL_MAP.get('create_task');
38
+ const task = await createTaskTool.execute({
39
+ projectId: project.id,
40
+ title: 'Implement WebMCP Spec',
41
+ priority: 'urgent',
42
+ tags: ['agent', 'mcp']
43
+ }, engine);
44
+ expect(task.id).toBeDefined();
45
+ expect(task.title).toBe('Implement WebMCP Spec');
46
+ expect(task.priority).toBe('urgent');
47
+ // 4. Update task
48
+ const updateTaskTool = TOOL_MAP.get('update_task');
49
+ const updated = await updateTaskTool.execute({
50
+ id: task.id,
51
+ status: 'in_progress',
52
+ estimatedHours: 5
53
+ }, engine);
54
+ expect(updated.status).toBe('in_progress');
55
+ expect(updated.estimatedHours).toBe(5);
56
+ // 5. Add comment
57
+ const addCommentTool = TOOL_MAP.get('add_comment');
58
+ const comment = await addCommentTool.execute({
59
+ taskId: task.id,
60
+ content: 'Started drafting the WebMCP handler',
61
+ authorId: 'agent-1'
62
+ }, engine);
63
+ expect(comment.content).toBe('Started drafting the WebMCP handler');
64
+ // 6. List tasks with filter
65
+ const listTasksTool = TOOL_MAP.get('list_tasks');
66
+ const filtered = await listTasksTool.execute({ projectId: project.id, status: 'in_progress' }, engine);
67
+ expect(filtered).toHaveLength(1);
68
+ // 7. Delete task
69
+ const deleteTaskTool = TOOL_MAP.get('delete_task');
70
+ const delRes = await deleteTaskTool.execute({ id: task.id }, engine);
71
+ expect(delRes.success).toBe(true);
72
+ const afterDelete = await listTasksTool.execute({ projectId: project.id }, engine);
73
+ expect(afterDelete).toHaveLength(0);
74
+ });
75
+ });
76
+ describe('Standard MCP Server Creation', () => {
77
+ it('creates an MCP Server instance with capabilities', () => {
78
+ const server = createCriticalPathMcpServer({
79
+ engine,
80
+ name: 'test-mcp-server',
81
+ version: '1.0.0'
82
+ });
83
+ expect(server).toBeDefined();
84
+ });
85
+ it('throws if neither engine nor client is provided', () => {
86
+ expect(() => createCriticalPathMcpServer({})).toThrow('Either engine or client must be provided');
87
+ });
88
+ });
89
+ describe('WebMCP Client Layer', () => {
90
+ let mockDoc;
91
+ let mockWin;
92
+ beforeEach(() => {
93
+ mockDoc = {};
94
+ mockWin = {};
95
+ });
96
+ it('creates a modelContext shim if document.modelContext is not natively present', () => {
97
+ const shim = ensureModelContextShim(mockDoc);
98
+ expect(shim).toBeDefined();
99
+ expect(mockDoc.modelContext).toBe(shim);
100
+ expect(typeof shim.registerTool).toBe('function');
101
+ });
102
+ it('registers tools into modelContext and allows execution', async () => {
103
+ const project = await engine.createProject({ name: 'WebMCP Test Project' });
104
+ // Mock client that delegates to engine
105
+ const mockClient = {
106
+ getProjects: () => engine.getProjects(),
107
+ getProject: (id) => engine.getProject(id),
108
+ createProject: (d) => engine.createProject(d),
109
+ getTasks: (pId) => engine.getTasks(pId),
110
+ getTask: (id) => engine.getTask(id),
111
+ createTask: (d) => engine.createTask(d),
112
+ updateTask: (id, u) => engine.updateTask(id, u),
113
+ deleteTask: (id) => engine.deleteTask(id)
114
+ };
115
+ const handle = registerWebMcpTools({
116
+ client: mockClient,
117
+ projectId: project.id,
118
+ document: mockDoc,
119
+ window: mockWin
120
+ });
121
+ expect(handle.getRegisteredTools().length).toBeGreaterThan(0);
122
+ expect(mockDoc.modelContext).toBeDefined();
123
+ const registered = await mockDoc.modelContext.getTools();
124
+ expect(registered.length).toBe(handle.getRegisteredTools().length);
125
+ // Execute create_task via WebMCP modelContext, inheriting ambient projectId
126
+ const createdTask = await mockDoc.modelContext.executeTool('create_task', {
127
+ title: 'Task Created via WebMCP'
128
+ });
129
+ expect(createdTask.id).toBeDefined();
130
+ expect(createdTask.projectId).toBe(project.id);
131
+ expect(createdTask.title).toBe('Task Created via WebMCP');
132
+ // Verify window fallback
133
+ expect(mockWin.__CRITICAL_PATH_WEBMCP__).toBeDefined();
134
+ expect(mockWin.__CRITICAL_PATH_WEBMCP__.projectId).toBe(project.id);
135
+ // Cleanup
136
+ handle.unregister();
137
+ const afterUnregister = await mockDoc.modelContext.getTools();
138
+ expect(afterUnregister).toHaveLength(0);
139
+ expect(mockWin.__CRITICAL_PATH_WEBMCP__).toBeUndefined();
140
+ });
141
+ it('supports AbortSignal unregistration lifecycle', async () => {
142
+ const controller = new AbortController();
143
+ const mockClient = {
144
+ getTasks: () => Promise.resolve([])
145
+ };
146
+ registerWebMcpTools({
147
+ client: mockClient,
148
+ signal: controller.signal,
149
+ document: mockDoc,
150
+ window: mockWin
151
+ });
152
+ let tools = await mockDoc.modelContext.getTools();
153
+ expect(tools.length).toBeGreaterThan(0);
154
+ controller.abort();
155
+ tools = await mockDoc.modelContext.getTools();
156
+ expect(tools).toHaveLength(0);
157
+ });
158
+ });
159
+ });
160
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import type { CriticalPathEngine } from '@critical-path/core';
3
+ import type { CriticalPathClient } from '@critical-path/client';
4
+ export interface CriticalPathMcpServerOptions {
5
+ engine?: CriticalPathEngine;
6
+ client?: CriticalPathClient;
7
+ name?: string;
8
+ version?: string;
9
+ tools?: string[];
10
+ }
11
+ export declare function createCriticalPathMcpServer(options: CriticalPathMcpServerOptions): Server;
12
+ export declare function startStdioServer(server: Server): Promise<void>;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,4BAA4B,GAAG,MAAM,CAiOzF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}