@aiready/mcp-server 0.2.5 → 0.2.7
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/.turbo/turbo-build.log +17 -16
- package/.turbo/turbo-format-check.log +7 -0
- package/.turbo/turbo-lint.log +5 -4
- package/.turbo/turbo-test.log +22 -8
- package/.turbo/turbo-type-check.log +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +103 -17
- package/package.json +8 -6
- package/src/index.ts +122 -17
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
DTS
|
|
16
|
-
DTS
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @aiready/mcp-server@0.2.7 build /Users/pengcao/projects/aiready/packages/mcp-server
|
|
4
|
+
> tsup src/index.ts --format esm --clean --dts
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.1
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/pengcao/projects/aiready/packages/mcp-server/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: node20
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[32mESM[39m [1mdist/index.js [22m[32m7.52 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 17ms
|
|
15
|
+
DTS Build start
|
|
16
|
+
DTS ⚡️ Build success in 950ms
|
|
17
|
+
DTS dist/index.d.ts 461.00 B
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @aiready/mcp-server@0.2.7 format-check /Users/pengcao/projects/aiready/packages/mcp-server
|
|
4
|
+
> prettier --check . --ignore-path ../../.prettierignore
|
|
5
|
+
|
|
6
|
+
Checking formatting...
|
|
7
|
+
.env.smithery[2K[1G.well-known/mcp/server-card.json[2K[1Gpackage.json[2K[1GREADME.md[2K[1Gsmithery.yaml[2K[1Gsrc/__tests__/server.test.ts[2K[1Gsrc/index.ts[2K[1Gtest-mcp.ts[2K[1Gtsconfig.json[2K[1Gtsup.config.ts[2K[1GAll matched files use Prettier code style!
|
package/.turbo/turbo-lint.log
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @aiready/mcp-server@0.2.7 lint /Users/pengcao/projects/aiready/packages/mcp-server
|
|
4
|
+
> eslint src
|
|
5
|
+
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @aiready/mcp-server@0.2.6 test /Users/pengcao/projects/aiready/packages/mcp-server
|
|
4
|
+
> vitest run
|
|
5
|
+
|
|
6
|
+
[?25l
|
|
7
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/pengcao/projects/aiready/packages/mcp-server[39m
|
|
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
|
+
[32m✓[39m src/__tests__/server.test.ts [2m([22m[2m5 tests[22m[2m)[22m[33m 622[2mms[22m[39m
|
|
15
|
+
[33m[2m✓[22m[39m should execute pattern-detect and return results [33m 351[2mms[22m[39m
|
|
16
|
+
|
|
17
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
18
|
+
[2m Tests [22m [1m[32m5 passed[39m[22m[90m (5)[39m
|
|
19
|
+
[2m Start at [22m 00:08:39
|
|
20
|
+
[2m Duration [22m 747ms[2m (transform 23ms, setup 0ms, import 41ms, tests 622ms, environment 0ms)[22m
|
|
21
|
+
|
|
22
|
+
[?25h
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -48,6 +48,62 @@ var AIReadyMcpServer = class {
|
|
|
48
48
|
console.error("[MCP Error]", error);
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
+
async handleRemediation(args) {
|
|
52
|
+
const apiKey = process.env.AIREADY_API_KEY;
|
|
53
|
+
const serverUrl = process.env.AIREADY_PLATFORM_URL || "https://platform.getaiready.dev";
|
|
54
|
+
if (!apiKey) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
"AIREADY_API_KEY is not set. Remediation requires an active subscription."
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
console.error(`[MCP] Requesting remediation for ${args.issue_id}...`);
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(`${serverUrl}/api/v1/remediate`, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
"X-API-KEY": apiKey
|
|
66
|
+
},
|
|
67
|
+
body: JSON.stringify({
|
|
68
|
+
issueId: args.issue_id,
|
|
69
|
+
filePath: args.file_path,
|
|
70
|
+
context: args.context,
|
|
71
|
+
agent: "mcp-server"
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
const errorData = await response.json().catch(() => ({}));
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Platform Error: ${errorData.message || response.statusText}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
const data = await response.json();
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: `Recommended Fix (Diff):
|
|
86
|
+
|
|
87
|
+
${data.diff}
|
|
88
|
+
|
|
89
|
+
Rationale:
|
|
90
|
+
${data.rationale}`
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
96
|
+
return {
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
99
|
+
type: "text",
|
|
100
|
+
text: `Failed to get remediation: ${errorMessage}. Please visit the dashboard to fix manually.`
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
isError: true
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
51
107
|
setupHandlers() {
|
|
52
108
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
53
109
|
const toolsToAdvertise = [
|
|
@@ -62,26 +118,54 @@ var AIReadyMcpServer = class {
|
|
|
62
118
|
ToolName.ChangeAmplification
|
|
63
119
|
];
|
|
64
120
|
return {
|
|
65
|
-
tools:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
+
}
|
|
132
|
+
},
|
|
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
|
+
}
|
|
154
|
+
},
|
|
155
|
+
required: ["issue_id", "file_path", "context"]
|
|
156
|
+
}
|
|
78
157
|
}
|
|
79
|
-
|
|
158
|
+
]
|
|
80
159
|
};
|
|
81
160
|
});
|
|
82
161
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
83
162
|
const { name, arguments: args } = request.params;
|
|
84
163
|
try {
|
|
164
|
+
if (name === "get_remediation_diff") {
|
|
165
|
+
return await this.handleRemediation(
|
|
166
|
+
args
|
|
167
|
+
);
|
|
168
|
+
}
|
|
85
169
|
let provider = ToolRegistry.find(name);
|
|
86
170
|
if (!provider) {
|
|
87
171
|
const packageName = TOOL_PACKAGE_MAP[name] ?? (name.startsWith("@aiready/") ? name : `@aiready/${name}`);
|
|
@@ -92,11 +176,12 @@ var AIReadyMcpServer = class {
|
|
|
92
176
|
await import(packageName);
|
|
93
177
|
provider = ToolRegistry.find(name);
|
|
94
178
|
} catch (importError) {
|
|
179
|
+
const importErrorMessage = importError instanceof Error ? importError.message : String(importError);
|
|
95
180
|
console.error(
|
|
96
|
-
`[MCP] Failed to load tool package ${packageName}: ${
|
|
181
|
+
`[MCP] Failed to load tool package ${packageName}: ${importErrorMessage}`
|
|
97
182
|
);
|
|
98
183
|
const error = new Error(
|
|
99
|
-
`Tool ${name} not found and failed to load package ${packageName}: ${
|
|
184
|
+
`Tool ${name} not found and failed to load package ${packageName}: ${importErrorMessage}`
|
|
100
185
|
);
|
|
101
186
|
error.cause = importError;
|
|
102
187
|
throw error;
|
|
@@ -121,11 +206,12 @@ var AIReadyMcpServer = class {
|
|
|
121
206
|
]
|
|
122
207
|
};
|
|
123
208
|
} catch (error) {
|
|
209
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
124
210
|
return {
|
|
125
211
|
content: [
|
|
126
212
|
{
|
|
127
213
|
type: "text",
|
|
128
|
-
text: `Error: ${
|
|
214
|
+
text: `Error: ${errorMessage}`
|
|
129
215
|
}
|
|
130
216
|
],
|
|
131
217
|
isError: true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
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,10 @@
|
|
|
13
13
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
14
14
|
"chalk": "^5.3.0",
|
|
15
15
|
"zod": "^4.3.6",
|
|
16
|
-
"@aiready/consistency": "0.21.
|
|
17
|
-
"@aiready/
|
|
18
|
-
"@aiready/
|
|
19
|
-
"@aiready/
|
|
16
|
+
"@aiready/consistency": "0.21.8",
|
|
17
|
+
"@aiready/pattern-detect": "0.17.8",
|
|
18
|
+
"@aiready/context-analyzer": "0.22.8",
|
|
19
|
+
"@aiready/core": "0.24.8"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^24.0.0",
|
|
@@ -47,6 +47,8 @@
|
|
|
47
47
|
"test": "vitest run",
|
|
48
48
|
"lint": "eslint src",
|
|
49
49
|
"clean": "rm -rf dist",
|
|
50
|
-
"start": "node dist/index.js"
|
|
50
|
+
"start": "node dist/index.js",
|
|
51
|
+
"type-check": "tsc --noEmit",
|
|
52
|
+
"format-check": "prettier --check . --ignore-path ../../.prettierignore"
|
|
51
53
|
}
|
|
52
54
|
}
|
package/src/index.ts
CHANGED
|
@@ -59,6 +59,70 @@ export class AIReadyMcpServer {
|
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
private async handleRemediation(args: {
|
|
63
|
+
issue_id: string;
|
|
64
|
+
file_path: string;
|
|
65
|
+
context: string;
|
|
66
|
+
}) {
|
|
67
|
+
const apiKey = process.env.AIREADY_API_KEY;
|
|
68
|
+
const serverUrl =
|
|
69
|
+
process.env.AIREADY_PLATFORM_URL || 'https://platform.getaiready.dev';
|
|
70
|
+
|
|
71
|
+
if (!apiKey) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
'AIREADY_API_KEY is not set. Remediation requires an active subscription.'
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.error(`[MCP] Requesting remediation for ${args.issue_id}...`);
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(`${serverUrl}/api/v1/remediate`, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: {
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
'X-API-KEY': apiKey,
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
issueId: args.issue_id,
|
|
88
|
+
filePath: args.file_path,
|
|
89
|
+
context: args.context,
|
|
90
|
+
agent: 'mcp-server',
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
const errorData = await response.json().catch(() => ({}));
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Platform Error: ${errorData.message || response.statusText}`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
content: [
|
|
105
|
+
{
|
|
106
|
+
type: 'text',
|
|
107
|
+
text: `Recommended Fix (Diff):\n\n${data.diff}\n\nRationale:\n${data.rationale}`,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
} catch (error: unknown) {
|
|
112
|
+
const errorMessage =
|
|
113
|
+
error instanceof Error ? error.message : String(error);
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: `Failed to get remediation: ${errorMessage}. Please visit the dashboard to fix manually.`,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
isError: true,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
62
126
|
private setupHandlers() {
|
|
63
127
|
// List available tools
|
|
64
128
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
@@ -77,21 +141,46 @@ export class AIReadyMcpServer {
|
|
|
77
141
|
];
|
|
78
142
|
|
|
79
143
|
return {
|
|
80
|
-
tools:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
+
},
|
|
155
|
+
},
|
|
156
|
+
required: ['path'],
|
|
157
|
+
},
|
|
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
|
+
},
|
|
89
179
|
},
|
|
90
|
-
|
|
180
|
+
required: ['issue_id', 'file_path', 'context'],
|
|
91
181
|
},
|
|
92
|
-
required: ['path'],
|
|
93
182
|
},
|
|
94
|
-
|
|
183
|
+
],
|
|
95
184
|
};
|
|
96
185
|
});
|
|
97
186
|
|
|
@@ -100,6 +189,16 @@ export class AIReadyMcpServer {
|
|
|
100
189
|
const { name, arguments: args } = request.params;
|
|
101
190
|
|
|
102
191
|
try {
|
|
192
|
+
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
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
103
202
|
let provider = ToolRegistry.find(name);
|
|
104
203
|
|
|
105
204
|
// Dynamic loading if not already registered (CLI pattern)
|
|
@@ -114,12 +213,16 @@ export class AIReadyMcpServer {
|
|
|
114
213
|
);
|
|
115
214
|
await import(packageName);
|
|
116
215
|
provider = ToolRegistry.find(name);
|
|
117
|
-
} catch (importError:
|
|
216
|
+
} catch (importError: unknown) {
|
|
217
|
+
const importErrorMessage =
|
|
218
|
+
importError instanceof Error
|
|
219
|
+
? importError.message
|
|
220
|
+
: String(importError);
|
|
118
221
|
console.error(
|
|
119
|
-
`[MCP] Failed to load tool package ${packageName}: ${
|
|
222
|
+
`[MCP] Failed to load tool package ${packageName}: ${importErrorMessage}`
|
|
120
223
|
);
|
|
121
224
|
const error = new Error(
|
|
122
|
-
`Tool ${name} not found and failed to load package ${packageName}: ${
|
|
225
|
+
`Tool ${name} not found and failed to load package ${packageName}: ${importErrorMessage}`
|
|
123
226
|
);
|
|
124
227
|
(error as { cause?: unknown }).cause = importError;
|
|
125
228
|
throw error;
|
|
@@ -149,12 +252,14 @@ export class AIReadyMcpServer {
|
|
|
149
252
|
},
|
|
150
253
|
],
|
|
151
254
|
};
|
|
152
|
-
} catch (error:
|
|
255
|
+
} catch (error: unknown) {
|
|
256
|
+
const errorMessage =
|
|
257
|
+
error instanceof Error ? error.message : String(error);
|
|
153
258
|
return {
|
|
154
259
|
content: [
|
|
155
260
|
{
|
|
156
261
|
type: 'text',
|
|
157
|
-
text: `Error: ${
|
|
262
|
+
text: `Error: ${errorMessage}`,
|
|
158
263
|
},
|
|
159
264
|
],
|
|
160
265
|
isError: true,
|