nimai-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.
@@ -0,0 +1,118 @@
1
+ /**
2
+ * FORGE MCP Tool Contract — v1
3
+ *
4
+ * All tool schemas are defined and locked here before server implementation.
5
+ * Do NOT change tool names or output shapes without a contract version bump.
6
+ *
7
+ * Adversarial review notes (stress-tested before locking):
8
+ * - Tool names prefixed with "nimai_" to avoid collisions with host tool namespaces
9
+ * - All inputs validated with zod to prevent runtime shape errors
10
+ * - Outputs are plain serialisable objects (no class instances, no Buffers)
11
+ * - No LLM calls inside any tool — tools return context/structure only
12
+ * - specPath / repoPath are absolute or relative to cwd; server does NOT resolve ~
13
+ * - outputPath for nimai_new: parent directory is created if missing; write errors surface as tool errors
14
+ */
15
+ import { z } from 'zod';
16
+ import type { LintIssue, ContextItem } from 'nimai-core';
17
+ export declare const ForgeSpecInput: z.ZodObject<{
18
+ repoPath: z.ZodString;
19
+ request: z.ZodString;
20
+ }, "strip", z.ZodTypeAny, {
21
+ repoPath: string;
22
+ request: string;
23
+ }, {
24
+ repoPath: string;
25
+ request: string;
26
+ }>;
27
+ export declare const ForgeReviewInput: z.ZodObject<{
28
+ specPath: z.ZodString;
29
+ }, "strip", z.ZodTypeAny, {
30
+ specPath: string;
31
+ }, {
32
+ specPath: string;
33
+ }>;
34
+ export declare const ForgeValidateInput: z.ZodObject<{
35
+ specPath: z.ZodString;
36
+ }, "strip", z.ZodTypeAny, {
37
+ specPath: string;
38
+ }, {
39
+ specPath: string;
40
+ }>;
41
+ export declare const ForgeNewInput: z.ZodObject<{
42
+ outputPath: z.ZodString;
43
+ }, "strip", z.ZodTypeAny, {
44
+ outputPath: string;
45
+ }, {
46
+ outputPath: string;
47
+ }>;
48
+ export interface ForgeSpecOutput {
49
+ /** The populated FORGE Prompt 1 (Self-Spec Agent), ready to pass to a model */
50
+ prompt: string;
51
+ /** Repo context items extracted for the request */
52
+ context: ContextItem[];
53
+ }
54
+ export interface ForgeReviewOutput {
55
+ /** The populated FORGE Prompt 2 (Reviewer/Validator), derived from the spec */
56
+ reviewerPrompt: string;
57
+ }
58
+ export interface ForgeValidateOutput {
59
+ issues: LintIssue[];
60
+ /** true if zero issues found */
61
+ passed: boolean;
62
+ }
63
+ export interface ForgeNewOutput {
64
+ /** Absolute path where the spec file was written */
65
+ path: string;
66
+ /** Content written to the file */
67
+ content: string;
68
+ }
69
+ export declare const TOOL_DESCRIPTORS: {
70
+ readonly nimai_spec: {
71
+ readonly name: "nimai_spec";
72
+ readonly description: string;
73
+ readonly inputSchema: z.ZodObject<{
74
+ repoPath: z.ZodString;
75
+ request: z.ZodString;
76
+ }, "strip", z.ZodTypeAny, {
77
+ repoPath: string;
78
+ request: string;
79
+ }, {
80
+ repoPath: string;
81
+ request: string;
82
+ }>;
83
+ };
84
+ readonly nimai_review: {
85
+ readonly name: "nimai_review";
86
+ readonly description: string;
87
+ readonly inputSchema: z.ZodObject<{
88
+ specPath: z.ZodString;
89
+ }, "strip", z.ZodTypeAny, {
90
+ specPath: string;
91
+ }, {
92
+ specPath: string;
93
+ }>;
94
+ };
95
+ readonly nimai_validate: {
96
+ readonly name: "nimai_validate";
97
+ readonly description: string;
98
+ readonly inputSchema: z.ZodObject<{
99
+ specPath: z.ZodString;
100
+ }, "strip", z.ZodTypeAny, {
101
+ specPath: string;
102
+ }, {
103
+ specPath: string;
104
+ }>;
105
+ };
106
+ readonly nimai_new: {
107
+ readonly name: "nimai_new";
108
+ readonly description: "Scaffolds a new FORGE spec file from the canonical template at the specified output path.";
109
+ readonly inputSchema: z.ZodObject<{
110
+ outputPath: z.ZodString;
111
+ }, "strip", z.ZodTypeAny, {
112
+ outputPath: string;
113
+ }, {
114
+ outputPath: string;
115
+ }>;
116
+ };
117
+ };
118
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzD,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;EAE3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;EAE7B,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;EAExB,CAAC;AAIH,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BnB,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * FORGE MCP Tool Contract — v1
4
+ *
5
+ * All tool schemas are defined and locked here before server implementation.
6
+ * Do NOT change tool names or output shapes without a contract version bump.
7
+ *
8
+ * Adversarial review notes (stress-tested before locking):
9
+ * - Tool names prefixed with "nimai_" to avoid collisions with host tool namespaces
10
+ * - All inputs validated with zod to prevent runtime shape errors
11
+ * - Outputs are plain serialisable objects (no class instances, no Buffers)
12
+ * - No LLM calls inside any tool — tools return context/structure only
13
+ * - specPath / repoPath are absolute or relative to cwd; server does NOT resolve ~
14
+ * - outputPath for nimai_new: parent directory is created if missing; write errors surface as tool errors
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.TOOL_DESCRIPTORS = exports.ForgeNewInput = exports.ForgeValidateInput = exports.ForgeReviewInput = exports.ForgeSpecInput = void 0;
18
+ const zod_1 = require("zod");
19
+ // ─── Input Schemas ────────────────────────────────────────────────────────────
20
+ exports.ForgeSpecInput = zod_1.z.object({
21
+ repoPath: zod_1.z.string().describe('Absolute path to the repository root'),
22
+ request: zod_1.z.string().min(1).describe('The loose request to turn into a spec prompt'),
23
+ });
24
+ exports.ForgeReviewInput = zod_1.z.object({
25
+ specPath: zod_1.z.string().describe('Path to the approved spec markdown file'),
26
+ });
27
+ exports.ForgeValidateInput = zod_1.z.object({
28
+ specPath: zod_1.z.string().describe('Path to the spec markdown file to lint'),
29
+ });
30
+ exports.ForgeNewInput = zod_1.z.object({
31
+ outputPath: zod_1.z.string().describe('Path where the new spec file should be written'),
32
+ });
33
+ // ─── Tool Descriptors (used to register tools in the MCP server) ──────────────
34
+ exports.TOOL_DESCRIPTORS = {
35
+ nimai_spec: {
36
+ name: 'nimai_spec',
37
+ description: 'Returns a populated FORGE Self-Spec Agent prompt (Prompt 1) plus extracted repo context. ' +
38
+ 'The host model uses this bundle to generate a draft spec — no LLM call is made inside this tool.',
39
+ inputSchema: exports.ForgeSpecInput,
40
+ },
41
+ nimai_review: {
42
+ name: 'nimai_review',
43
+ description: 'Returns a populated FORGE Reviewer/Validator prompt (Prompt 2) derived from an approved spec file. ' +
44
+ 'The host model uses this to validate agent output against the spec.',
45
+ inputSchema: exports.ForgeReviewInput,
46
+ },
47
+ nimai_validate: {
48
+ name: 'nimai_validate',
49
+ description: 'Lints a spec file for unresolved placeholder fields (___), [NEEDS HUMAN INPUT] flags, ' +
50
+ 'and missing required sections. Returns structured issues and a pass/fail result.',
51
+ inputSchema: exports.ForgeValidateInput,
52
+ },
53
+ nimai_new: {
54
+ name: 'nimai_new',
55
+ description: 'Scaffolds a new FORGE spec file from the canonical template at the specified output path.',
56
+ inputSchema: exports.ForgeNewInput,
57
+ },
58
+ };
59
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,6BAAwB;AAGxB,iFAAiF;AAEpE,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IACrE,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACpF,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CACzE,CAAC,CAAC;AAEU,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;CACxE,CAAC,CAAC;AAEU,QAAA,aAAa,GAAG,OAAC,CAAC,MAAM,CAAC;IACpC,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;CAClF,CAAC,CAAC;AA6BH,iFAAiF;AAEpE,QAAA,gBAAgB,GAAG;IAC9B,UAAU,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,2FAA2F;YAC3F,kGAAkG;QACpG,WAAW,EAAE,sBAAc;KAC5B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,qGAAqG;YACrG,qEAAqE;QACvE,WAAW,EAAE,wBAAgB;KAC9B;IACD,cAAc,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,wFAAwF;YACxF,kFAAkF;QACpF,WAAW,EAAE,0BAAkB;KAChC;IACD,SAAS,EAAE;QACT,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,2FAA2F;QAC7F,WAAW,EAAE,qBAAa;KAC3B;CACO,CAAC"}
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ export { FORGE_ROOT } from './prompts';
3
+ export { createServer, startServer } from './server';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.startServer = exports.createServer = exports.FORGE_ROOT = void 0;
5
+ var prompts_1 = require("./prompts");
6
+ Object.defineProperty(exports, "FORGE_ROOT", { enumerable: true, get: function () { return prompts_1.FORGE_ROOT; } });
7
+ var server_1 = require("./server");
8
+ Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_1.createServer; } });
9
+ Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return server_1.startServer; } });
10
+ // Start server when run directly
11
+ if (require.main === module) {
12
+ const { startServer: start } = require('./server');
13
+ start().catch((err) => {
14
+ console.error('Nimai MCP server failed to start:', err);
15
+ process.exit(1);
16
+ });
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AACA,qCAAuC;AAA9B,qGAAA,UAAU,OAAA;AACnB,mCAAqD;AAA5C,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA;AAElC,iCAAiC;AACjC,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;QAC3B,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const FORGE_ROOT: string;
2
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,UAAU,QAAkB,CAAC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FORGE_ROOT = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Locate the FORGE docs root by walking up from __dirname until we find
41
+ * FORGE-quickref.md. Works regardless of where the package is installed.
42
+ */
43
+ function findForgeRoot() {
44
+ let dir = __dirname;
45
+ for (let i = 0; i < 10; i++) {
46
+ if (fs.existsSync(path.join(dir, 'FORGE-quickref.md')))
47
+ return dir;
48
+ const parent = path.dirname(dir);
49
+ if (parent === dir)
50
+ break;
51
+ dir = parent;
52
+ }
53
+ throw new Error('Cannot locate FORGE-quickref.md. Ensure the FORGE docs are present at the repo root.');
54
+ }
55
+ exports.FORGE_ROOT = findForgeRoot();
56
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B;;;GAGG;AACH,SAAS,aAAa;IACpB,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;AACJ,CAAC;AAEY,QAAA,UAAU,GAAG,aAAa,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ export declare function createServer(): Server;
3
+ export declare function startServer(): Promise<void>;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAYnE,wBAAgB,YAAY,IAAI,MAAM,CAkErC;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
package/dist/server.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createServer = createServer;
4
+ exports.startServer = startServer;
5
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
6
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
7
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
8
+ const contract_1 = require("./contract");
9
+ const spec_1 = require("./tools/spec");
10
+ const review_1 = require("./tools/review");
11
+ const validate_1 = require("./tools/validate");
12
+ const new_1 = require("./tools/new");
13
+ function createServer() {
14
+ const server = new index_js_1.Server({ name: 'nimai', version: '0.1.0' }, { capabilities: { tools: {} } });
15
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
16
+ tools: Object.values(contract_1.TOOL_DESCRIPTORS).map(descriptor => ({
17
+ name: descriptor.name,
18
+ description: descriptor.description,
19
+ inputSchema: {
20
+ type: 'object',
21
+ properties: Object.fromEntries(Object.entries(descriptor.inputSchema.shape).map(([key, schema]) => [
22
+ key,
23
+ { type: 'string', description: schema.description ?? '' },
24
+ ])),
25
+ required: Object.keys(descriptor.inputSchema.shape),
26
+ },
27
+ })),
28
+ }));
29
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
30
+ const { name, arguments: args } = request.params;
31
+ try {
32
+ let result;
33
+ switch (name) {
34
+ case 'nimai_spec': {
35
+ const input = contract_1.ForgeSpecInput.parse(args);
36
+ result = await (0, spec_1.toolSpec)(input);
37
+ break;
38
+ }
39
+ case 'nimai_review': {
40
+ const input = contract_1.ForgeReviewInput.parse(args);
41
+ result = await (0, review_1.toolReview)(input);
42
+ break;
43
+ }
44
+ case 'nimai_validate': {
45
+ const input = contract_1.ForgeValidateInput.parse(args);
46
+ result = await (0, validate_1.toolValidate)(input);
47
+ break;
48
+ }
49
+ case 'nimai_new': {
50
+ const input = contract_1.ForgeNewInput.parse(args);
51
+ result = await (0, new_1.toolNew)(input);
52
+ break;
53
+ }
54
+ default:
55
+ throw new Error(`Unknown tool: ${name}`);
56
+ }
57
+ return {
58
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
59
+ };
60
+ }
61
+ catch (err) {
62
+ return {
63
+ content: [{ type: 'text', text: `Error: ${err.message}` }],
64
+ isError: true,
65
+ };
66
+ }
67
+ });
68
+ return server;
69
+ }
70
+ async function startServer() {
71
+ const server = createServer();
72
+ const transport = new stdio_js_1.StdioServerTransport();
73
+ await server.connect(transport);
74
+ }
75
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ForgeNewInput, ForgeNewOutput } from '../contract';
2
+ import { z } from 'zod';
3
+ export declare function toolNew(input: z.infer<typeof ForgeNewInput>): Promise<ForgeNewOutput>;
4
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/tools/new.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAsB,OAAO,CAC3B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,GACnC,OAAO,CAAC,cAAc,CAAC,CAYzB"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.toolNew = toolNew;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const nimai_core_1 = require("nimai-core");
40
+ const prompts_1 = require("../prompts");
41
+ async function toolNew(input) {
42
+ const templatePath = path.join(prompts_1.FORGE_ROOT, 'FORGE-spec-template.md');
43
+ const template = (0, nimai_core_1.loadTemplate)(templatePath);
44
+ const outputPath = path.resolve(input.outputPath);
45
+ const dir = path.dirname(outputPath);
46
+ if (!fs.existsSync(dir)) {
47
+ fs.mkdirSync(dir, { recursive: true });
48
+ }
49
+ fs.writeFileSync(outputPath, template.raw, 'utf-8');
50
+ return { path: outputPath, content: template.raw };
51
+ }
52
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/tools/new.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,0BAcC;AArBD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA0C;AAE1C,wCAAwC;AAGjC,KAAK,UAAU,OAAO,CAC3B,KAAoC;IAEpC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,oBAAU,EAAE,wBAAwB,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,IAAA,yBAAY,EAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAElD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ForgeReviewInput, ForgeReviewOutput } from '../contract';
2
+ import { z } from 'zod';
3
+ export declare function toolReview(input: z.infer<typeof ForgeReviewInput>): Promise<ForgeReviewOutput>;
4
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/tools/review.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAsB,UAAU,CAC9B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GACtC,OAAO,CAAC,iBAAiB,CAAC,CAW5B"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.toolReview = toolReview;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const nimai_core_1 = require("nimai-core");
40
+ async function toolReview(input) {
41
+ const specPath = path.resolve(input.specPath);
42
+ let specContent;
43
+ try {
44
+ specContent = fs.readFileSync(specPath, 'utf-8');
45
+ }
46
+ catch (err) {
47
+ throw new Error(`Cannot read spec at "${specPath}": ${err.message}`);
48
+ }
49
+ return { reviewerPrompt: (0, nimai_core_1.buildPrompt2)(specContent) };
50
+ }
51
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/tools/review.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,gCAaC;AAnBD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA0C;AAInC,KAAK,UAAU,UAAU,CAC9B,KAAuC;IAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,wBAAwB,QAAQ,MAAO,GAA6B,CAAC,OAAO,EAAE,CAC/E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,IAAA,yBAAY,EAAC,WAAW,CAAC,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ForgeSpecInput, ForgeSpecOutput } from '../contract';
2
+ import { z } from 'zod';
3
+ export declare function toolSpec(input: z.infer<typeof ForgeSpecInput>): Promise<ForgeSpecOutput>;
4
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/tools/spec.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,GACpC,OAAO,CAAC,eAAe,CAAC,CAW1B"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.toolSpec = toolSpec;
37
+ const path = __importStar(require("path"));
38
+ const nimai_core_1 = require("nimai-core");
39
+ async function toolSpec(input) {
40
+ const repoPath = path.resolve(input.repoPath);
41
+ const context = (0, nimai_core_1.extractContext)(repoPath, input.request);
42
+ const contextSummary = context
43
+ .map(item => `[${item.file}]\n${item.snippet}`)
44
+ .join('\n\n---\n\n');
45
+ const prompt = (0, nimai_core_1.buildPrompt1)(input.request, contextSummary);
46
+ return { prompt, context };
47
+ }
48
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/tools/spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,4BAaC;AAlBD,2CAA6B;AAC7B,2CAA0D;AAInD,KAAK,UAAU,QAAQ,CAC5B,KAAqC;IAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAA,2BAAc,EAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAExD,MAAM,cAAc,GAAG,OAAO;SAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;SAC9C,IAAI,CAAC,aAAa,CAAC,CAAC;IAEvB,MAAM,MAAM,GAAG,IAAA,yBAAY,EAAC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAE3D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ForgeValidateInput, ForgeValidateOutput } from '../contract';
2
+ import { z } from 'zod';
3
+ export declare function toolValidate(input: z.infer<typeof ForgeValidateInput>): Promise<ForgeValidateOutput>;
4
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wBAAsB,YAAY,CAChC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,GACxC,OAAO,CAAC,mBAAmB,CAAC,CAG9B"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toolValidate = toolValidate;
4
+ const nimai_core_1 = require("nimai-core");
5
+ async function toolValidate(input) {
6
+ const issues = (0, nimai_core_1.lintSpec)(input.specPath);
7
+ return { issues, passed: issues.length === 0 };
8
+ }
9
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":";;AAIA,oCAKC;AATD,2CAAsC;AAI/B,KAAK,UAAU,YAAY,CAChC,KAAyC;IAEzC,MAAM,MAAM,GAAG,IAAA,qBAAQ,EAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AACjD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "nimai-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Nimai MCP server — exposes nimai_spec, nimai_review, nimai_validate, nimai_new as tools. No internal LLM calls.",
5
+ "keywords": ["nimai", "forge", "mcp", "model-context-protocol", "ai", "llm", "specification", "claude", "codex"],
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/Balagopalaji/nimai.git",
10
+ "directory": "packages/mcp"
11
+ },
12
+ "files": ["dist/"],
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "bin": {
16
+ "nimai-mcp": "dist/index.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "test": "vitest run",
21
+ "dev": "tsc --watch",
22
+ "clean": "rm -rf dist"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.0.0",
26
+ "typescript": "^5.4.5",
27
+ "vitest": "^1.6.0"
28
+ },
29
+ "dependencies": {
30
+ "nimai-core": "workspace:*",
31
+ "@modelcontextprotocol/sdk": "^1.0.0",
32
+ "zod": "^3.23.8"
33
+ }
34
+ }