@karthikrajkumar.kannan/get-things-done 1.0.0 → 1.0.2
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/lib/installer-core.cjs +6 -0
- package/lib/installers/cursor.cjs +33 -19
- package/mcp/README.md +128 -0
- package/mcp/gtd-mcp-server.cjs +507 -0
- package/package.json +10 -5
package/lib/installer-core.cjs
CHANGED
|
@@ -25,6 +25,10 @@ const INSTALL_DIRS = [
|
|
|
25
25
|
'agents/forward',
|
|
26
26
|
'agents/backward',
|
|
27
27
|
'agents/sync',
|
|
28
|
+
'commands/gtd/forward',
|
|
29
|
+
'commands/gtd/backward',
|
|
30
|
+
'commands/gtd/sync',
|
|
31
|
+
'commands/gtd/utility',
|
|
28
32
|
'workflows/forward',
|
|
29
33
|
'workflows/backward',
|
|
30
34
|
'workflows/sync',
|
|
@@ -38,7 +42,9 @@ const INSTALL_DIRS = [
|
|
|
38
42
|
'templates/backward/system-design',
|
|
39
43
|
'templates/backward/api-docs',
|
|
40
44
|
'templates/backward/runbook',
|
|
45
|
+
'templates/backward/formats',
|
|
41
46
|
'contexts',
|
|
47
|
+
'hooks',
|
|
42
48
|
];
|
|
43
49
|
|
|
44
50
|
/**
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GTD Installer Adapter — Cursor runtime.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Cursor reads commands from .cursor/skills/<name>/SKILL.md at the PROJECT level.
|
|
5
|
+
* This is the same format as Claude Code skills.
|
|
6
|
+
*
|
|
7
|
+
* Install location:
|
|
8
|
+
* Local: PROJECT/.cursor/skills/gtd-COMMAND/SKILL.md (recommended for Cursor)
|
|
9
|
+
* Global: HOME/.cursor/skills/gtd-COMMAND/SKILL.md
|
|
10
|
+
*
|
|
11
|
+
* Framework files go to:
|
|
12
|
+
* Local: PROJECT/.cursor/get-things-done/
|
|
13
|
+
* Global: HOME/.cursor/get-things-done/
|
|
5
14
|
*
|
|
6
15
|
* @module lib/installers/cursor
|
|
7
16
|
*/
|
|
@@ -23,39 +32,44 @@ function getInstallPath(location) {
|
|
|
23
32
|
return path.join(process.cwd(), '.cursor', 'get-things-done');
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* Cursor reads the manifest for available GTD workflow commands.
|
|
29
|
-
*/
|
|
35
|
+
// Install commands as .cursor/skills/gtd-COMMAND/SKILL.md files.
|
|
36
|
+
// This is the format Cursor recognizes as slash commands.
|
|
30
37
|
function copyCommands(installBase) {
|
|
31
|
-
|
|
32
|
-
const
|
|
38
|
+
// Determine the .cursor root (parent of get-things-done/)
|
|
39
|
+
const cursorRoot = path.dirname(installBase);
|
|
40
|
+
const skillsDir = path.join(cursorRoot, 'skills');
|
|
33
41
|
let installed = 0;
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
// Read all command files from commands/gtd/
|
|
44
|
+
const commandsBase = path.join(installBase, 'commands', 'gtd');
|
|
45
|
+
if (!fs.existsSync(commandsBase)) return { installed };
|
|
36
46
|
|
|
37
|
-
for (const category of
|
|
38
|
-
const catDir = path.join(
|
|
39
|
-
if (!fs.
|
|
47
|
+
for (const category of ['backward', 'forward', 'sync', 'utility']) {
|
|
48
|
+
const catDir = path.join(commandsBase, category);
|
|
49
|
+
if (!fs.existsSync(catDir)) continue;
|
|
40
50
|
|
|
41
51
|
for (const file of fs.readdirSync(catDir).filter((f) => f.endsWith('.md'))) {
|
|
42
52
|
const cmdName = path.basename(file, '.md');
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
const skillName = `gtd-${cmdName}`;
|
|
54
|
+
const skillDir = path.join(skillsDir, skillName);
|
|
55
|
+
|
|
56
|
+
ensureDir(skillDir);
|
|
57
|
+
|
|
58
|
+
// Read the original command file
|
|
59
|
+
const content = fs.readFileSync(path.join(catDir, file), 'utf8');
|
|
60
|
+
|
|
61
|
+
// Write as SKILL.md (Cursor skill format)
|
|
62
|
+
atomicWrite(path.join(skillDir, 'SKILL.md'), content);
|
|
47
63
|
installed++;
|
|
48
64
|
}
|
|
49
65
|
}
|
|
50
66
|
|
|
51
|
-
|
|
52
|
-
atomicWrite(manifestPath, JSON.stringify(commands, null, 2) + '\n');
|
|
53
|
-
|
|
67
|
+
console.log(` Skills: ${installed} commands installed to ${skillsDir}`);
|
|
54
68
|
return { installed };
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
function setupHooks(installBase) {
|
|
58
|
-
//
|
|
72
|
+
// No additional hooks needed for Cursor
|
|
59
73
|
return { hooks: 0 };
|
|
60
74
|
}
|
|
61
75
|
|
package/mcp/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# GTD MCP Server
|
|
2
|
+
|
|
3
|
+
> Exposes all Get Things Done operations as MCP tools via stdio transport.
|
|
4
|
+
> No HTTP server. No deployment. Just a local subprocess.
|
|
5
|
+
|
|
6
|
+
## 19 Tools Exposed
|
|
7
|
+
|
|
8
|
+
| Tool | Description |
|
|
9
|
+
|------|-------------|
|
|
10
|
+
| `gtd_scan` | Scan and map codebase |
|
|
11
|
+
| `gtd_analyze` | Deep code analysis (7 dimensions) |
|
|
12
|
+
| `gtd_create_document` | Generate a specific document |
|
|
13
|
+
| `gtd_create_all` | Generate all 7 documents |
|
|
14
|
+
| `gtd_verify_docs` | Verify document accuracy |
|
|
15
|
+
| `gtd_update_docs` | Incremental document update |
|
|
16
|
+
| `gtd_new_project` | Initialize from idea |
|
|
17
|
+
| `gtd_plan_phase` | Research + plan a phase |
|
|
18
|
+
| `gtd_execute_phase` | Execute phase (generate code) |
|
|
19
|
+
| `gtd_deploy_local` | Deploy locally |
|
|
20
|
+
| `gtd_test` | Run test suite |
|
|
21
|
+
| `gtd_drift` | Detect spec-code drift |
|
|
22
|
+
| `gtd_sync` | Auto-reconcile drift |
|
|
23
|
+
| `gtd_audit` | Full alignment audit |
|
|
24
|
+
| `gtd_status` | Pipeline status |
|
|
25
|
+
| `gtd_config` | Get/set configuration |
|
|
26
|
+
| `gtd_read_document` | Read a generated document |
|
|
27
|
+
| `gtd_list_documents` | List all documents |
|
|
28
|
+
| `gtd_scale_detect` | Detect project tier |
|
|
29
|
+
|
|
30
|
+
## Setup
|
|
31
|
+
|
|
32
|
+
### Claude Desktop
|
|
33
|
+
|
|
34
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"gtd": {
|
|
40
|
+
"command": "node",
|
|
41
|
+
"args": [
|
|
42
|
+
"/path/to/node_modules/@karthikrajkumar.kannan/get-things-done/mcp/gtd-mcp-server.cjs",
|
|
43
|
+
"--project",
|
|
44
|
+
"/path/to/your/project"
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Claude Code
|
|
52
|
+
|
|
53
|
+
Add to `.claude/settings.json`:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"gtd": {
|
|
59
|
+
"command": "node",
|
|
60
|
+
"args": ["./node_modules/@karthikrajkumar.kannan/get-things-done/mcp/gtd-mcp-server.cjs"]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### After npx Install (Global)
|
|
67
|
+
|
|
68
|
+
If you installed via `npx @karthikrajkumar.kannan/get-things-done --claude --global`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"gtd": {
|
|
74
|
+
"command": "gtd-mcp-server",
|
|
75
|
+
"args": ["--project", "/path/to/your/project"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Custom Application (React + Monaco + Chat)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
85
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
86
|
+
|
|
87
|
+
// Start GTD MCP server as a subprocess
|
|
88
|
+
const transport = new StdioClientTransport({
|
|
89
|
+
command: 'node',
|
|
90
|
+
args: [
|
|
91
|
+
'node_modules/@karthikrajkumar.kannan/get-things-done/mcp/gtd-mcp-server.cjs',
|
|
92
|
+
'--project', '/path/to/project'
|
|
93
|
+
],
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const client = new Client({ name: 'my-app', version: '1.0.0' }, {});
|
|
97
|
+
await client.connect(transport);
|
|
98
|
+
|
|
99
|
+
// List available tools
|
|
100
|
+
const tools = await client.listTools();
|
|
101
|
+
console.log(tools); // 19 GTD tools
|
|
102
|
+
|
|
103
|
+
// Call a tool
|
|
104
|
+
const result = await client.callTool({
|
|
105
|
+
name: 'gtd_scan',
|
|
106
|
+
arguments: { force: false },
|
|
107
|
+
});
|
|
108
|
+
console.log(result.content[0].text);
|
|
109
|
+
|
|
110
|
+
// Use with Claude API (pass tools as tool definitions)
|
|
111
|
+
const response = await anthropic.messages.create({
|
|
112
|
+
model: 'claude-sonnet-4-20250514',
|
|
113
|
+
messages: [{ role: 'user', content: 'Scan this codebase and generate a TDD' }],
|
|
114
|
+
tools: tools.tools.map(t => ({
|
|
115
|
+
name: t.name,
|
|
116
|
+
description: t.description,
|
|
117
|
+
input_schema: t.inputSchema,
|
|
118
|
+
})),
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Test
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Quick test — send initialize + tools/list
|
|
126
|
+
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}
|
|
127
|
+
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | node mcp/gtd-mcp-server.cjs
|
|
128
|
+
```
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GTD MCP Server — Exposes all Get Things Done operations as MCP tools.
|
|
5
|
+
*
|
|
6
|
+
* Transport: stdio (no HTTP, no deployment — runs as a local subprocess)
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node gtd-mcp-server.cjs # Uses cwd as project dir
|
|
10
|
+
* node gtd-mcp-server.cjs --project /path/to/dir # Explicit project dir
|
|
11
|
+
*
|
|
12
|
+
* Configure in Claude Desktop (claude_desktop_config.json):
|
|
13
|
+
* {
|
|
14
|
+
* "mcpServers": {
|
|
15
|
+
* "gtd": {
|
|
16
|
+
* "command": "node",
|
|
17
|
+
* "args": ["/path/to/gtd-mcp-server.cjs", "--project", "/path/to/your/project"]
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
|
|
26
|
+
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
27
|
+
const {
|
|
28
|
+
CallToolRequestSchema,
|
|
29
|
+
ListToolsRequestSchema,
|
|
30
|
+
} = require('@modelcontextprotocol/sdk/types.js');
|
|
31
|
+
const { execSync } = require('child_process');
|
|
32
|
+
const fs = require('fs');
|
|
33
|
+
const path = require('path');
|
|
34
|
+
|
|
35
|
+
// --- Parse args ---
|
|
36
|
+
const args = process.argv.slice(2);
|
|
37
|
+
let projectDir = process.cwd();
|
|
38
|
+
const projectIdx = args.indexOf('--project');
|
|
39
|
+
if (projectIdx !== -1 && args[projectIdx + 1]) {
|
|
40
|
+
projectDir = path.resolve(args[projectIdx + 1]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// --- Resolve gtd-tools.cjs ---
|
|
44
|
+
const GTD_TOOLS = path.resolve(__dirname, '..', 'bin', 'gtd-tools.cjs');
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Run a gtd-tools.cjs command and return the result.
|
|
48
|
+
*/
|
|
49
|
+
function runGTD(command, cmdArgs = []) {
|
|
50
|
+
try {
|
|
51
|
+
const result = execSync(
|
|
52
|
+
`node "${GTD_TOOLS}" ${command} ${cmdArgs.join(' ')}`,
|
|
53
|
+
{
|
|
54
|
+
encoding: 'utf8',
|
|
55
|
+
cwd: projectDir,
|
|
56
|
+
timeout: 60000,
|
|
57
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
58
|
+
}
|
|
59
|
+
).trim();
|
|
60
|
+
return { success: true, data: result };
|
|
61
|
+
} catch (err) {
|
|
62
|
+
return { success: false, error: err.stderr || err.message };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Read a file from the project's .planning/ directory.
|
|
68
|
+
*/
|
|
69
|
+
function readPlanningFile(filename) {
|
|
70
|
+
const filePath = path.join(projectDir, '.planning', filename);
|
|
71
|
+
if (fs.existsSync(filePath)) {
|
|
72
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// --- Define all GTD tools ---
|
|
78
|
+
|
|
79
|
+
const GTD_TOOLS_DEFINITION = [
|
|
80
|
+
// === BACKWARD PIPELINE ===
|
|
81
|
+
{
|
|
82
|
+
name: 'gtd_scan',
|
|
83
|
+
description: 'Scan and map a codebase — detects languages, frameworks, entry points, infrastructure. Run this first before any document generation.',
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
force: { type: 'boolean', description: 'Force re-scan even if map is current', default: false },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'gtd_analyze',
|
|
93
|
+
description: 'Run deep code analysis across 7 dimensions: architecture, API, patterns, data-flow, dependencies, security, performance.',
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
focus: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'Analyze only this dimension',
|
|
100
|
+
enum: ['architecture', 'api', 'data-flow', 'dependencies', 'security', 'performance'],
|
|
101
|
+
},
|
|
102
|
+
force: { type: 'boolean', description: 'Force re-analysis', default: false },
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'gtd_create_document',
|
|
108
|
+
description: 'Generate a technical document from codebase analysis. Auto-scans and analyzes if needed.',
|
|
109
|
+
inputSchema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
doc_type: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Type of document to generate',
|
|
115
|
+
enum: ['tdd', 'hld', 'lld', 'capacity', 'system-design', 'api-docs', 'runbook'],
|
|
116
|
+
},
|
|
117
|
+
format: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
description: 'Document format/template',
|
|
120
|
+
enum: ['standard', 'enterprise', 'startup', 'compliance'],
|
|
121
|
+
default: 'standard',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
required: ['doc_type'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'gtd_create_all',
|
|
129
|
+
description: 'Generate the complete 7-document suite (TDD, HLD, LLD, Capacity Plan, System Design, API Docs, Runbook).',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
format: {
|
|
134
|
+
type: 'string',
|
|
135
|
+
enum: ['standard', 'enterprise', 'startup', 'compliance'],
|
|
136
|
+
default: 'standard',
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'gtd_verify_docs',
|
|
143
|
+
description: 'Verify accuracy of generated documents by cross-referencing claims against actual code.',
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
doc_type: {
|
|
148
|
+
type: 'string',
|
|
149
|
+
description: 'Document to verify (or omit for all)',
|
|
150
|
+
enum: ['tdd', 'hld', 'lld', 'capacity', 'system-design', 'api-docs', 'runbook'],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'gtd_update_docs',
|
|
157
|
+
description: 'Incrementally update documents based on code changes — only regenerates affected sections.',
|
|
158
|
+
inputSchema: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
since: { type: 'string', description: 'Git commit to compare against (default: last generation)' },
|
|
162
|
+
doc_type: { type: 'string', description: 'Update specific document only' },
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// === FORWARD PIPELINE ===
|
|
168
|
+
{
|
|
169
|
+
name: 'gtd_new_project',
|
|
170
|
+
description: 'Initialize a new project from an idea — adaptive questioning, research, requirements, roadmap.',
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: 'object',
|
|
173
|
+
properties: {
|
|
174
|
+
idea: { type: 'string', description: 'Project idea description' },
|
|
175
|
+
auto: { type: 'boolean', description: 'Skip interactive questions, use defaults', default: false },
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'gtd_plan_phase',
|
|
181
|
+
description: 'Research and create a detailed execution plan for a specific phase.',
|
|
182
|
+
inputSchema: {
|
|
183
|
+
type: 'object',
|
|
184
|
+
properties: {
|
|
185
|
+
phase: { type: 'number', description: 'Phase number to plan' },
|
|
186
|
+
},
|
|
187
|
+
required: ['phase'],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'gtd_execute_phase',
|
|
192
|
+
description: 'Execute a phase plan — generate code, run tests, commit atomically per task.',
|
|
193
|
+
inputSchema: {
|
|
194
|
+
type: 'object',
|
|
195
|
+
properties: {
|
|
196
|
+
phase: { type: 'number', description: 'Phase number to execute' },
|
|
197
|
+
wave: { type: 'number', description: 'Execute specific wave only' },
|
|
198
|
+
},
|
|
199
|
+
required: ['phase'],
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'gtd_deploy_local',
|
|
204
|
+
description: 'Deploy the project locally — auto-detects Docker, npm, Python, Go, Rust.',
|
|
205
|
+
inputSchema: {
|
|
206
|
+
type: 'object',
|
|
207
|
+
properties: {},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: 'gtd_test',
|
|
212
|
+
description: 'Run the project test suite — auto-detects Jest, Vitest, pytest, Go test, Cargo test, RSpec.',
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: 'object',
|
|
215
|
+
properties: {
|
|
216
|
+
phase: { type: 'number', description: 'Phase to test (optional)' },
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
// === SYNC ===
|
|
222
|
+
{
|
|
223
|
+
name: 'gtd_drift',
|
|
224
|
+
description: 'Detect drift between specs/docs and actual code. Finds additions, removals, mutations, structural changes.',
|
|
225
|
+
inputSchema: {
|
|
226
|
+
type: 'object',
|
|
227
|
+
properties: {
|
|
228
|
+
since: { type: 'string', description: 'Compare against this git commit' },
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: 'gtd_sync',
|
|
234
|
+
description: 'Auto-reconcile spec-code drift — detect, plan reconciliation, apply changes.',
|
|
235
|
+
inputSchema: {
|
|
236
|
+
type: 'object',
|
|
237
|
+
properties: {
|
|
238
|
+
strategy: {
|
|
239
|
+
type: 'string',
|
|
240
|
+
description: 'Reconciliation strategy',
|
|
241
|
+
enum: ['code-wins', 'spec-wins', 'interactive'],
|
|
242
|
+
default: 'code-wins',
|
|
243
|
+
},
|
|
244
|
+
auto: { type: 'boolean', description: 'Skip confirmation, auto-apply', default: false },
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: 'gtd_audit',
|
|
250
|
+
description: 'Full alignment audit — coverage matrix of requirements to code to docs to tests.',
|
|
251
|
+
inputSchema: {
|
|
252
|
+
type: 'object',
|
|
253
|
+
properties: {
|
|
254
|
+
compliance: {
|
|
255
|
+
type: 'string',
|
|
256
|
+
description: 'Compliance framework to check against',
|
|
257
|
+
enum: ['soc2', 'iso27001'],
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
// === UTILITY ===
|
|
264
|
+
{
|
|
265
|
+
name: 'gtd_status',
|
|
266
|
+
description: 'Get full pipeline status — forward progress, backward documents, sync alignment, analysis cache.',
|
|
267
|
+
inputSchema: {
|
|
268
|
+
type: 'object',
|
|
269
|
+
properties: {},
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
name: 'gtd_config',
|
|
274
|
+
description: 'Get or set GTD configuration values.',
|
|
275
|
+
inputSchema: {
|
|
276
|
+
type: 'object',
|
|
277
|
+
properties: {
|
|
278
|
+
key: { type: 'string', description: 'Config key (dot notation, e.g., "documents.format")' },
|
|
279
|
+
value: { type: 'string', description: 'Value to set (omit to read)' },
|
|
280
|
+
},
|
|
281
|
+
required: ['key'],
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'gtd_read_document',
|
|
286
|
+
description: 'Read a generated document or planning artifact from .planning/ directory.',
|
|
287
|
+
inputSchema: {
|
|
288
|
+
type: 'object',
|
|
289
|
+
properties: {
|
|
290
|
+
filename: {
|
|
291
|
+
type: 'string',
|
|
292
|
+
description: 'File to read (e.g., "documents/TDD.md", "CODEBASE-MAP.md", "analysis/ARCHITECTURE-ANALYSIS.md")',
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
required: ['filename'],
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: 'gtd_list_documents',
|
|
300
|
+
description: 'List all generated documents with their status (pending, drafting, finalized, stale).',
|
|
301
|
+
inputSchema: {
|
|
302
|
+
type: 'object',
|
|
303
|
+
properties: {},
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: 'gtd_scale_detect',
|
|
308
|
+
description: 'Detect project tier (micro/small/medium/large/enterprise) and get adaptive configuration.',
|
|
309
|
+
inputSchema: {
|
|
310
|
+
type: 'object',
|
|
311
|
+
properties: {},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
// --- Tool execution ---
|
|
317
|
+
|
|
318
|
+
async function executeTool(name, toolArgs) {
|
|
319
|
+
switch (name) {
|
|
320
|
+
// BACKWARD
|
|
321
|
+
case 'gtd_scan': {
|
|
322
|
+
const a = ['scan-codebase'];
|
|
323
|
+
if (toolArgs.force) a.push('--force');
|
|
324
|
+
const ctx = runGTD('init', a);
|
|
325
|
+
if (!ctx.success) return `Error: ${ctx.error}`;
|
|
326
|
+
return `Scan context loaded for project at ${projectDir}.\n\nUse the codebase mapper agent instructions from the scan-codebase workflow to produce CODEBASE-MAP.md.\n\nContext:\n${ctx.data.slice(0, 3000)}`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
case 'gtd_analyze': {
|
|
330
|
+
const a = ['analyze-codebase'];
|
|
331
|
+
if (toolArgs.focus) a.push('--focus', toolArgs.focus);
|
|
332
|
+
if (toolArgs.force) a.push('--force');
|
|
333
|
+
const ctx = runGTD('init', a);
|
|
334
|
+
return ctx.success ? `Analysis context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
case 'gtd_create_document': {
|
|
338
|
+
const a = ['generate-document', toolArgs.doc_type];
|
|
339
|
+
if (toolArgs.format) a.push('--format', toolArgs.format);
|
|
340
|
+
const ctx = runGTD('init', a);
|
|
341
|
+
return ctx.success ? `Document generation context for ${toolArgs.doc_type}:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
case 'gtd_create_all': {
|
|
345
|
+
const a = ['create-all'];
|
|
346
|
+
if (toolArgs.format) a.push('--format', toolArgs.format);
|
|
347
|
+
const ctx = runGTD('init', a);
|
|
348
|
+
return ctx.success ? `Create-all context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
case 'gtd_verify_docs': {
|
|
352
|
+
const a = ['verify-document'];
|
|
353
|
+
if (toolArgs.doc_type) a.push(toolArgs.doc_type);
|
|
354
|
+
const ctx = runGTD('init', a);
|
|
355
|
+
return ctx.success ? `Verification context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
case 'gtd_update_docs': {
|
|
359
|
+
const a = ['incremental-update'];
|
|
360
|
+
if (toolArgs.since) a.push('--since', toolArgs.since);
|
|
361
|
+
if (toolArgs.doc_type) a.push('--doc', toolArgs.doc_type);
|
|
362
|
+
const ctx = runGTD('init', a);
|
|
363
|
+
return ctx.success ? `Update context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// FORWARD
|
|
367
|
+
case 'gtd_new_project': {
|
|
368
|
+
const a = ['new-project'];
|
|
369
|
+
if (toolArgs.auto) a.push('--auto');
|
|
370
|
+
const ctx = runGTD('init', a);
|
|
371
|
+
return ctx.success ? `New project context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
case 'gtd_plan_phase': {
|
|
375
|
+
const ctx = runGTD('init', ['plan-phase', String(toolArgs.phase)]);
|
|
376
|
+
return ctx.success ? `Plan phase ${toolArgs.phase} context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
case 'gtd_execute_phase': {
|
|
380
|
+
const a = ['execute-phase', String(toolArgs.phase)];
|
|
381
|
+
if (toolArgs.wave) a.push('--wave', String(toolArgs.wave));
|
|
382
|
+
const ctx = runGTD('init', a);
|
|
383
|
+
return ctx.success ? `Execute phase ${toolArgs.phase} context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
case 'gtd_deploy_local': {
|
|
387
|
+
const deploy = runGTD('deploy', ['detect']);
|
|
388
|
+
const ctx = runGTD('init', ['deploy-local']);
|
|
389
|
+
return `Deploy detection:\n${deploy.data || deploy.error}\n\nContext:\n${ctx.data || ctx.error}`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
case 'gtd_test': {
|
|
393
|
+
const testInfo = runGTD('test', ['detect']);
|
|
394
|
+
const a = toolArgs.phase ? ['test-phase', String(toolArgs.phase)] : ['test-phase'];
|
|
395
|
+
const ctx = runGTD('init', a);
|
|
396
|
+
return `Test framework:\n${testInfo.data || testInfo.error}\n\nContext:\n${ctx.data || ctx.error}`;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// SYNC
|
|
400
|
+
case 'gtd_drift': {
|
|
401
|
+
const check = runGTD('drift', ['check']);
|
|
402
|
+
const context = runGTD('drift', ['context']);
|
|
403
|
+
return `Drift check:\n${check.data || check.error}\n\nDrift context:\n${context.data || context.error}`;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
case 'gtd_sync': {
|
|
407
|
+
const a = ['sync'];
|
|
408
|
+
if (toolArgs.auto) a.push('--auto');
|
|
409
|
+
if (toolArgs.strategy) a.push('--strategy', toolArgs.strategy);
|
|
410
|
+
const ctx = runGTD('init', a);
|
|
411
|
+
return ctx.success ? `Sync context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
case 'gtd_audit': {
|
|
415
|
+
const a = ['audit'];
|
|
416
|
+
if (toolArgs.compliance) a.push('--compliance', toolArgs.compliance);
|
|
417
|
+
const ctx = runGTD('init', a);
|
|
418
|
+
return ctx.success ? `Audit context:\n${ctx.data.slice(0, 3000)}` : `Error: ${ctx.error}`;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// UTILITY
|
|
422
|
+
case 'gtd_status': {
|
|
423
|
+
const state = runGTD('state', ['get']);
|
|
424
|
+
const analysis = runGTD('analysis', ['status']);
|
|
425
|
+
const docs = runGTD('doc', ['list']);
|
|
426
|
+
return `State:\n${state.data || state.error}\n\nAnalysis:\n${analysis.data || analysis.error}\n\nDocuments:\n${docs.data || docs.error}`;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
case 'gtd_config': {
|
|
430
|
+
if (toolArgs.value !== undefined) {
|
|
431
|
+
const result = runGTD('config-set', [toolArgs.key, toolArgs.value]);
|
|
432
|
+
return result.success ? `Set ${toolArgs.key} = ${toolArgs.value}` : `Error: ${result.error}`;
|
|
433
|
+
} else {
|
|
434
|
+
const result = runGTD('config-get', [toolArgs.key]);
|
|
435
|
+
return result.success ? `${toolArgs.key} = ${result.data}` : `Error: ${result.error}`;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
case 'gtd_read_document': {
|
|
440
|
+
const content = readPlanningFile(toolArgs.filename);
|
|
441
|
+
if (content) return content;
|
|
442
|
+
return `File not found: .planning/${toolArgs.filename}`;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
case 'gtd_list_documents': {
|
|
446
|
+
const result = runGTD('doc', ['list']);
|
|
447
|
+
return result.success ? result.data : `Error: ${result.error}`;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
case 'gtd_scale_detect': {
|
|
451
|
+
const result = runGTD('scale', ['detect']);
|
|
452
|
+
return result.success ? result.data : `Error: ${result.error}`;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
default:
|
|
456
|
+
return `Unknown tool: ${name}`;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// --- Create MCP Server ---
|
|
461
|
+
|
|
462
|
+
const server = new Server(
|
|
463
|
+
{
|
|
464
|
+
name: 'gtd-mcp-server',
|
|
465
|
+
version: '1.0.0',
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
capabilities: {
|
|
469
|
+
tools: {},
|
|
470
|
+
},
|
|
471
|
+
}
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
// List tools
|
|
475
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
476
|
+
return { tools: GTD_TOOLS_DEFINITION };
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// Call tool
|
|
480
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
481
|
+
const { name, arguments: toolArgs } = request.params;
|
|
482
|
+
|
|
483
|
+
try {
|
|
484
|
+
const result = await executeTool(name, toolArgs || {});
|
|
485
|
+
return {
|
|
486
|
+
content: [{ type: 'text', text: result }],
|
|
487
|
+
};
|
|
488
|
+
} catch (err) {
|
|
489
|
+
return {
|
|
490
|
+
content: [{ type: 'text', text: `GTD Error: ${err.message}` }],
|
|
491
|
+
isError: true,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// --- Start ---
|
|
497
|
+
|
|
498
|
+
async function main() {
|
|
499
|
+
const transport = new StdioServerTransport();
|
|
500
|
+
await server.connect(transport);
|
|
501
|
+
// Server is now running on stdio — it reads from stdin and writes to stdout
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
main().catch((err) => {
|
|
505
|
+
process.stderr.write(`GTD MCP Server error: ${err.message}\n`);
|
|
506
|
+
process.exit(1);
|
|
507
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@karthikrajkumar.kannan/get-things-done",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Bidirectional spec-driven agentic framework — Forward (idea to code to deploy), Backward (code to docs), Sync (drift detection and reconciliation). The first framework that goes both ways.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -28,11 +28,13 @@
|
|
|
28
28
|
"url": "https://github.com/get-things-done/get-things-done"
|
|
29
29
|
},
|
|
30
30
|
"bin": {
|
|
31
|
-
"get-things-done": "./bin/install.js"
|
|
31
|
+
"get-things-done": "./bin/install.js",
|
|
32
|
+
"gtd-mcp-server": "./mcp/gtd-mcp-server.cjs"
|
|
32
33
|
},
|
|
33
34
|
"main": "./bin/gtd-tools.cjs",
|
|
34
35
|
"files": [
|
|
35
36
|
"bin/",
|
|
37
|
+
"mcp/",
|
|
36
38
|
"lib/",
|
|
37
39
|
"agents/",
|
|
38
40
|
"commands/",
|
|
@@ -57,12 +59,12 @@
|
|
|
57
59
|
"prepare": "husky"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
60
|
-
"vitest": "^3.1.0",
|
|
61
62
|
"@vitest/coverage-v8": "^3.1.0",
|
|
62
63
|
"eslint": "^9.0.0",
|
|
63
|
-
"prettier": "^3.5.0",
|
|
64
64
|
"husky": "^9.1.0",
|
|
65
|
-
"lint-staged": "^15.4.0"
|
|
65
|
+
"lint-staged": "^15.4.0",
|
|
66
|
+
"prettier": "^3.5.0",
|
|
67
|
+
"vitest": "^3.1.0"
|
|
66
68
|
},
|
|
67
69
|
"lint-staged": {
|
|
68
70
|
"*.{js,cjs,ts}": [
|
|
@@ -72,5 +74,8 @@
|
|
|
72
74
|
"*.{md,json,yml,yaml}": [
|
|
73
75
|
"prettier --write"
|
|
74
76
|
]
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
75
80
|
}
|
|
76
81
|
}
|