@godpowers/mcp 2.6.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Godpowers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # @godpowers/mcp
2
+
3
+ - [DECISION] `@godpowers/mcp` is the first-party read-only MCP companion package for Godpowers.
4
+ - [DECISION] The main `godpowers` package stays dependency-free at runtime, and the MCP SDK dependency lives only in this companion package.
5
+ - [DECISION] Version 2.6.0 exposes five tools: `status`, `next`, `gate_check`, `lint_artifact`, and `trace_requirement`.
6
+ - [DECISION] Mutation tools are intentionally absent through the 3.0.0 release.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install -g godpowers @godpowers/mcp
12
+ ```
13
+
14
+ ## Run
15
+
16
+ ```bash
17
+ godpowers-mcp serve --project=.
18
+ ```
19
+
20
+ ## Codex Setup
21
+
22
+ ```bash
23
+ godpowers-mcp setup --host=codex --project=.
24
+ godpowers-mcp setup --host=codex --project=. --write
25
+ ```
26
+
27
+ - [DECISION] The first command prints a registration plan without writing files.
28
+ - [DECISION] The second command writes a managed `[mcp_servers.godpowers]` block to `~/.codex/config.toml`.
29
+ - [DECISION] No automatic host registration runs during package install.
30
+
31
+ ## Tool Boundary
32
+
33
+ - [DECISION] `status` wraps `lib/dashboard.js` and returns rendered dashboard text plus structured status.
34
+ - [DECISION] `next` wraps `lib/dashboard.js` and returns the recommended next command from disk state.
35
+ - [DECISION] `gate_check` wraps `lib/gate.js` and returns the executable tier gate verdict.
36
+ - [DECISION] `lint_artifact` wraps `lib/artifact-linter.js` for one file inside the project root.
37
+ - [DECISION] `trace_requirement` wraps `lib/requirements.js` and returns requirement, roadmap, linkage, and ledger evidence.
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+
5
+ const server = require('../lib/server');
6
+ const setup = require('../lib/setup');
7
+
8
+ function parseArgs(argv, cwd = process.cwd()) {
9
+ const args = argv.slice(2);
10
+ const opts = {
11
+ command: 'serve',
12
+ project: cwd,
13
+ runtimeRoot: null,
14
+ host: 'codex',
15
+ write: false,
16
+ json: false,
17
+ homeDir: null,
18
+ help: false
19
+ };
20
+
21
+ if (args[0] && !args[0].startsWith('-')) {
22
+ opts.command = args[0];
23
+ args.shift();
24
+ }
25
+
26
+ for (let i = 0; i < args.length; i++) {
27
+ const arg = args[i];
28
+ switch (arg) {
29
+ case '--project':
30
+ if (args[i + 1]) {
31
+ opts.project = path.resolve(args[i + 1]);
32
+ i++;
33
+ }
34
+ break;
35
+ case '--runtime-root':
36
+ if (args[i + 1]) {
37
+ opts.runtimeRoot = path.resolve(args[i + 1]);
38
+ i++;
39
+ }
40
+ break;
41
+ case '--host':
42
+ if (args[i + 1]) {
43
+ opts.host = args[i + 1];
44
+ i++;
45
+ }
46
+ break;
47
+ case '--home':
48
+ if (args[i + 1]) {
49
+ opts.homeDir = path.resolve(args[i + 1]);
50
+ i++;
51
+ }
52
+ break;
53
+ case '--write':
54
+ opts.write = true;
55
+ break;
56
+ case '--json':
57
+ opts.json = true;
58
+ break;
59
+ case '-h':
60
+ case '--help':
61
+ opts.help = true;
62
+ break;
63
+ default:
64
+ if (arg.startsWith('--project=')) {
65
+ opts.project = path.resolve(arg.slice('--project='.length));
66
+ } else if (arg.startsWith('--runtime-root=')) {
67
+ opts.runtimeRoot = path.resolve(arg.slice('--runtime-root='.length));
68
+ } else if (arg.startsWith('--host=')) {
69
+ opts.host = arg.slice('--host='.length);
70
+ } else if (arg.startsWith('--home=')) {
71
+ opts.homeDir = path.resolve(arg.slice('--home='.length));
72
+ }
73
+ break;
74
+ }
75
+ }
76
+
77
+ return opts;
78
+ }
79
+
80
+ function renderHelp() {
81
+ return [
82
+ 'Godpowers MCP',
83
+ '',
84
+ 'Usage:',
85
+ ' godpowers-mcp serve --project=.',
86
+ ' godpowers-mcp setup --host=codex --project=. --write',
87
+ '',
88
+ 'Commands:',
89
+ ' serve Run the read-only MCP server over stdio.',
90
+ ' setup Print or write an explicit host registration.',
91
+ '',
92
+ 'Options:',
93
+ ' --project=<path> Project root read by MCP tools.',
94
+ ' --runtime-root=<path> Godpowers runtime root for local checkouts.',
95
+ ' --host=<name> Host registration target. Currently codex.',
96
+ ' --home=<path> Home directory for setup tests or explicit installs.',
97
+ ' --write Write setup output. Without this, setup is read-only.',
98
+ ' --json Emit JSON for setup.',
99
+ ' -h, --help Show this help.'
100
+ ].join('\n');
101
+ }
102
+
103
+ async function main() {
104
+ const opts = parseArgs(process.argv);
105
+ if (opts.help || opts.command === 'help') {
106
+ console.log(renderHelp());
107
+ return;
108
+ }
109
+
110
+ if (opts.command === 'setup') {
111
+ const plan = setup.setupPlan({
112
+ host: opts.host,
113
+ projectRoot: opts.project,
114
+ runtimeRoot: opts.runtimeRoot,
115
+ homeDir: opts.homeDir
116
+ });
117
+ const result = opts.write ? setup.writeRegistration(plan) : plan;
118
+ if (opts.json) {
119
+ console.log(JSON.stringify(result, null, 2));
120
+ } else {
121
+ console.log(setup.render(result));
122
+ }
123
+ return;
124
+ }
125
+
126
+ if (opts.command !== 'serve') {
127
+ console.error(`Unknown command: ${opts.command}`);
128
+ process.exit(1);
129
+ }
130
+
131
+ await server.serveStdio({
132
+ projectRoot: opts.project,
133
+ runtimeRoot: opts.runtimeRoot
134
+ });
135
+ }
136
+
137
+ if (require.main === module) {
138
+ main().catch((error) => {
139
+ console.error(`Godpowers MCP failed: ${error.message}`);
140
+ process.exit(1);
141
+ });
142
+ }
143
+
144
+ module.exports = {
145
+ parseArgs,
146
+ renderHelp
147
+ };
package/lib/runtime.js ADDED
@@ -0,0 +1,82 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ function exists(filePath) {
5
+ return fs.existsSync(filePath);
6
+ }
7
+
8
+ function isRuntimeRoot(root) {
9
+ if (!root) return false;
10
+ const pkgPath = path.join(root, 'package.json');
11
+ if (!exists(pkgPath)) return false;
12
+ if (!exists(path.join(root, 'lib', 'dashboard.js'))) return false;
13
+ try {
14
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
15
+ return pkg.name === 'godpowers';
16
+ } catch (error) {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ function addCandidate(candidates, value) {
22
+ if (!value) return;
23
+ const resolved = path.resolve(value);
24
+ if (!candidates.includes(resolved)) candidates.push(resolved);
25
+ }
26
+
27
+ function candidateRoots(opts = {}) {
28
+ const candidates = [];
29
+ addCandidate(candidates, opts.runtimeRoot);
30
+ addCandidate(candidates, process.env.GODPOWERS_RUNTIME_ROOT);
31
+ addCandidate(candidates, path.resolve(__dirname, '..', '..', '..'));
32
+ addCandidate(candidates, process.cwd());
33
+
34
+ try {
35
+ const pkgPath = require.resolve('godpowers/package.json', {
36
+ paths: [process.cwd(), __dirname]
37
+ });
38
+ addCandidate(candidates, path.dirname(pkgPath));
39
+ } catch (error) {
40
+ // Optional peer dependency. Local checkouts resolve through the candidates above.
41
+ }
42
+
43
+ return candidates;
44
+ }
45
+
46
+ function resolveRuntimeRoot(opts = {}) {
47
+ for (const root of candidateRoots(opts)) {
48
+ if (isRuntimeRoot(root)) return root;
49
+ }
50
+ throw new Error('Could not find a Godpowers runtime root. Pass --runtime-root or install godpowers beside @godpowers/mcp.');
51
+ }
52
+
53
+ function requireRuntime(moduleName, opts = {}) {
54
+ const root = resolveRuntimeRoot(opts);
55
+ return require(path.join(root, 'lib', `${moduleName}.js`));
56
+ }
57
+
58
+ function resolveProject(projectRoot) {
59
+ return path.resolve(projectRoot || process.cwd());
60
+ }
61
+
62
+ function resolveProjectFile(projectRoot, filePath) {
63
+ const root = resolveProject(projectRoot);
64
+ if (!filePath) throw new Error('file path is required');
65
+ const abs = path.isAbsolute(filePath)
66
+ ? path.resolve(filePath)
67
+ : path.resolve(root, filePath);
68
+ const relative = path.relative(root, abs);
69
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
70
+ throw new Error('artifact path must stay inside the project root');
71
+ }
72
+ return abs;
73
+ }
74
+
75
+ module.exports = {
76
+ isRuntimeRoot,
77
+ candidateRoots,
78
+ resolveRuntimeRoot,
79
+ requireRuntime,
80
+ resolveProject,
81
+ resolveProjectFile
82
+ };
package/lib/server.js ADDED
@@ -0,0 +1,26 @@
1
+ const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js');
2
+ const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
3
+
4
+ const pkg = require('../package.json');
5
+ const tools = require('./tools');
6
+
7
+ function createServer(opts = {}) {
8
+ const server = new McpServer({
9
+ name: 'godpowers-mcp',
10
+ version: pkg.version
11
+ });
12
+ tools.registerTools(server, opts);
13
+ return server;
14
+ }
15
+
16
+ async function serveStdio(opts = {}) {
17
+ const server = createServer(opts);
18
+ const transport = new StdioServerTransport();
19
+ await server.connect(transport);
20
+ return server;
21
+ }
22
+
23
+ module.exports = {
24
+ createServer,
25
+ serveStdio
26
+ };
package/lib/setup.js ADDED
@@ -0,0 +1,133 @@
1
+ const fs = require('fs');
2
+ const os = require('os');
3
+ const path = require('path');
4
+
5
+ const pkg = require('../package.json');
6
+
7
+ const BEGIN = '# godpowers:mcp:begin';
8
+ const END = '# godpowers:mcp:end';
9
+
10
+ function resolveProject(projectRoot) {
11
+ return path.resolve(projectRoot || process.cwd());
12
+ }
13
+
14
+ function serverCommand(projectRoot, version = pkg.version) {
15
+ return {
16
+ command: 'npx',
17
+ args: [
18
+ '-y',
19
+ '-p',
20
+ `godpowers@${version}`,
21
+ '-p',
22
+ `@godpowers/mcp@${version}`,
23
+ 'godpowers-mcp',
24
+ 'serve',
25
+ '--project',
26
+ resolveProject(projectRoot)
27
+ ]
28
+ };
29
+ }
30
+
31
+ function codexConfigPath(homeDir = os.homedir()) {
32
+ return path.join(homeDir, '.codex', 'config.toml');
33
+ }
34
+
35
+ function codexBlock(projectRoot, version = pkg.version) {
36
+ const command = serverCommand(projectRoot, version);
37
+ return [
38
+ BEGIN,
39
+ '[mcp_servers.godpowers]',
40
+ `command = ${JSON.stringify(command.command)}`,
41
+ `args = ${JSON.stringify(command.args)}`,
42
+ END
43
+ ].join('\n');
44
+ }
45
+
46
+ function genericJson(projectRoot, version = pkg.version) {
47
+ const command = serverCommand(projectRoot, version);
48
+ return {
49
+ mcpServers: {
50
+ godpowers: command
51
+ }
52
+ };
53
+ }
54
+
55
+ function setupPlan(opts = {}) {
56
+ const projectRoot = resolveProject(opts.projectRoot);
57
+ const host = opts.host || 'codex';
58
+ const homeDir = opts.homeDir || os.homedir();
59
+ const version = opts.version || pkg.version;
60
+ return {
61
+ host,
62
+ projectRoot,
63
+ version,
64
+ writes: false,
65
+ automaticRegistration: false,
66
+ codexConfigPath: codexConfigPath(homeDir),
67
+ command: serverCommand(projectRoot, version),
68
+ codexToml: codexBlock(projectRoot, version),
69
+ genericJson: genericJson(projectRoot, version)
70
+ };
71
+ }
72
+
73
+ function replaceManagedBlock(current, block) {
74
+ const pattern = new RegExp(`${BEGIN}[\\s\\S]*?${END}`);
75
+ if (pattern.test(current)) {
76
+ return current.replace(pattern, block);
77
+ }
78
+ const prefix = current.trimEnd();
79
+ return `${prefix}${prefix ? '\n\n' : ''}${block}\n`;
80
+ }
81
+
82
+ function writeRegistration(plan) {
83
+ if (plan.host !== 'codex') {
84
+ throw new Error('Only codex registration writes are supported. Use setup without --write for a JSON snippet.');
85
+ }
86
+ const filePath = plan.codexConfigPath;
87
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
88
+ const current = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
89
+ const next = replaceManagedBlock(current, plan.codexToml);
90
+ fs.writeFileSync(filePath, next);
91
+ return {
92
+ ...plan,
93
+ writes: true,
94
+ written: filePath
95
+ };
96
+ }
97
+
98
+ function render(plan) {
99
+ const lines = [
100
+ 'Godpowers MCP setup',
101
+ '',
102
+ `Host: ${plan.host}`,
103
+ `Project: ${plan.projectRoot}`,
104
+ `Package: @godpowers/mcp@${plan.version}`,
105
+ '',
106
+ 'Read-only server command:',
107
+ ` ${plan.command.command} ${plan.command.args.join(' ')}`,
108
+ '',
109
+ 'Codex config block:',
110
+ plan.codexToml,
111
+ '',
112
+ 'Generic JSON registration:',
113
+ JSON.stringify(plan.genericJson, null, 2),
114
+ '',
115
+ plan.writes
116
+ ? `Wrote explicit registration: ${plan.written}`
117
+ : 'No files written. Re-run setup with --write to opt in.'
118
+ ];
119
+ return lines.join('\n');
120
+ }
121
+
122
+ module.exports = {
123
+ BEGIN,
124
+ END,
125
+ serverCommand,
126
+ codexConfigPath,
127
+ codexBlock,
128
+ genericJson,
129
+ setupPlan,
130
+ replaceManagedBlock,
131
+ writeRegistration,
132
+ render
133
+ };
package/lib/tools.js ADDED
@@ -0,0 +1,202 @@
1
+ const path = require('path');
2
+ const z = require('zod/v4');
3
+
4
+ const runtime = require('./runtime');
5
+
6
+ const TOOL_NAMES = [
7
+ 'status',
8
+ 'next',
9
+ 'gate_check',
10
+ 'lint_artifact',
11
+ 'trace_requirement'
12
+ ];
13
+
14
+ function toolResult(value) {
15
+ return {
16
+ content: [
17
+ {
18
+ type: 'text',
19
+ text: JSON.stringify(value, null, 2)
20
+ }
21
+ ],
22
+ structuredContent: value
23
+ };
24
+ }
25
+
26
+ function toolError(error) {
27
+ return {
28
+ isError: true,
29
+ content: [
30
+ {
31
+ type: 'text',
32
+ text: error && error.message ? error.message : String(error)
33
+ }
34
+ ]
35
+ };
36
+ }
37
+
38
+ async function withErrors(fn) {
39
+ try {
40
+ return toolResult(await fn());
41
+ } catch (error) {
42
+ return toolError(error);
43
+ }
44
+ }
45
+
46
+ function projectRootFor(input, opts) {
47
+ return runtime.resolveProject(input.project || opts.projectRoot || process.cwd());
48
+ }
49
+
50
+ function statusTool(input = {}, opts = {}) {
51
+ const projectRoot = projectRootFor(input, opts);
52
+ const dashboard = runtime.requireRuntime('dashboard', opts);
53
+ const result = dashboard.compute(projectRoot, { git: input.git !== false });
54
+ return {
55
+ project: projectRoot,
56
+ dashboard: result,
57
+ rendered: dashboard.render(result, { brief: Boolean(input.brief) })
58
+ };
59
+ }
60
+
61
+ function nextTool(input = {}, opts = {}) {
62
+ const projectRoot = projectRootFor(input, opts);
63
+ const dashboard = runtime.requireRuntime('dashboard', opts);
64
+ const result = dashboard.compute(projectRoot, { git: input.git !== false });
65
+ return {
66
+ project: projectRoot,
67
+ next: result.next,
68
+ actionBrief: result.actionBrief,
69
+ dashboard: result
70
+ };
71
+ }
72
+
73
+ function gateTool(input = {}, opts = {}) {
74
+ const projectRoot = projectRootFor(input, opts);
75
+ const gate = runtime.requireRuntime('gate', opts);
76
+ return gate.check({
77
+ tier: input.tier,
78
+ projectRoot
79
+ });
80
+ }
81
+
82
+ function lintTool(input = {}, opts = {}) {
83
+ const projectRoot = projectRootFor(input, opts);
84
+ const linter = runtime.requireRuntime('artifact-linter', opts);
85
+ const artifactPath = runtime.resolveProjectFile(projectRoot, input.path);
86
+ const result = linter.lintFile(artifactPath, { projectRoot });
87
+ return {
88
+ project: projectRoot,
89
+ artifact: path.relative(projectRoot, artifactPath).split(path.sep).join('/'),
90
+ lint: {
91
+ type: result.type,
92
+ findings: result.findings,
93
+ summary: result.summary
94
+ }
95
+ };
96
+ }
97
+
98
+ function traceRequirementTool(input = {}, opts = {}) {
99
+ const projectRoot = projectRootFor(input, opts);
100
+ const requirements = runtime.requireRuntime('requirements', opts);
101
+ const derived = requirements.derive(projectRoot);
102
+ const id = String(input.id || '').trim();
103
+ const requirement = derived.requirements.find((item) => item.id === id) || null;
104
+ const increment = requirement && requirement.increment
105
+ ? derived.increments.find((item) => item.id === requirement.increment) || null
106
+ : null;
107
+ return {
108
+ project: projectRoot,
109
+ id,
110
+ found: Boolean(requirement),
111
+ requirement,
112
+ increment,
113
+ summary: derived.summary,
114
+ ledger: requirements.LEDGER_PATH
115
+ };
116
+ }
117
+
118
+ function registerTools(server, opts = {}) {
119
+ server.registerTool('status', {
120
+ title: 'Godpowers status',
121
+ description: 'Read Godpowers dashboard state from disk.',
122
+ inputSchema: {
123
+ project: z.string().optional().describe('Project root. Defaults to the server project.'),
124
+ brief: z.boolean().optional().describe('Include compact rendered dashboard text.'),
125
+ git: z.boolean().optional().describe('Set false to skip git status checks.')
126
+ },
127
+ annotations: {
128
+ readOnlyHint: true,
129
+ destructiveHint: false,
130
+ idempotentHint: true
131
+ }
132
+ }, async (input) => withErrors(() => statusTool(input, opts)));
133
+
134
+ server.registerTool('next', {
135
+ title: 'Godpowers next',
136
+ description: 'Read the recommended next Godpowers command from disk state.',
137
+ inputSchema: {
138
+ project: z.string().optional().describe('Project root. Defaults to the server project.'),
139
+ git: z.boolean().optional().describe('Set false to skip git status checks.')
140
+ },
141
+ annotations: {
142
+ readOnlyHint: true,
143
+ destructiveHint: false,
144
+ idempotentHint: true
145
+ }
146
+ }, async (input) => withErrors(() => nextTool(input, opts)));
147
+
148
+ server.registerTool('gate_check', {
149
+ title: 'Godpowers gate check',
150
+ description: 'Run a read-only executable tier gate check.',
151
+ inputSchema: {
152
+ project: z.string().optional().describe('Project root. Defaults to the server project.'),
153
+ tier: z.enum(['prd', 'design', 'arch', 'roadmap', 'stack', 'repo', 'build', 'harden'])
154
+ .describe('Gate tier to check.')
155
+ },
156
+ annotations: {
157
+ readOnlyHint: true,
158
+ destructiveHint: false,
159
+ idempotentHint: true
160
+ }
161
+ }, async (input) => withErrors(() => gateTool(input, opts)));
162
+
163
+ server.registerTool('lint_artifact', {
164
+ title: 'Godpowers artifact lint',
165
+ description: 'Lint one artifact path inside the project root.',
166
+ inputSchema: {
167
+ project: z.string().optional().describe('Project root. Defaults to the server project.'),
168
+ path: z.string().describe('Artifact path relative to the project root.')
169
+ },
170
+ annotations: {
171
+ readOnlyHint: true,
172
+ destructiveHint: false,
173
+ idempotentHint: true
174
+ }
175
+ }, async (input) => withErrors(() => lintTool(input, opts)));
176
+
177
+ server.registerTool('trace_requirement', {
178
+ title: 'Godpowers requirement trace',
179
+ description: 'Trace one PRD requirement id to linkage and roadmap evidence.',
180
+ inputSchema: {
181
+ project: z.string().optional().describe('Project root. Defaults to the server project.'),
182
+ id: z.string().describe('Requirement id such as P-MUST-01.')
183
+ },
184
+ annotations: {
185
+ readOnlyHint: true,
186
+ destructiveHint: false,
187
+ idempotentHint: true
188
+ }
189
+ }, async (input) => withErrors(() => traceRequirementTool(input, opts)));
190
+ }
191
+
192
+ module.exports = {
193
+ TOOL_NAMES,
194
+ registerTools,
195
+ statusTool,
196
+ nextTool,
197
+ gateTool,
198
+ lintTool,
199
+ traceRequirementTool,
200
+ toolResult,
201
+ toolError
202
+ };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@godpowers/mcp",
3
+ "version": "2.6.0",
4
+ "description": "Read-only MCP server for Godpowers runtime status, routing, gates, artifact linting, and requirement tracing.",
5
+ "bin": {
6
+ "godpowers-mcp": "./bin/godpowers-mcp.js"
7
+ },
8
+ "main": "./lib/server.js",
9
+ "type": "commonjs",
10
+ "scripts": {
11
+ "test": "node scripts/test-protocol.js",
12
+ "pack:check": "node scripts/check-package-contents.js"
13
+ },
14
+ "keywords": [
15
+ "godpowers",
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "ai-coding"
19
+ ],
20
+ "author": "Godpowers",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/aihxp/godpowers.git",
25
+ "directory": "packages/mcp"
26
+ },
27
+ "homepage": "https://github.com/aihxp/godpowers/tree/main/packages/mcp#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/aihxp/godpowers/issues"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "files": [
35
+ "bin/",
36
+ "lib/",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.29.0",
42
+ "zod": "^4.1.13"
43
+ },
44
+ "peerDependencies": {
45
+ "godpowers": ">=2.6.0"
46
+ },
47
+ "peerDependenciesMeta": {
48
+ "godpowers": {
49
+ "optional": true
50
+ }
51
+ }
52
+ }