@aiready/mcp-server 0.2.8 → 0.4.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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/mcp-server@0.2.8 build /Users/pengcao/projects/aiready/packages/mcp-server
3
+ > @aiready/mcp-server@0.3.0 build /Users/pengcao/projects/aiready/packages/mcp-server
4
4
  > tsup src/index.ts --format esm --clean --dts
5
5
 
6
6
  CLI Building entry: src/index.ts
@@ -10,8 +10,8 @@
10
10
  CLI Target: node20
11
11
  CLI Cleaning output folder
12
12
  ESM Build start
13
- ESM dist/index.js 7.52 KB
14
- ESM ⚡️ Build success in 18ms
13
+ ESM dist/index.js 8.93 KB
14
+ ESM ⚡️ Build success in 42ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 1999ms
17
- DTS dist/index.d.ts 461.00 B
16
+ DTS ⚡️ Build success in 4156ms
17
+ DTS dist/index.d.ts 482.00 B
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/mcp-server@0.2.8 format-check /Users/pengcao/projects/aiready/packages/mcp-server
3
+ > @aiready/mcp-server@0.3.0 format-check /Users/pengcao/projects/aiready/packages/mcp-server
4
4
  > prettier --check . --ignore-path ../../.prettierignore
5
5
 
6
6
  Checking formatting...
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @aiready/mcp-server@0.2.8 lint /Users/pengcao/projects/aiready/packages/mcp-server
3
+ > @aiready/mcp-server@0.3.0 lint /Users/pengcao/projects/aiready/packages/mcp-server
4
4
  > eslint src
5
5
 
@@ -1,22 +1,20 @@
1
-
2
- 
3
- > @aiready/mcp-server@0.2.7 test /Users/pengcao/projects/aiready/packages/mcp-server
4
- > vitest run
5
-
6
- [?25l
7
-  RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/mcp-server
8
-
9
- AIReady MCP Server started
10
- [MCP] Dynamically loading @aiready/pattern-detect for tool pattern-detect
11
- [MCP] Executing pattern-detect on /Users/pengcao/projects/aiready/packages/core
12
- [MCP] Dynamically loading @aiready/non-existent-tool for tool non-existent-tool
13
- [MCP] Failed to load tool package @aiready/non-existent-tool: Cannot find package '@aiready/non-existent-tool' imported from /Users/pengcao/projects/aiready/packages/mcp-server/dist/index.js
14
- ✓ src/__tests__/server.test.ts (5 tests) 902ms
15
- ✓ should execute pattern-detect and return results  472ms
16
-
17
-  Test Files  1 passed (1)
18
-  Tests  5 passed (5)
19
-  Start at  00:14:12
20
-  Duration  1.20s (transform 68ms, setup 0ms, import 112ms, tests 902ms, environment 0ms)
21
-
22
- [?25h
1
+
2
+ > @aiready/mcp-server@0.2.10 test /Users/pengcao/projects/aiready/packages/mcp-server
3
+ > vitest run
4
+
5
+
6
+  RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/mcp-server
7
+
8
+ AIReady MCP Server started
9
+ [MCP] Dynamically loading @aiready/pattern-detect for tool pattern-detect
10
+ [MCP] Executing pattern-detect on /Users/pengcao/projects/aiready/packages/core
11
+ [MCP] Dynamically loading @aiready/non-existent-tool for tool non-existent-tool
12
+ [MCP] Failed to load tool package @aiready/non-existent-tool: Cannot find package '@aiready/non-existent-tool' imported from /Users/pengcao/projects/aiready/packages/mcp-server/dist/index.js
13
+ ✓ src/__tests__/server.test.ts (5 tests) 1147ms
14
+ ✓ should execute pattern-detect and return results  783ms
15
+
16
+  Test Files  1 passed (1)
17
+  Tests  5 passed (5)
18
+  Start at  14:45:23
19
+  Duration  1.44s (transform 45ms, setup 0ms, import 89ms, tests 1.15s, environment 0ms)
20
+
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @aiready/mcp-server@0.2.8 type-check /Users/pengcao/projects/aiready/packages/mcp-server
3
+ > @aiready/mcp-server@0.3.0 type-check /Users/pengcao/projects/aiready/packages/mcp-server
4
4
  > tsc --noEmit
5
5
 
package/README.md CHANGED
@@ -48,7 +48,7 @@ To use the AIReady MCP server in the Claude Desktop app, add the following confi
48
48
  If you prefer running MCP servers in isolated environments, you can use our Docker image:
49
49
 
50
50
  ```bash
51
- docker run -i --rm ghcr.io/caopengau/aiready-mcp-server
51
+ docker run -i --rm ghcr.io/getaiready/aiready-mcp-server
52
52
  ```
53
53
 
54
54
  _(Note: Docker image distribution is currently being set up. Use the command above once published.)_
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
5
  */
6
6
  declare class AIReadyMcpServer {
7
7
  private server;
8
+ private version;
8
9
  constructor();
9
10
  private handleRemediation;
10
11
  private setupHandlers;
package/dist/index.js CHANGED
@@ -8,6 +8,18 @@ import {
8
8
  ListToolsRequestSchema
9
9
  } from "@modelcontextprotocol/sdk/types.js";
10
10
  import { ToolRegistry, ToolName } from "@aiready/core";
11
+ import { z } from "zod";
12
+ var AnalysisArgsSchema = z.object({
13
+ path: z.string().describe("Path to the directory to analyze"),
14
+ summary_only: z.boolean().optional().describe(
15
+ "If true, returns only the summary and skips the detailed issue list. Best for large projects to save context."
16
+ )
17
+ });
18
+ var RemediationArgsSchema = z.object({
19
+ issue_id: z.string().describe("The unique ID of the issue to fix"),
20
+ file_path: z.string().describe("The path to the file containing the issue"),
21
+ context: z.string().describe("The content of the file or surrounding code")
22
+ });
11
23
  var TOOL_PACKAGE_MAP = {
12
24
  [ToolName.PatternDetect]: "@aiready/pattern-detect",
13
25
  [ToolName.ContextAnalyzer]: "@aiready/context-analyzer",
@@ -32,10 +44,11 @@ var TOOL_PACKAGE_MAP = {
32
44
  };
33
45
  var AIReadyMcpServer = class {
34
46
  constructor() {
47
+ this.version = "0.2.10";
35
48
  this.server = new Server(
36
49
  {
37
50
  name: "aiready-server",
38
- version: "0.1.0"
51
+ version: this.version
39
52
  },
40
53
  {
41
54
  capabilities: {
@@ -117,55 +130,69 @@ ${data.rationale}`
117
130
  ToolName.DependencyHealth,
118
131
  ToolName.ChangeAmplification
119
132
  ];
120
- return {
121
- tools: [
122
- ...toolsToAdvertise.map((id) => ({
123
- name: id,
124
- description: `Scan the directory for ${id} issues to improve AI-readiness.`,
125
- inputSchema: {
126
- type: "object",
127
- properties: {
128
- path: {
129
- type: "string",
130
- description: "Path to the directory to analyze"
131
- }
133
+ const tools = [
134
+ ...toolsToAdvertise.map((id) => ({
135
+ name: id,
136
+ description: `Scan the directory for ${id} issues to improve AI-readiness.`,
137
+ inputSchema: {
138
+ type: "object",
139
+ properties: {
140
+ path: {
141
+ type: "string",
142
+ description: "Path to the directory to analyze"
132
143
  },
133
- required: ["path"]
134
- }
135
- })),
136
- {
137
- name: "get_remediation_diff",
138
- description: "Get a precise code diff to fix a specific AI-readiness issue (Requires AIReady API Key).",
139
- inputSchema: {
140
- type: "object",
141
- properties: {
142
- issue_id: {
143
- type: "string",
144
- description: "The unique ID of the issue to fix (from a scan)."
145
- },
146
- file_path: {
147
- type: "string",
148
- description: "The path to the file containing the issue."
149
- },
150
- context: {
151
- type: "string",
152
- description: "The content of the file or surrounding code."
153
- }
144
+ summary_only: {
145
+ type: "boolean",
146
+ description: "If true, returns only the summary and skips the detailed issue list. Best for large projects to save context."
147
+ }
148
+ },
149
+ required: ["path"]
150
+ }
151
+ })),
152
+ {
153
+ name: "get_remediation_diff",
154
+ description: "Get a precise code diff to fix a specific AI-readiness issue (Requires AIReady API Key).",
155
+ inputSchema: {
156
+ type: "object",
157
+ properties: {
158
+ issue_id: {
159
+ type: "string",
160
+ description: "The unique ID of the issue to fix (from a scan)."
154
161
  },
155
- required: ["issue_id", "file_path", "context"]
156
- }
162
+ file_path: {
163
+ type: "string",
164
+ description: "The path to the file containing the issue."
165
+ },
166
+ context: {
167
+ type: "string",
168
+ description: "The content of the file or surrounding code."
169
+ }
170
+ },
171
+ required: ["issue_id", "file_path", "context"]
157
172
  }
158
- ]
159
- };
173
+ }
174
+ ];
175
+ return { tools };
160
176
  });
161
177
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
162
178
  const { name, arguments: args } = request.params;
163
179
  try {
164
180
  if (name === "get_remediation_diff") {
165
- return await this.handleRemediation(
166
- args
181
+ const parsedArgs2 = RemediationArgsSchema.safeParse(args);
182
+ if (!parsedArgs2.success) {
183
+ throw new Error(
184
+ `Invalid arguments for ${name}: ${parsedArgs2.error.message}`
185
+ );
186
+ }
187
+ return await this.handleRemediation(parsedArgs2.data);
188
+ }
189
+ const parsedArgs = AnalysisArgsSchema.safeParse(args);
190
+ if (!parsedArgs.success) {
191
+ throw new Error(
192
+ `Invalid arguments for ${name}: ${parsedArgs.error.message}`
167
193
  );
168
194
  }
195
+ const { path: rootDir, summary_only } = parsedArgs.data;
169
196
  let provider = ToolRegistry.find(name);
170
197
  if (!provider) {
171
198
  const packageName = TOOL_PACKAGE_MAP[name] ?? (name.startsWith("@aiready/") ? name : `@aiready/${name}`);
@@ -190,18 +217,22 @@ ${data.rationale}`
190
217
  if (!provider) {
191
218
  throw new Error(`Tool ${name} not found after attempting to load`);
192
219
  }
193
- if (!args || typeof args.path !== "string") {
194
- throw new Error("Missing required argument: path");
195
- }
196
- console.error(`[MCP] Executing ${name} on ${args.path}`);
220
+ console.error(
221
+ `[MCP] Executing ${name} on ${rootDir}${summary_only ? " (summary only)" : ""}`
222
+ );
197
223
  const results = await provider.analyze({
198
- rootDir: args.path
224
+ rootDir
199
225
  });
226
+ const responseData = summary_only ? {
227
+ summary: results.summary,
228
+ metadata: results.metadata,
229
+ notice: "Detailed issues were omitted (summary_only: true). Run without summary_only for full details."
230
+ } : results;
200
231
  return {
201
232
  content: [
202
233
  {
203
234
  type: "text",
204
- text: JSON.stringify(results, null, 2)
235
+ text: JSON.stringify(responseData, null, 2)
205
236
  }
206
237
  ]
207
238
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/mcp-server",
3
- "version": "0.2.8",
3
+ "version": "0.4.0",
4
4
  "description": "The AIReady Model Context Protocol (MCP) Server for Agentic Readiness. Optimize codebases for AI agents like Cursor, Windsurf, and Claude directly via MCP.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,10 +13,16 @@
13
13
  "@modelcontextprotocol/sdk": "^1.0.0",
14
14
  "chalk": "^5.3.0",
15
15
  "zod": "^4.3.6",
16
- "@aiready/consistency": "0.21.9",
17
- "@aiready/core": "0.24.9",
18
- "@aiready/context-analyzer": "0.22.9",
19
- "@aiready/pattern-detect": "0.17.9"
16
+ "@aiready/agent-grounding": "0.14.15",
17
+ "@aiready/ai-signal-clarity": "0.14.17",
18
+ "@aiready/change-amplification": "0.14.15",
19
+ "@aiready/context-analyzer": "0.22.15",
20
+ "@aiready/consistency": "0.21.15",
21
+ "@aiready/core": "0.24.16",
22
+ "@aiready/deps": "0.14.15",
23
+ "@aiready/doc-drift": "0.14.15",
24
+ "@aiready/testability": "0.7.16",
25
+ "@aiready/pattern-detect": "0.17.15"
20
26
  },
21
27
  "devDependencies": {
22
28
  "@types/node": "^24.0.0",
@@ -47,7 +47,7 @@ describe('AIReady MCP Server Integration', () => {
47
47
  expect(toolNames).toContain('naming-consistency');
48
48
  });
49
49
 
50
- it('should expose correct input schema for tools', async () => {
50
+ it('should expose correct input schema for tools including summary_only', async () => {
51
51
  const result = await client.listTools();
52
52
 
53
53
  const patternDetect = result.tools.find((t) => t.name === 'pattern-detect');
@@ -55,11 +55,31 @@ describe('AIReady MCP Server Integration', () => {
55
55
  type: 'object',
56
56
  properties: {
57
57
  path: { type: 'string' },
58
+ summary_only: { type: 'boolean' },
58
59
  },
59
60
  required: ['path'],
60
61
  });
61
62
  });
62
63
 
64
+ it('should execute pattern-detect with summary_only: true and return only summary', async () => {
65
+ const result = await client.callTool({
66
+ name: 'pattern-detect',
67
+ arguments: {
68
+ path: path.resolve(__dirname, '../../../core'),
69
+ summary_only: true,
70
+ },
71
+ });
72
+ const typedResult = result as ToolCallResponse;
73
+
74
+ expect(typedResult.content).toBeDefined();
75
+ const data = JSON.parse((typedResult.content[0] as any).text);
76
+
77
+ expect(data).toHaveProperty('summary');
78
+ expect(data).toHaveProperty('metadata');
79
+ expect(data).toHaveProperty('notice');
80
+ expect(data).not.toHaveProperty('results');
81
+ }, 20000);
82
+
63
83
  it('should execute pattern-detect and return results', async () => {
64
84
  const result = await client.callTool({
65
85
  name: 'pattern-detect',
@@ -104,7 +124,7 @@ describe('AIReady MCP Server Integration', () => {
104
124
  expect(typedResult.isError).toBe(true);
105
125
  expect(typedResult.content[0].type).toBe('text');
106
126
  expect((typedResult.content[0] as any).text).toContain(
107
- 'Missing required argument: path'
127
+ 'Invalid arguments for pattern-detect'
108
128
  );
109
129
  });
110
130
  });
package/src/index.ts CHANGED
@@ -5,6 +5,26 @@ import {
5
5
  ListToolsRequestSchema,
6
6
  } from '@modelcontextprotocol/sdk/types.js';
7
7
  import { ToolRegistry, ToolName } from '@aiready/core';
8
+ import { z } from 'zod';
9
+
10
+ /**
11
+ * Zod schemas for tool arguments
12
+ */
13
+ const AnalysisArgsSchema = z.object({
14
+ path: z.string().describe('Path to the directory to analyze'),
15
+ summary_only: z
16
+ .boolean()
17
+ .optional()
18
+ .describe(
19
+ 'If true, returns only the summary and skips the detailed issue list. Best for large projects to save context.'
20
+ ),
21
+ });
22
+
23
+ const RemediationArgsSchema = z.object({
24
+ issue_id: z.string().describe('The unique ID of the issue to fix'),
25
+ file_path: z.string().describe('The path to the file containing the issue'),
26
+ context: z.string().describe('The content of the file or surrounding code'),
27
+ });
8
28
 
9
29
  /**
10
30
  * Mapping between tool names and @aiready/ package names.
@@ -38,12 +58,13 @@ const TOOL_PACKAGE_MAP: Record<string, string> = {
38
58
  */
39
59
  export class AIReadyMcpServer {
40
60
  private server: Server;
61
+ private version: string = '0.2.10';
41
62
 
42
63
  constructor() {
43
64
  this.server = new Server(
44
65
  {
45
66
  name: 'aiready-server',
46
- version: '0.1.0',
67
+ version: this.version,
47
68
  },
48
69
  {
49
70
  capabilities: {
@@ -59,11 +80,7 @@ export class AIReadyMcpServer {
59
80
  };
60
81
  }
61
82
 
62
- private async handleRemediation(args: {
63
- issue_id: string;
64
- file_path: string;
65
- context: string;
66
- }) {
83
+ private async handleRemediation(args: z.infer<typeof RemediationArgsSchema>) {
67
84
  const apiKey = process.env.AIREADY_API_KEY;
68
85
  const serverUrl =
69
86
  process.env.AIREADY_PLATFORM_URL || 'https://platform.getaiready.dev';
@@ -140,48 +157,52 @@ export class AIReadyMcpServer {
140
157
  ToolName.ChangeAmplification,
141
158
  ];
142
159
 
143
- return {
144
- tools: [
145
- ...toolsToAdvertise.map((id) => ({
146
- name: id,
147
- description: `Scan the directory for ${id} issues to improve AI-readiness.`,
148
- inputSchema: {
149
- type: 'object',
150
- properties: {
151
- path: {
152
- type: 'string',
153
- description: 'Path to the directory to analyze',
154
- },
160
+ const tools: any[] = [
161
+ ...toolsToAdvertise.map((id) => ({
162
+ name: id,
163
+ description: `Scan the directory for ${id} issues to improve AI-readiness.`,
164
+ inputSchema: {
165
+ type: 'object',
166
+ properties: {
167
+ path: {
168
+ type: 'string',
169
+ description: 'Path to the directory to analyze',
170
+ },
171
+ summary_only: {
172
+ type: 'boolean',
173
+ description:
174
+ 'If true, returns only the summary and skips the detailed issue list. Best for large projects to save context.',
155
175
  },
156
- required: ['path'],
157
176
  },
158
- })),
159
- {
160
- name: 'get_remediation_diff',
161
- description:
162
- 'Get a precise code diff to fix a specific AI-readiness issue (Requires AIReady API Key).',
163
- inputSchema: {
164
- type: 'object',
165
- properties: {
166
- issue_id: {
167
- type: 'string',
168
- description:
169
- 'The unique ID of the issue to fix (from a scan).',
170
- },
171
- file_path: {
172
- type: 'string',
173
- description: 'The path to the file containing the issue.',
174
- },
175
- context: {
176
- type: 'string',
177
- description: 'The content of the file or surrounding code.',
178
- },
177
+ required: ['path'],
178
+ },
179
+ })),
180
+ {
181
+ name: 'get_remediation_diff',
182
+ description:
183
+ 'Get a precise code diff to fix a specific AI-readiness issue (Requires AIReady API Key).',
184
+ inputSchema: {
185
+ type: 'object',
186
+ properties: {
187
+ issue_id: {
188
+ type: 'string',
189
+ description: 'The unique ID of the issue to fix (from a scan).',
190
+ },
191
+ file_path: {
192
+ type: 'string',
193
+ description: 'The path to the file containing the issue.',
194
+ },
195
+ context: {
196
+ type: 'string',
197
+ description: 'The content of the file or surrounding code.',
179
198
  },
180
- required: ['issue_id', 'file_path', 'context'],
181
199
  },
200
+ required: ['issue_id', 'file_path', 'context'],
182
201
  },
183
- ],
184
- };
202
+ },
203
+ ];
204
+
205
+ return { tools };
185
206
  });
186
207
 
187
208
  // Handle tool execution
@@ -190,14 +211,22 @@ export class AIReadyMcpServer {
190
211
 
191
212
  try {
192
213
  if (name === 'get_remediation_diff') {
193
- return await this.handleRemediation(
194
- args as {
195
- issue_id: string;
196
- file_path: string;
197
- context: string;
198
- }
214
+ const parsedArgs = RemediationArgsSchema.safeParse(args);
215
+ if (!parsedArgs.success) {
216
+ throw new Error(
217
+ `Invalid arguments for ${name}: ${parsedArgs.error.message}`
218
+ );
219
+ }
220
+ return await this.handleRemediation(parsedArgs.data);
221
+ }
222
+
223
+ const parsedArgs = AnalysisArgsSchema.safeParse(args);
224
+ if (!parsedArgs.success) {
225
+ throw new Error(
226
+ `Invalid arguments for ${name}: ${parsedArgs.error.message}`
199
227
  );
200
228
  }
229
+ const { path: rootDir, summary_only } = parsedArgs.data;
201
230
 
202
231
  let provider = ToolRegistry.find(name);
203
232
 
@@ -233,22 +262,31 @@ export class AIReadyMcpServer {
233
262
  throw new Error(`Tool ${name} not found after attempting to load`);
234
263
  }
235
264
 
236
- if (!args || typeof args.path !== 'string') {
237
- throw new Error('Missing required argument: path');
238
- }
239
-
240
- console.error(`[MCP] Executing ${name} on ${args.path}`);
265
+ console.error(
266
+ `[MCP] Executing ${name} on ${rootDir}${
267
+ summary_only ? ' (summary only)' : ''
268
+ }`
269
+ );
241
270
 
242
271
  const results = await provider.analyze({
243
- rootDir: args.path,
272
+ rootDir,
244
273
  });
245
274
 
246
275
  // Format results for the agent
276
+ const responseData = summary_only
277
+ ? {
278
+ summary: results.summary,
279
+ metadata: results.metadata,
280
+ notice:
281
+ 'Detailed issues were omitted (summary_only: true). Run without summary_only for full details.',
282
+ }
283
+ : results;
284
+
247
285
  return {
248
286
  content: [
249
287
  {
250
288
  type: 'text',
251
- text: JSON.stringify(results, null, 2),
289
+ text: JSON.stringify(responseData, null, 2),
252
290
  },
253
291
  ],
254
292
  };