@agent-eyes/agent-eyes-mcp 0.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/README.md +35 -0
- package/dist/cli.js +7 -0
- package/dist/cli.mjs +7 -0
- package/dist/index.js +4 -0
- package/dist/index.mjs +2 -0
- package/dist/src-D-OQOBYj.js +214 -0
- package/dist/src-DMIK-7Qu.mjs +181 -0
- package/package.json +59 -0
- package/types/cli.d.ts +2 -0
- package/types/index.d.ts +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# agent-eyes-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for Agent Eyes. It exposes two tools:
|
|
4
|
+
|
|
5
|
+
- `get_selected_context`
|
|
6
|
+
Reads `GET /context/selected` from the local Agent Eyes service.
|
|
7
|
+
- `ensure_agents_rule`
|
|
8
|
+
Creates or updates `AGENTS.md` in the target project root with the Agent Eyes workflow rule.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add -D agent-eyes-mcp
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Configure MCP client
|
|
17
|
+
|
|
18
|
+
Example stdio config:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"mcpServers": {
|
|
23
|
+
"agent-eyes": {
|
|
24
|
+
"command": "npx",
|
|
25
|
+
"args": ["agent-eyes-mcp"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Tool notes
|
|
32
|
+
|
|
33
|
+
`get_selected_context` expects the local Agent Eyes service to be running, usually at `http://127.0.0.1:5678`.
|
|
34
|
+
|
|
35
|
+
`ensure_agents_rule` writes `AGENTS.md` in the provided `projectRoot`, or in the current working directory when omitted.
|
package/dist/cli.js
ADDED
package/dist/cli.mjs
ADDED
package/dist/index.js
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
9
|
+
key = keys[i];
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
11
|
+
get: ((k) => from[k]).bind(null, key),
|
|
12
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
18
|
+
value: mod,
|
|
19
|
+
enumerable: true
|
|
20
|
+
}) : target, mod));
|
|
21
|
+
let fs = require("fs");
|
|
22
|
+
fs = __toESM(fs);
|
|
23
|
+
let path = require("path");
|
|
24
|
+
path = __toESM(path);
|
|
25
|
+
let __modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
26
|
+
let __modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
27
|
+
let zod = require("zod");
|
|
28
|
+
var DEFAULT_BASE_URL = "http://127.0.0.1:5678";
|
|
29
|
+
var agentEyesRuleSection = `## Agent Eyes Workflow
|
|
30
|
+
|
|
31
|
+
For any task that may modify UI, DOM structure, styles, component behavior, page content, or selected elements:
|
|
32
|
+
|
|
33
|
+
1. First verify that \`code-inspector-plugin\` is installed in this project.
|
|
34
|
+
2. Before making any code change, request \`GET http://127.0.0.1:5678/context/selected\`.
|
|
35
|
+
3. If the response contains \`data: null\`, do not guess the target code.
|
|
36
|
+
4. Ask the user to open Agent Eyes, select the target element, and keep the selection panel open.
|
|
37
|
+
5. Only after a non-null context is returned may you use that context to locate and modify code precisely.
|
|
38
|
+
|
|
39
|
+
Prefer multi-selection fields when available:
|
|
40
|
+
|
|
41
|
+
- \`activeSelectionId\`
|
|
42
|
+
- \`selections\` / \`contexts\`
|
|
43
|
+
- \`data.active\` and \`data.selections\`
|
|
44
|
+
|
|
45
|
+
If only single-selection fields exist, use \`filePath\`, \`line\`, \`column\`, \`elementName\`, \`dom\`, and \`domPath\`.
|
|
46
|
+
|
|
47
|
+
If \`code-inspector-plugin\` is missing:
|
|
48
|
+
|
|
49
|
+
- \`pnpm add -D code-inspector-plugin\`
|
|
50
|
+
- \`yarn add -D code-inspector-plugin\`
|
|
51
|
+
- \`npm i -D code-inspector-plugin\`
|
|
52
|
+
|
|
53
|
+
Then add the minimal bundler configuration required by the current project before continuing.
|
|
54
|
+
`;
|
|
55
|
+
function detectPackageManager(rootDir) {
|
|
56
|
+
if (fs.default.existsSync(path.default.join(rootDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
57
|
+
if (fs.default.existsSync(path.default.join(rootDir, "yarn.lock"))) return "yarn";
|
|
58
|
+
if (fs.default.existsSync(path.default.join(rootDir, "package-lock.json"))) return "npm";
|
|
59
|
+
return "npm";
|
|
60
|
+
}
|
|
61
|
+
function readProjectPackageMeta(rootDir) {
|
|
62
|
+
const packageJsonPath = path.default.join(rootDir, "package.json");
|
|
63
|
+
if (!fs.default.existsSync(packageJsonPath)) return {
|
|
64
|
+
packageJsonPath,
|
|
65
|
+
packageExists: false,
|
|
66
|
+
pluginInstalled: false
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
const pkg = JSON.parse(fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
70
|
+
return {
|
|
71
|
+
packageJsonPath,
|
|
72
|
+
packageExists: true,
|
|
73
|
+
pluginInstalled: !!{
|
|
74
|
+
...pkg?.dependencies || {},
|
|
75
|
+
...pkg?.devDependencies || {}
|
|
76
|
+
}["code-inspector-plugin"]
|
|
77
|
+
};
|
|
78
|
+
} catch {
|
|
79
|
+
return {
|
|
80
|
+
packageJsonPath,
|
|
81
|
+
packageExists: true,
|
|
82
|
+
pluginInstalled: false
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function getAgentsFileStatus(rootDir) {
|
|
87
|
+
const agentsPath = path.default.join(rootDir, "AGENTS.md");
|
|
88
|
+
const exists = fs.default.existsSync(agentsPath);
|
|
89
|
+
const content = exists ? fs.default.readFileSync(agentsPath, "utf-8") : "";
|
|
90
|
+
return {
|
|
91
|
+
agentsPath,
|
|
92
|
+
exists,
|
|
93
|
+
hasRule: content.includes("## Agent Eyes Workflow"),
|
|
94
|
+
content
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function getSelectedContext(baseUrl) {
|
|
98
|
+
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/context/selected`, { headers: { Accept: "application/json" } });
|
|
99
|
+
if (!response.ok) throw new Error(`request failed: ${response.status}`);
|
|
100
|
+
return response.json();
|
|
101
|
+
}
|
|
102
|
+
function normalizeSelectedContextPayload(payload) {
|
|
103
|
+
const topSelections = Array.isArray(payload?.selections) ? payload.selections : [];
|
|
104
|
+
const topContexts = Array.isArray(payload?.contexts) ? payload.contexts : [];
|
|
105
|
+
const dataSelections = Array.isArray(payload?.data?.selections) ? payload.data.selections : [];
|
|
106
|
+
const dataContexts = Array.isArray(payload?.data?.contexts) ? payload.data.contexts : [];
|
|
107
|
+
const contexts = topContexts.length > 0 ? topContexts : topSelections.length > 0 ? topSelections : dataContexts.length > 0 ? dataContexts : dataSelections.length > 0 ? dataSelections : payload?.data?.filePath ? [payload.data] : [];
|
|
108
|
+
const activeSelectionId = String(payload?.activeSelectionId || payload?.data?.activeSelectionId || payload?.active?.id || payload?.data?.active?.id || "");
|
|
109
|
+
const active = payload?.active || payload?.data?.active || contexts.find((item) => item?.id && item.id === activeSelectionId) || payload?.data || contexts[0] || null;
|
|
110
|
+
return {
|
|
111
|
+
...payload,
|
|
112
|
+
data: payload?.data ?? active,
|
|
113
|
+
active,
|
|
114
|
+
activeSelectionId: activeSelectionId || active?.id || "",
|
|
115
|
+
contexts,
|
|
116
|
+
selections: contexts
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function ensureAgentsRule(rootDir) {
|
|
120
|
+
const agentsMeta = getAgentsFileStatus(rootDir);
|
|
121
|
+
let nextContent = "";
|
|
122
|
+
if (!agentsMeta.exists) nextContent = `# Project Agent Rules\n\n${agentEyesRuleSection}\n`;
|
|
123
|
+
else nextContent = agentsMeta.hasRule ? agentsMeta.content.replace(/## Agent Eyes Workflow[\s\S]*$/m, agentEyesRuleSection.trimEnd()) : `${agentsMeta.content.trimEnd()}\n\n${agentEyesRuleSection}\n`;
|
|
124
|
+
fs.default.writeFileSync(agentsMeta.agentsPath, nextContent, "utf-8");
|
|
125
|
+
return {
|
|
126
|
+
agentsPath: agentsMeta.agentsPath,
|
|
127
|
+
created: !agentsMeta.exists,
|
|
128
|
+
updated: agentsMeta.exists
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function createAgentEyesMcpServer() {
|
|
132
|
+
const server = new __modelcontextprotocol_sdk_server_mcp_js.McpServer({
|
|
133
|
+
name: "agent-eyes-mcp",
|
|
134
|
+
version: "0.0.1"
|
|
135
|
+
});
|
|
136
|
+
server.registerTool("get_selected_context", {
|
|
137
|
+
description: "Get the currently selected Agent Eyes code context from the local service. Use before any precise UI or page code modification.",
|
|
138
|
+
inputSchema: { baseUrl: zod.z.string().optional().describe("Agent Eyes local service base URL, default http://127.0.0.1:5678") }
|
|
139
|
+
}, async ({ baseUrl }) => {
|
|
140
|
+
try {
|
|
141
|
+
const normalized = normalizeSelectedContextPayload(await getSelectedContext(baseUrl || DEFAULT_BASE_URL));
|
|
142
|
+
return {
|
|
143
|
+
content: [{
|
|
144
|
+
type: "text",
|
|
145
|
+
text: JSON.stringify(normalized, null, 2)
|
|
146
|
+
}],
|
|
147
|
+
structuredContent: normalized
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
return {
|
|
151
|
+
content: [{
|
|
152
|
+
type: "text",
|
|
153
|
+
text: String(error instanceof Error ? error.message : error)
|
|
154
|
+
}],
|
|
155
|
+
isError: true
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
server.registerTool("ensure_agents_rule", {
|
|
160
|
+
description: "Create or update AGENTS.md in the project root with the Agent Eyes workflow rule.",
|
|
161
|
+
inputSchema: { projectRoot: zod.z.string().optional().describe("Project root directory. Defaults to current working directory.") }
|
|
162
|
+
}, async ({ projectRoot }) => {
|
|
163
|
+
const rootDir = path.default.resolve(projectRoot || process.cwd());
|
|
164
|
+
try {
|
|
165
|
+
const packageMeta = readProjectPackageMeta(rootDir);
|
|
166
|
+
const packageManager = detectPackageManager(rootDir);
|
|
167
|
+
const installCommand = packageManager === "pnpm" ? "pnpm add -D code-inspector-plugin" : packageManager === "yarn" ? "yarn add -D code-inspector-plugin" : "npm i -D code-inspector-plugin";
|
|
168
|
+
const agentsResult = ensureAgentsRule(rootDir);
|
|
169
|
+
const result = {
|
|
170
|
+
rootDir,
|
|
171
|
+
packageJsonPath: packageMeta.packageJsonPath,
|
|
172
|
+
packageExists: packageMeta.packageExists,
|
|
173
|
+
pluginInstalled: packageMeta.pluginInstalled,
|
|
174
|
+
packageManager,
|
|
175
|
+
installCommand,
|
|
176
|
+
...agentsResult
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
content: [{
|
|
180
|
+
type: "text",
|
|
181
|
+
text: JSON.stringify(result, null, 2)
|
|
182
|
+
}],
|
|
183
|
+
structuredContent: result
|
|
184
|
+
};
|
|
185
|
+
} catch (error) {
|
|
186
|
+
return {
|
|
187
|
+
content: [{
|
|
188
|
+
type: "text",
|
|
189
|
+
text: String(error instanceof Error ? error.message : error)
|
|
190
|
+
}],
|
|
191
|
+
isError: true
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return server;
|
|
196
|
+
}
|
|
197
|
+
async function startAgentEyesMcpServer() {
|
|
198
|
+
const server = createAgentEyesMcpServer();
|
|
199
|
+
const transport = new __modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
|
|
200
|
+
await server.connect(transport);
|
|
201
|
+
return server;
|
|
202
|
+
}
|
|
203
|
+
Object.defineProperty(exports, "createAgentEyesMcpServer", {
|
|
204
|
+
enumerable: true,
|
|
205
|
+
get: function() {
|
|
206
|
+
return createAgentEyesMcpServer;
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
Object.defineProperty(exports, "startAgentEyesMcpServer", {
|
|
210
|
+
enumerable: true,
|
|
211
|
+
get: function() {
|
|
212
|
+
return startAgentEyesMcpServer;
|
|
213
|
+
}
|
|
214
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
var DEFAULT_BASE_URL = "http://127.0.0.1:5678";
|
|
7
|
+
var agentEyesRuleSection = `## Agent Eyes Workflow
|
|
8
|
+
|
|
9
|
+
For any task that may modify UI, DOM structure, styles, component behavior, page content, or selected elements:
|
|
10
|
+
|
|
11
|
+
1. First verify that \`code-inspector-plugin\` is installed in this project.
|
|
12
|
+
2. Before making any code change, request \`GET http://127.0.0.1:5678/context/selected\`.
|
|
13
|
+
3. If the response contains \`data: null\`, do not guess the target code.
|
|
14
|
+
4. Ask the user to open Agent Eyes, select the target element, and keep the selection panel open.
|
|
15
|
+
5. Only after a non-null context is returned may you use that context to locate and modify code precisely.
|
|
16
|
+
|
|
17
|
+
Prefer multi-selection fields when available:
|
|
18
|
+
|
|
19
|
+
- \`activeSelectionId\`
|
|
20
|
+
- \`selections\` / \`contexts\`
|
|
21
|
+
- \`data.active\` and \`data.selections\`
|
|
22
|
+
|
|
23
|
+
If only single-selection fields exist, use \`filePath\`, \`line\`, \`column\`, \`elementName\`, \`dom\`, and \`domPath\`.
|
|
24
|
+
|
|
25
|
+
If \`code-inspector-plugin\` is missing:
|
|
26
|
+
|
|
27
|
+
- \`pnpm add -D code-inspector-plugin\`
|
|
28
|
+
- \`yarn add -D code-inspector-plugin\`
|
|
29
|
+
- \`npm i -D code-inspector-plugin\`
|
|
30
|
+
|
|
31
|
+
Then add the minimal bundler configuration required by the current project before continuing.
|
|
32
|
+
`;
|
|
33
|
+
function detectPackageManager(rootDir) {
|
|
34
|
+
if (fs.existsSync(path.join(rootDir, "pnpm-lock.yaml"))) return "pnpm";
|
|
35
|
+
if (fs.existsSync(path.join(rootDir, "yarn.lock"))) return "yarn";
|
|
36
|
+
if (fs.existsSync(path.join(rootDir, "package-lock.json"))) return "npm";
|
|
37
|
+
return "npm";
|
|
38
|
+
}
|
|
39
|
+
function readProjectPackageMeta(rootDir) {
|
|
40
|
+
const packageJsonPath = path.join(rootDir, "package.json");
|
|
41
|
+
if (!fs.existsSync(packageJsonPath)) return {
|
|
42
|
+
packageJsonPath,
|
|
43
|
+
packageExists: false,
|
|
44
|
+
pluginInstalled: false
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
48
|
+
return {
|
|
49
|
+
packageJsonPath,
|
|
50
|
+
packageExists: true,
|
|
51
|
+
pluginInstalled: !!{
|
|
52
|
+
...pkg?.dependencies || {},
|
|
53
|
+
...pkg?.devDependencies || {}
|
|
54
|
+
}["code-inspector-plugin"]
|
|
55
|
+
};
|
|
56
|
+
} catch {
|
|
57
|
+
return {
|
|
58
|
+
packageJsonPath,
|
|
59
|
+
packageExists: true,
|
|
60
|
+
pluginInstalled: false
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function getAgentsFileStatus(rootDir) {
|
|
65
|
+
const agentsPath = path.join(rootDir, "AGENTS.md");
|
|
66
|
+
const exists = fs.existsSync(agentsPath);
|
|
67
|
+
const content = exists ? fs.readFileSync(agentsPath, "utf-8") : "";
|
|
68
|
+
return {
|
|
69
|
+
agentsPath,
|
|
70
|
+
exists,
|
|
71
|
+
hasRule: content.includes("## Agent Eyes Workflow"),
|
|
72
|
+
content
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function getSelectedContext(baseUrl) {
|
|
76
|
+
const response = await fetch(`${baseUrl.replace(/\/$/, "")}/context/selected`, { headers: { Accept: "application/json" } });
|
|
77
|
+
if (!response.ok) throw new Error(`request failed: ${response.status}`);
|
|
78
|
+
return response.json();
|
|
79
|
+
}
|
|
80
|
+
function normalizeSelectedContextPayload(payload) {
|
|
81
|
+
const topSelections = Array.isArray(payload?.selections) ? payload.selections : [];
|
|
82
|
+
const topContexts = Array.isArray(payload?.contexts) ? payload.contexts : [];
|
|
83
|
+
const dataSelections = Array.isArray(payload?.data?.selections) ? payload.data.selections : [];
|
|
84
|
+
const dataContexts = Array.isArray(payload?.data?.contexts) ? payload.data.contexts : [];
|
|
85
|
+
const contexts = topContexts.length > 0 ? topContexts : topSelections.length > 0 ? topSelections : dataContexts.length > 0 ? dataContexts : dataSelections.length > 0 ? dataSelections : payload?.data?.filePath ? [payload.data] : [];
|
|
86
|
+
const activeSelectionId = String(payload?.activeSelectionId || payload?.data?.activeSelectionId || payload?.active?.id || payload?.data?.active?.id || "");
|
|
87
|
+
const active = payload?.active || payload?.data?.active || contexts.find((item) => item?.id && item.id === activeSelectionId) || payload?.data || contexts[0] || null;
|
|
88
|
+
return {
|
|
89
|
+
...payload,
|
|
90
|
+
data: payload?.data ?? active,
|
|
91
|
+
active,
|
|
92
|
+
activeSelectionId: activeSelectionId || active?.id || "",
|
|
93
|
+
contexts,
|
|
94
|
+
selections: contexts
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function ensureAgentsRule(rootDir) {
|
|
98
|
+
const agentsMeta = getAgentsFileStatus(rootDir);
|
|
99
|
+
let nextContent = "";
|
|
100
|
+
if (!agentsMeta.exists) nextContent = `# Project Agent Rules\n\n${agentEyesRuleSection}\n`;
|
|
101
|
+
else nextContent = agentsMeta.hasRule ? agentsMeta.content.replace(/## Agent Eyes Workflow[\s\S]*$/m, agentEyesRuleSection.trimEnd()) : `${agentsMeta.content.trimEnd()}\n\n${agentEyesRuleSection}\n`;
|
|
102
|
+
fs.writeFileSync(agentsMeta.agentsPath, nextContent, "utf-8");
|
|
103
|
+
return {
|
|
104
|
+
agentsPath: agentsMeta.agentsPath,
|
|
105
|
+
created: !agentsMeta.exists,
|
|
106
|
+
updated: agentsMeta.exists
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createAgentEyesMcpServer() {
|
|
110
|
+
const server = new McpServer({
|
|
111
|
+
name: "agent-eyes-mcp",
|
|
112
|
+
version: "0.0.1"
|
|
113
|
+
});
|
|
114
|
+
server.registerTool("get_selected_context", {
|
|
115
|
+
description: "Get the currently selected Agent Eyes code context from the local service. Use before any precise UI or page code modification.",
|
|
116
|
+
inputSchema: { baseUrl: z.string().optional().describe("Agent Eyes local service base URL, default http://127.0.0.1:5678") }
|
|
117
|
+
}, async ({ baseUrl }) => {
|
|
118
|
+
try {
|
|
119
|
+
const normalized = normalizeSelectedContextPayload(await getSelectedContext(baseUrl || DEFAULT_BASE_URL));
|
|
120
|
+
return {
|
|
121
|
+
content: [{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: JSON.stringify(normalized, null, 2)
|
|
124
|
+
}],
|
|
125
|
+
structuredContent: normalized
|
|
126
|
+
};
|
|
127
|
+
} catch (error) {
|
|
128
|
+
return {
|
|
129
|
+
content: [{
|
|
130
|
+
type: "text",
|
|
131
|
+
text: String(error instanceof Error ? error.message : error)
|
|
132
|
+
}],
|
|
133
|
+
isError: true
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
server.registerTool("ensure_agents_rule", {
|
|
138
|
+
description: "Create or update AGENTS.md in the project root with the Agent Eyes workflow rule.",
|
|
139
|
+
inputSchema: { projectRoot: z.string().optional().describe("Project root directory. Defaults to current working directory.") }
|
|
140
|
+
}, async ({ projectRoot }) => {
|
|
141
|
+
const rootDir = path.resolve(projectRoot || process.cwd());
|
|
142
|
+
try {
|
|
143
|
+
const packageMeta = readProjectPackageMeta(rootDir);
|
|
144
|
+
const packageManager = detectPackageManager(rootDir);
|
|
145
|
+
const installCommand = packageManager === "pnpm" ? "pnpm add -D code-inspector-plugin" : packageManager === "yarn" ? "yarn add -D code-inspector-plugin" : "npm i -D code-inspector-plugin";
|
|
146
|
+
const agentsResult = ensureAgentsRule(rootDir);
|
|
147
|
+
const result = {
|
|
148
|
+
rootDir,
|
|
149
|
+
packageJsonPath: packageMeta.packageJsonPath,
|
|
150
|
+
packageExists: packageMeta.packageExists,
|
|
151
|
+
pluginInstalled: packageMeta.pluginInstalled,
|
|
152
|
+
packageManager,
|
|
153
|
+
installCommand,
|
|
154
|
+
...agentsResult
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
content: [{
|
|
158
|
+
type: "text",
|
|
159
|
+
text: JSON.stringify(result, null, 2)
|
|
160
|
+
}],
|
|
161
|
+
structuredContent: result
|
|
162
|
+
};
|
|
163
|
+
} catch (error) {
|
|
164
|
+
return {
|
|
165
|
+
content: [{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: String(error instanceof Error ? error.message : error)
|
|
168
|
+
}],
|
|
169
|
+
isError: true
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return server;
|
|
174
|
+
}
|
|
175
|
+
async function startAgentEyesMcpServer() {
|
|
176
|
+
const server = createAgentEyesMcpServer();
|
|
177
|
+
const transport = new StdioServerTransport();
|
|
178
|
+
await server.connect(transport);
|
|
179
|
+
return server;
|
|
180
|
+
}
|
|
181
|
+
export { startAgentEyesMcpServer as n, createAgentEyesMcpServer as t };
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agent-eyes/agent-eyes-mcp",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"typings": "./types/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"agent-eyes-mcp": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"repository": "git@github.com:zh-lx/code-inspector.git",
|
|
14
|
+
"author": "zh-lx <18366276315@163.com>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://inspector.fe-dev.cn/en",
|
|
17
|
+
"description": "MCP server for Agent Eyes selected context and AGENTS.md setup.",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"types",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./types/index.d.ts",
|
|
27
|
+
"default": "./dist/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./types/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mcp",
|
|
37
|
+
"agent-eyes",
|
|
38
|
+
"code-inspector",
|
|
39
|
+
"model-context-protocol"
|
|
40
|
+
],
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/zh-lx/code-inspector/issues"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
46
|
+
"zod": "^3.25.76"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.3.3",
|
|
50
|
+
"typescript": "^5.5.4",
|
|
51
|
+
"vite": "^4.3.9"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"clear": "rimraf ./dist && rimraf ./types",
|
|
55
|
+
"build": "node ./scripts/build.mjs",
|
|
56
|
+
"pub": "pnpm publish",
|
|
57
|
+
"pub:beta": "pnpm publish --tag beta"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/types/cli.d.ts
ADDED
package/types/index.d.ts
ADDED