neo-mcp 1.1.11

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,316 @@
1
+ "use strict";
2
+ /**
3
+ * neo-mcp MCP server — stdio transport.
4
+ *
5
+ * Exposes 7 tools identical to the Python neo-mcp package:
6
+ * neo_submit_task, neo_task_status, neo_get_messages,
7
+ * neo_send_feedback, neo_pause_task, neo_resume_task, neo_stop_task
8
+ *
9
+ * Also starts the Neo daemon polling loop in the background so tasks
10
+ * actually execute locally — mirrors the Python server's BackendPoller.
11
+ *
12
+ * Usage:
13
+ * NEO_SECRET_KEY=sk-v1-... npx neo-mcp-daemon --mcp [/path/to/workspace]
14
+ *
15
+ * Register with Claude Code:
16
+ * claude mcp add --scope user neo \
17
+ * -e NEO_SECRET_KEY=sk-v1-... \
18
+ * -- npx neo-mcp-daemon --mcp
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.runMcpServer = runMcpServer;
22
+ const mcp_1 = require("@modelcontextprotocol/sdk/server/mcp");
23
+ const stdio_1 = require("@modelcontextprotocol/sdk/server/stdio");
24
+ const zod_1 = require("zod");
25
+ const auth_1 = require("./auth");
26
+ const daemon_1 = require("./daemon");
27
+ const neo_client_1 = require("./neo-client");
28
+ // Return helpers.
29
+ // Note: explicit return-type annotations are intentionally omitted on handlers to avoid
30
+ // TS2589 "type instantiation excessively deep" — a known tsc limitation when McpServer
31
+ // infers through deeply-chained Zod generics. The returned shapes are correct at runtime.
32
+ function ok(data) {
33
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
34
+ }
35
+ function toolErr(e) {
36
+ const msg = e instanceof Error ? e.message : String(e);
37
+ return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
38
+ }
39
+ async function runMcpServer(opts) {
40
+ const token = (0, auth_1.getAuthToken)();
41
+ if (!token) {
42
+ process.stderr.write('ERROR: NEO_SECRET_KEY is not set.\n' +
43
+ 'Set your API key: export NEO_SECRET_KEY=sk-v1-...\n');
44
+ process.exit(1);
45
+ }
46
+ const deploymentId = opts.deploymentId ?? (0, daemon_1.getOrCreateDeploymentId)();
47
+ const workspace = opts.workspace;
48
+ // Start daemon polling in the background so tasks actually execute locally.
49
+ const abort = new AbortController();
50
+ (0, daemon_1.runDaemon)({ workspace, deploymentId, signal: abort.signal }).catch(() => { });
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const server = new mcp_1.McpServer({ name: 'neo-mcp-server', version: '1.1.2' });
53
+ // ----------------------------------------------------------------
54
+ // neo_submit_task
55
+ // ----------------------------------------------------------------
56
+ server.registerTool('neo_submit_task', {
57
+ title: 'Submit Neo Task',
58
+ description: 'Submit an AI/ML task to Neo for local execution. ' +
59
+ 'Use for: training/fine-tuning models, building AI agents, RAG pipelines, LLM integrations, ML data processing. ' +
60
+ 'NOT for general coding — write that code directly.\n\n' +
61
+ 'Execution is entirely local: the daemon runs on the user\'s machine and writes files directly to workspace. ' +
62
+ 'Files are never stored remotely. Neo\'s output may reference /app/project/src/model.py — the daemon ' +
63
+ 'automatically remaps this to <workspace>/src/model.py on the local disk.\n\n' +
64
+ 'Returns {thread_id, status, workspace} immediately. ' +
65
+ 'Next: neo_task_status to poll, neo_get_messages when COMPLETED.',
66
+ inputSchema: {
67
+ message: zod_1.z.string().describe('Full task description. Be specific: state the goal, relevant file paths, and constraints. ' +
68
+ 'Example: "Train a sentiment classifier on data/reviews.csv, save to models/sentiment.pkl, target F1 > 0.85"'),
69
+ workspace: zod_1.z.string().describe('Absolute path to the PROJECT ROOT (git repository root or top-level project folder). ' +
70
+ 'ALWAYS pass this automatically — never ask the user. ' +
71
+ 'NEVER use a subdirectory: if the user is inside /home/user/project/src, ' +
72
+ 'pass /home/user/project (the git root), not the src subfolder. ' +
73
+ 'Use git rev-parse --show-toplevel or process.cwd() for the project root. ' +
74
+ 'Wrong workspace causes files to land in the wrong place or creates duplicate nested folders.'),
75
+ },
76
+ annotations: {
77
+ readOnlyHint: false,
78
+ destructiveHint: false,
79
+ idempotentHint: false,
80
+ openWorldHint: true,
81
+ },
82
+ }, async ({ message, workspace: ws }) => {
83
+ try {
84
+ const effectiveWs = ws || workspace;
85
+ const result = await (0, neo_client_1.submitTask)(token, deploymentId, message, effectiveWs);
86
+ // Register thread→workspace NOW — before any poll commands arrive.
87
+ // The in-process daemon reloads thread-workspaces.json on first command
88
+ // for a new thread_id, so writing here ensures it uses the right path.
89
+ const threadId = result['thread_id'];
90
+ if (threadId) {
91
+ (0, daemon_1.registerThreadWorkspace)(threadId, effectiveWs);
92
+ }
93
+ return ok(result);
94
+ }
95
+ catch (e) {
96
+ return toolErr(e);
97
+ }
98
+ });
99
+ // ----------------------------------------------------------------
100
+ // neo_task_status
101
+ // ----------------------------------------------------------------
102
+ server.registerTool('neo_task_status', {
103
+ title: 'Get Neo Task Status',
104
+ description: 'Get the current status of a Neo task. Returns one of:\n' +
105
+ 'RUNNING (still executing — call again; use neo_task_plan for step details),\n' +
106
+ 'COMPLETED (done — call neo_get_messages for output),\n' +
107
+ 'WAITING_FOR_FEEDBACK (Neo has a question — call neo_send_feedback),\n' +
108
+ 'PAUSED (frozen — call neo_resume_task to continue),\n' +
109
+ 'TERMINATED or FAILED (ended — call neo_get_messages to read what happened).\n\n' +
110
+ 'Reads from in-memory cache backed by an adaptive poller (3s–60s). ' +
111
+ 'Fast and safe to call once per turn. Do NOT poll in a tight loop.',
112
+ inputSchema: {
113
+ thread_id: zod_1.z.string().describe('Thread ID from neo_submit_task. Example: "thread_abc123"'),
114
+ },
115
+ annotations: {
116
+ readOnlyHint: true,
117
+ destructiveHint: false,
118
+ idempotentHint: true,
119
+ openWorldHint: true,
120
+ },
121
+ }, async ({ thread_id }) => {
122
+ try {
123
+ return ok(await (0, neo_client_1.getTaskStatus)(token, thread_id));
124
+ }
125
+ catch (e) {
126
+ return toolErr(e);
127
+ }
128
+ });
129
+ // ----------------------------------------------------------------
130
+ // neo_get_messages
131
+ // ----------------------------------------------------------------
132
+ server.registerTool('neo_get_messages', {
133
+ title: 'Get Neo Task Messages',
134
+ description: 'Retrieve the full conversation output from a completed Neo task. ' +
135
+ 'Only call when neo_task_status returns COMPLETED — for live progress while RUNNING ' +
136
+ 'use neo_task_plan instead (cheaper, shows per-step status).\n\n' +
137
+ 'Output is capped at ~80,000 characters (~20,000 tokens). If truncated, paginate ' +
138
+ 'backwards using the `before` cursor set to the ISO timestamp of the oldest message ' +
139
+ 'from the previous page.',
140
+ inputSchema: {
141
+ thread_id: zod_1.z.string().describe('Thread ID returned by neo_submit_task.'),
142
+ before: zod_1.z.string().optional().describe('Pagination cursor — ISO timestamp of the oldest message in the previous page. ' +
143
+ 'Omit to get the most recent messages.'),
144
+ limit: zod_1.z.number().int().min(1).max(200).default(50).describe('Maximum number of messages to return. Default: 50.'),
145
+ },
146
+ annotations: {
147
+ readOnlyHint: true,
148
+ destructiveHint: false,
149
+ idempotentHint: true,
150
+ openWorldHint: true,
151
+ },
152
+ }, async ({ thread_id, before, limit }) => {
153
+ try {
154
+ return ok(await (0, neo_client_1.getMessages)(token, thread_id, before, limit));
155
+ }
156
+ catch (e) {
157
+ return toolErr(e);
158
+ }
159
+ });
160
+ // ----------------------------------------------------------------
161
+ // neo_send_feedback
162
+ // ----------------------------------------------------------------
163
+ server.registerTool('neo_send_feedback', {
164
+ title: 'Send Neo Task Feedback',
165
+ description: 'Reply to Neo when it is waiting for user input. ' +
166
+ 'Only call when neo_task_status returns WAITING_FOR_FEEDBACK — Neo has paused and ' +
167
+ 'needs a decision or clarification before continuing. ' +
168
+ 'After sending, call neo_task_status again to confirm the task resumed.\n\n' +
169
+ 'Do NOT use to submit a new task — use neo_submit_task for that.',
170
+ inputSchema: {
171
+ thread_id: zod_1.z.string().describe('Thread ID of the waiting task.'),
172
+ message: zod_1.z.string().describe("Your reply to Neo's question, or additional instructions. " +
173
+ 'Example: "Yes, use PyTorch. Target accuracy is 90%."'),
174
+ },
175
+ annotations: {
176
+ readOnlyHint: false,
177
+ destructiveHint: false,
178
+ idempotentHint: false,
179
+ openWorldHint: true,
180
+ },
181
+ }, async ({ thread_id, message }) => {
182
+ try {
183
+ await (0, neo_client_1.sendFeedback)(token, thread_id, message);
184
+ return ok({ status: 'ok', thread_id });
185
+ }
186
+ catch (e) {
187
+ return toolErr(e);
188
+ }
189
+ });
190
+ // ----------------------------------------------------------------
191
+ // neo_pause_task
192
+ // ----------------------------------------------------------------
193
+ server.registerTool('neo_pause_task', {
194
+ title: 'Pause Neo Task',
195
+ description: 'Pause a running Neo task mid-execution. The task freezes at its current step and ' +
196
+ 'can be resumed later with neo_resume_task. Safe to call on an already-paused task (no-op). ' +
197
+ 'To cancel permanently, use neo_stop_task instead.',
198
+ inputSchema: {
199
+ thread_id: zod_1.z.string().describe('Thread ID of the running task to pause.'),
200
+ },
201
+ annotations: {
202
+ readOnlyHint: false,
203
+ destructiveHint: false,
204
+ idempotentHint: true,
205
+ openWorldHint: true,
206
+ },
207
+ }, async ({ thread_id }) => {
208
+ try {
209
+ await (0, neo_client_1.controlThread)(token, thread_id, 'PAUSE');
210
+ return ok({ status: 'paused', thread_id });
211
+ }
212
+ catch (e) {
213
+ return toolErr(e);
214
+ }
215
+ });
216
+ // ----------------------------------------------------------------
217
+ // neo_resume_task
218
+ // ----------------------------------------------------------------
219
+ server.registerTool('neo_resume_task', {
220
+ title: 'Resume Neo Task',
221
+ description: 'Resume a paused Neo task from where it stopped. Has no effect if already running. ' +
222
+ 'Only works after neo_pause_task — to start a new task use neo_submit_task.',
223
+ inputSchema: {
224
+ thread_id: zod_1.z.string().describe('Thread ID of the paused task to resume.'),
225
+ },
226
+ annotations: {
227
+ readOnlyHint: false,
228
+ destructiveHint: false,
229
+ idempotentHint: true,
230
+ openWorldHint: true,
231
+ },
232
+ }, async ({ thread_id }) => {
233
+ try {
234
+ await (0, neo_client_1.controlThread)(token, thread_id, 'RESUME');
235
+ return ok({ status: 'resumed', thread_id });
236
+ }
237
+ catch (e) {
238
+ return toolErr(e);
239
+ }
240
+ });
241
+ // ----------------------------------------------------------------
242
+ // neo_stop_task
243
+ // ----------------------------------------------------------------
244
+ server.registerTool('neo_stop_task', {
245
+ title: 'Stop Neo Task',
246
+ description: 'Permanently stop and clean up a Neo task. ' +
247
+ 'IRREVERSIBLE — execution context is deleted and the task cannot be resumed. ' +
248
+ 'Only call when the user explicitly asks to cancel. ' +
249
+ 'To pause temporarily (resumable), use neo_pause_task instead.',
250
+ inputSchema: {
251
+ thread_id: zod_1.z.string().describe('Thread ID of the task to stop and clean up.'),
252
+ },
253
+ annotations: {
254
+ readOnlyHint: false,
255
+ destructiveHint: true,
256
+ idempotentHint: false,
257
+ openWorldHint: true,
258
+ },
259
+ }, async ({ thread_id }) => {
260
+ try {
261
+ await (0, neo_client_1.stopThread)(token, thread_id);
262
+ return ok({ status: 'stopped', thread_id });
263
+ }
264
+ catch (e) {
265
+ return toolErr(e);
266
+ }
267
+ });
268
+ // ----------------------------------------------------------------
269
+ // neo_list_tasks
270
+ // ----------------------------------------------------------------
271
+ server.registerTool('neo_list_tasks', {
272
+ title: 'List Neo Tasks',
273
+ description: 'List all known Neo tasks with their current live status. ' +
274
+ 'Use this when returning to a session — e.g. after closing and reopening ' +
275
+ 'Claude Code — to see which tasks are still RUNNING, which are COMPLETED, ' +
276
+ 'and which need feedback. ' +
277
+ 'Returns tasks sorted newest-first. For each task: thread_id, workspace, ' +
278
+ 'status, and last-updated timestamp. ' +
279
+ 'After getting thread_ids, use neo_task_status or neo_get_messages to drill into a specific task.',
280
+ inputSchema: {},
281
+ annotations: {
282
+ readOnlyHint: true,
283
+ destructiveHint: false,
284
+ idempotentHint: true,
285
+ openWorldHint: true,
286
+ },
287
+ }, async () => {
288
+ try {
289
+ const workspaces = (0, daemon_1.loadThreadWorkspaces)();
290
+ const entries = Object.entries(workspaces);
291
+ if (entries.length === 0)
292
+ return ok({ tasks: [], count: 0 });
293
+ const tasks = await Promise.all(entries.map(async ([threadId, workspace]) => {
294
+ let status = 'UNKNOWN';
295
+ try {
296
+ const data = await (0, neo_client_1.getTaskStatus)(token, threadId);
297
+ status = data['status'] ?? 'UNKNOWN';
298
+ }
299
+ catch { /* unreachable thread — leave as UNKNOWN */ }
300
+ return { thread_id: threadId, workspace, status };
301
+ }));
302
+ // Sort RUNNING first, then by thread_id (newest IDs tend to be lexicographically last)
303
+ const order = { RUNNING: 0, WAITING_FOR_FEEDBACK: 1, PAUSED: 2, COMPLETED: 3, FAILED: 4, TERMINATED: 5, UNKNOWN: 6 };
304
+ tasks.sort((a, b) => (order[a.status] ?? 6) - (order[b.status] ?? 6));
305
+ return ok({ tasks, count: tasks.length });
306
+ }
307
+ catch (e) {
308
+ return toolErr(e);
309
+ }
310
+ });
311
+ const transport = new stdio_1.StdioServerTransport();
312
+ await server.connect(transport);
313
+ // MCP server exited — shut down the background daemon cleanly.
314
+ abort.abort();
315
+ }
316
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HTTP client for the Neo backend API.
3
+ * Used by the MCP server to implement tool calls.
4
+ */
5
+ export declare function submitTask(token: string, deploymentId: string, message: string, workspace: string): Promise<Record<string, unknown>>;
6
+ export declare function getTaskStatus(token: string, threadId: string): Promise<Record<string, unknown>>;
7
+ export declare function getMessages(token: string, threadId: string, before?: string, limit?: number): Promise<Record<string, unknown>>;
8
+ export declare function sendFeedback(token: string, threadId: string, message: string): Promise<void>;
9
+ export declare function controlThread(token: string, threadId: string, signal: 'PAUSE' | 'RESUME'): Promise<void>;
10
+ export declare function stopThread(token: string, threadId: string): Promise<void>;
11
+ //# sourceMappingURL=neo-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo-client.d.ts","sourceRoot":"","sources":["../src/neo-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+BH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQlC;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMrG;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,SAAK,GACT,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAQlC;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlG;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GAAG,QAAQ,GACzB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /**
3
+ * HTTP client for the Neo backend API.
4
+ * Used by the MCP server to implement tool calls.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.submitTask = submitTask;
8
+ exports.getTaskStatus = getTaskStatus;
9
+ exports.getMessages = getMessages;
10
+ exports.sendFeedback = sendFeedback;
11
+ exports.controlThread = controlThread;
12
+ exports.stopThread = stopThread;
13
+ const config_1 = require("./config");
14
+ const TIMEOUT_MS = 30_000;
15
+ async function fetchWithTimeout(url, init) {
16
+ const controller = new AbortController();
17
+ const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
18
+ try {
19
+ return await fetch(url, { ...init, signal: controller.signal });
20
+ }
21
+ finally {
22
+ clearTimeout(timer);
23
+ }
24
+ }
25
+ function authHeaders(token) {
26
+ return { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' };
27
+ }
28
+ function handleError(status) {
29
+ switch (status) {
30
+ case 401: return 'Authentication failed. Check that NEO_SECRET_KEY is correct (sk-v1-...).';
31
+ case 403: return 'Permission denied. Your key may not have access to this resource.';
32
+ case 404: return 'Not found. The thread_id may be invalid or the task has expired.';
33
+ case 429: return 'Rate limit exceeded. Wait a moment before retrying.';
34
+ case 500: return 'Neo backend error. Try again in a moment.';
35
+ default: return `Neo API returned status ${status}.`;
36
+ }
37
+ }
38
+ async function submitTask(token, deploymentId, message, workspace) {
39
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/init-chat-direct`, {
40
+ method: 'POST',
41
+ headers: authHeaders(token),
42
+ body: JSON.stringify({ message, deployment_id: deploymentId, deployment_type: 'vscode', workspace }),
43
+ });
44
+ if (!res.ok)
45
+ throw new Error(handleError(res.status));
46
+ return res.json();
47
+ }
48
+ async function getTaskStatus(token, threadId) {
49
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/status/${threadId}`, {
50
+ headers: { Authorization: `Bearer ${token}` },
51
+ });
52
+ if (!res.ok)
53
+ throw new Error(handleError(res.status));
54
+ return res.json();
55
+ }
56
+ async function getMessages(token, threadId, before, limit = 50) {
57
+ const params = new URLSearchParams({ thread_id: threadId, limit: String(limit) });
58
+ if (before)
59
+ params.set('before', before);
60
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/thread-messages?${params}`, {
61
+ headers: { Authorization: `Bearer ${token}` },
62
+ });
63
+ if (!res.ok)
64
+ throw new Error(handleError(res.status));
65
+ return res.json();
66
+ }
67
+ async function sendFeedback(token, threadId, message) {
68
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/feedback/${threadId}`, {
69
+ method: 'POST',
70
+ headers: authHeaders(token),
71
+ body: JSON.stringify({ message }),
72
+ });
73
+ if (!res.ok)
74
+ throw new Error(handleError(res.status));
75
+ }
76
+ async function controlThread(token, threadId, signal) {
77
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/control/${threadId}`, {
78
+ method: 'POST',
79
+ headers: authHeaders(token),
80
+ body: JSON.stringify({ signal }),
81
+ });
82
+ if (!res.ok)
83
+ throw new Error(handleError(res.status));
84
+ }
85
+ async function stopThread(token, threadId) {
86
+ const res = await fetchWithTimeout(`${config_1.NEO_API_URL}/v2/thread/cleanup-direct/${threadId}`, {
87
+ method: 'DELETE',
88
+ headers: { Authorization: `Bearer ${token}` },
89
+ });
90
+ if (!res.ok)
91
+ throw new Error(handleError(res.status));
92
+ }
93
+ //# sourceMappingURL=neo-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neo-client.js","sourceRoot":"","sources":["../src/neo-client.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA+BH,gCAaC;AAED,sCAMC;AAED,kCAaC;AAED,oCAOC;AAED,sCAWC;AAED,gCAMC;AA/FD,qCAAuC;AAEvC,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,IAAiB;IAC5D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/D,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;AAClF,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,GAAG,CAAC,CAAC,OAAO,0EAA0E,CAAC;QAC5F,KAAK,GAAG,CAAC,CAAC,OAAO,mEAAmE,CAAC;QACrF,KAAK,GAAG,CAAC,CAAC,OAAO,kEAAkE,CAAC;QACpF,KAAK,GAAG,CAAC,CAAC,OAAO,qDAAqD,CAAC;QACvE,KAAK,GAAG,CAAC,CAAC,OAAO,2CAA2C,CAAC;QAC7D,OAAO,CAAC,CAAE,OAAO,2BAA2B,MAAM,GAAG,CAAC;IACxD,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,YAAoB,EACpB,OAAe,EACf,SAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,6BAA6B,EAAE;QAC9E,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;KACrG,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,IAAI,EAAsC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,aAAa,CAAC,KAAa,EAAE,QAAgB;IACjE,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,qBAAqB,QAAQ,EAAE,EAAE;QAChF,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,IAAI,EAAsC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,QAAgB,EAChB,MAAe,EACf,KAAK,GAAG,EAAE;IAEV,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,IAAI,MAAM;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,8BAA8B,MAAM,EAAE,EAAE;QACvF,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,IAAI,EAAsC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,QAAgB,EAAE,OAAe;IACjF,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,uBAAuB,QAAQ,EAAE,EAAE;QAClF,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;KAClC,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,KAAa,EACb,QAAgB,EAChB,MAA0B;IAE1B,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,sBAAsB,QAAQ,EAAE,EAAE;QACjF,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACjC,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,QAAgB;IAC9D,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,oBAAW,6BAA6B,QAAQ,EAAE,EAAE;QACxF,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const NEO_HOME: string;
2
+ export declare const DAEMON_DIR: string;
3
+ export declare const STANDALONE_UUID_FILE: string;
4
+ export declare const DAEMON_LOG: string;
5
+ export declare const NPM_PID_FILE: string;
6
+ export declare const WORKSPACES_FILE: string;
7
+ /** Per-deployment PID file — matches Python daemon's naming for compatibility. */
8
+ export declare function pidFileForDeployment(deploymentId: string): string;
9
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,QAAqD,CAAC;AAC3E,eAAO,MAAM,UAAU,QAA2B,CAAC;AACnD,eAAO,MAAM,oBAAoB,QAA+C,CAAC;AACjF,eAAO,MAAM,UAAU,QAAiC,CAAC;AACzD,eAAO,MAAM,YAAY,QAAqC,CAAC;AAC/D,eAAO,MAAM,eAAe,QAA6C,CAAC;AAE1E,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEjE"}
package/dist/paths.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WORKSPACES_FILE = exports.NPM_PID_FILE = exports.DAEMON_LOG = exports.STANDALONE_UUID_FILE = exports.DAEMON_DIR = exports.NEO_HOME = void 0;
4
+ exports.pidFileForDeployment = pidFileForDeployment;
5
+ const os_1 = require("os");
6
+ const path_1 = require("path");
7
+ exports.NEO_HOME = process.env['NEO_HOME'] || (0, path_1.join)((0, os_1.homedir)(), '.neo');
8
+ exports.DAEMON_DIR = (0, path_1.join)(exports.NEO_HOME, 'daemon');
9
+ exports.STANDALONE_UUID_FILE = (0, path_1.join)(exports.DAEMON_DIR, 'standalone_deployment_id');
10
+ exports.DAEMON_LOG = (0, path_1.join)(exports.DAEMON_DIR, 'daemon.log');
11
+ exports.NPM_PID_FILE = (0, path_1.join)(exports.DAEMON_DIR, 'npm_daemon.pid');
12
+ exports.WORKSPACES_FILE = (0, path_1.join)(exports.DAEMON_DIR, 'thread-workspaces.json');
13
+ /** Per-deployment PID file — matches Python daemon's naming for compatibility. */
14
+ function pidFileForDeployment(deploymentId) {
15
+ return (0, path_1.join)(exports.DAEMON_DIR, `daemon_${deploymentId.slice(0, 8)}.pid`);
16
+ }
17
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":";;;AAWA,oDAEC;AAbD,2BAA6B;AAC7B,+BAA4B;AAEf,QAAA,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,MAAM,CAAC,CAAC;AAC9D,QAAA,UAAU,GAAG,IAAA,WAAI,EAAC,gBAAQ,EAAE,QAAQ,CAAC,CAAC;AACtC,QAAA,oBAAoB,GAAG,IAAA,WAAI,EAAC,kBAAU,EAAE,0BAA0B,CAAC,CAAC;AACpE,QAAA,UAAU,GAAG,IAAA,WAAI,EAAC,kBAAU,EAAE,YAAY,CAAC,CAAC;AAC5C,QAAA,YAAY,GAAG,IAAA,WAAI,EAAC,kBAAU,EAAE,gBAAgB,CAAC,CAAC;AAClD,QAAA,eAAe,GAAG,IAAA,WAAI,EAAC,kBAAU,EAAE,wBAAwB,CAAC,CAAC;AAE1E,kFAAkF;AAClF,SAAgB,oBAAoB,CAAC,YAAoB;IACvD,OAAO,IAAA,WAAI,EAAC,kBAAU,EAAE,UAAU,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "neo-mcp",
3
+ "version": "1.1.11",
4
+ "description": "Neo MCP server and local execution daemon — runs AI/ML tasks locally, no Python required",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "neo-mcp-daemon": "bin/neo-mcp-daemon"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "test": "vitest run",
12
+ "test:watch": "vitest",
13
+ "postinstall": "node scripts/postinstall.js",
14
+ "prepublishOnly": "npm run build && npm test"
15
+ },
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "bin",
22
+ "scripts/postinstall.js",
23
+ "README.md"
24
+ ],
25
+ "keywords": [
26
+ "neo",
27
+ "mcp",
28
+ "daemon",
29
+ "ai",
30
+ "ml",
31
+ "local-execution"
32
+ ],
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.6.1",
36
+ "zod": "^3.23.8"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.0.0",
40
+ "typescript": "^5.5.0",
41
+ "vitest": "^2.0.0"
42
+ }
43
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Nothing to do — neo-mcp-daemon runs as a pure Node.js process.