replicas-mcp 0.2.14 → 0.2.16
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 +3 -3
- package/dist/index.js +596 -266
- package/package.json +1 -1
- package/src/index.ts +72 -120
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
VALID_LIFECYCLE_POLICIES,
|
|
19
19
|
} from '../../shared/src/routes/workspaces';
|
|
20
20
|
|
|
21
|
-
const API_URL = process.env.REPLICAS_API_URL || 'https://api.
|
|
21
|
+
const API_URL = process.env.REPLICAS_API_URL || 'https://api.replicas.dev';
|
|
22
22
|
const API_KEY = process.env.REPLICAS_API_KEY;
|
|
23
23
|
|
|
24
24
|
if (!API_KEY) {
|
|
@@ -71,10 +71,23 @@ type RegisterToolFn = (
|
|
|
71
71
|
|
|
72
72
|
const server = new McpServer({
|
|
73
73
|
name: 'replicas-mcp',
|
|
74
|
-
version: '0.2.
|
|
74
|
+
version: '0.2.16',
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
function registerTool(
|
|
78
|
+
name: string,
|
|
79
|
+
config: Parameters<RegisterToolFn>[1],
|
|
80
|
+
handler: (args: Record<string, unknown>) => Promise<unknown>,
|
|
81
|
+
): void {
|
|
82
|
+
(server.registerTool.bind(server) as RegisterToolFn)(name, config, async (args) => {
|
|
83
|
+
try {
|
|
84
|
+
return result(await handler(args));
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return result(error instanceof Error ? error.message : String(error), true);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
78
91
|
const codingAgentSchema = z.string().refine(isValidCodingAgentProvider, {
|
|
79
92
|
message: `Coding agent must be ${getCodingAgentDisplayNames()}`,
|
|
80
93
|
});
|
|
@@ -99,20 +112,16 @@ registerTool(
|
|
|
99
112
|
},
|
|
100
113
|
},
|
|
101
114
|
async (args) => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return result(await api('POST', '/v1/replica', body));
|
|
113
|
-
} catch (e) {
|
|
114
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
115
|
-
}
|
|
115
|
+
const body: Record<string, unknown> = {
|
|
116
|
+
name: args.name,
|
|
117
|
+
message: args.message,
|
|
118
|
+
};
|
|
119
|
+
if (args.repository_ids) body.repository_ids = args.repository_ids;
|
|
120
|
+
if (args.repository_set_id) body.repository_set_id = args.repository_set_id;
|
|
121
|
+
if (args.coding_agent) body.coding_agent = args.coding_agent;
|
|
122
|
+
if (args.model) body.model = args.model;
|
|
123
|
+
if (args.lifecycle_policy) body.lifecycle_policy = args.lifecycle_policy;
|
|
124
|
+
return api('POST', '/v1/replica', body);
|
|
116
125
|
}
|
|
117
126
|
);
|
|
118
127
|
|
|
@@ -129,18 +138,14 @@ registerTool(
|
|
|
129
138
|
},
|
|
130
139
|
},
|
|
131
140
|
async (args) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return result(await api('GET', `/v1/replica${q ? '?' + q : ''}`));
|
|
141
|
-
} catch (e) {
|
|
142
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
143
|
-
}
|
|
141
|
+
const params = new URLSearchParams();
|
|
142
|
+
if (args.page) params.set('page', String(args.page));
|
|
143
|
+
if (args.limit) params.set('limit', String(args.limit));
|
|
144
|
+
if (args.user_id) params.set('user_id', args.user_id as string);
|
|
145
|
+
if (args.source) params.set('source', args.source as string);
|
|
146
|
+
if (args.status) params.set('status', args.status as string);
|
|
147
|
+
const q = params.toString();
|
|
148
|
+
return api('GET', `/v1/replica${q ? '?' + q : ''}`);
|
|
144
149
|
}
|
|
145
150
|
);
|
|
146
151
|
|
|
@@ -154,14 +159,10 @@ registerTool(
|
|
|
154
159
|
},
|
|
155
160
|
},
|
|
156
161
|
async (args) => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return result(await api('GET', `/v1/replica/${args.id}${q ? '?' + q : ''}`));
|
|
162
|
-
} catch (e) {
|
|
163
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
164
|
-
}
|
|
162
|
+
const params = new URLSearchParams();
|
|
163
|
+
if (args.include) params.set('include', (args.include as string[]).join(','));
|
|
164
|
+
const q = params.toString();
|
|
165
|
+
return api('GET', `/v1/replica/${args.id}${q ? '?' + q : ''}`);
|
|
165
166
|
}
|
|
166
167
|
);
|
|
167
168
|
|
|
@@ -179,16 +180,12 @@ registerTool(
|
|
|
179
180
|
},
|
|
180
181
|
},
|
|
181
182
|
async (args) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return result(await api('POST', `/v1/replica/${args.id}/messages`, body));
|
|
189
|
-
} catch (e) {
|
|
190
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
191
|
-
}
|
|
183
|
+
const body: Record<string, unknown> = { message: args.message };
|
|
184
|
+
if (args.coding_agent) body.coding_agent = args.coding_agent;
|
|
185
|
+
if (args.chat_id) body.chat_id = args.chat_id;
|
|
186
|
+
if (args.model) body.model = args.model;
|
|
187
|
+
if (args.plan_mode !== undefined) body.plan_mode = args.plan_mode;
|
|
188
|
+
return api('POST', `/v1/replica/${args.id}/messages`, body);
|
|
192
189
|
}
|
|
193
190
|
);
|
|
194
191
|
|
|
@@ -200,13 +197,7 @@ registerTool(
|
|
|
200
197
|
id: z.string(),
|
|
201
198
|
},
|
|
202
199
|
},
|
|
203
|
-
|
|
204
|
-
try {
|
|
205
|
-
return result(await api('DELETE', `/v1/replica/${args.id}`));
|
|
206
|
-
} catch (e) {
|
|
207
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
200
|
+
(args) => api('DELETE', `/v1/replica/${args.id}`)
|
|
210
201
|
);
|
|
211
202
|
|
|
212
203
|
// ---------------------------------------------------------------------------
|
|
@@ -218,13 +209,7 @@ registerTool(
|
|
|
218
209
|
{
|
|
219
210
|
description: 'List available repositories that can be used when creating replicas',
|
|
220
211
|
},
|
|
221
|
-
|
|
222
|
-
try {
|
|
223
|
-
return result(await api('GET', '/v1/replica/repositories'));
|
|
224
|
-
} catch (e) {
|
|
225
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
212
|
+
() => api('GET', '/v1/replica/repositories')
|
|
228
213
|
);
|
|
229
214
|
|
|
230
215
|
registerTool(
|
|
@@ -232,13 +217,7 @@ registerTool(
|
|
|
232
217
|
{
|
|
233
218
|
description: 'List available repository sets (named groups of repositories)',
|
|
234
219
|
},
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
return result(await api('GET', '/v1/replica/repository-sets'));
|
|
238
|
-
} catch (e) {
|
|
239
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
220
|
+
() => api('GET', '/v1/replica/repository-sets')
|
|
242
221
|
);
|
|
243
222
|
|
|
244
223
|
// ---------------------------------------------------------------------------
|
|
@@ -253,13 +232,7 @@ registerTool(
|
|
|
253
232
|
id: z.string().describe('Replica ID'),
|
|
254
233
|
},
|
|
255
234
|
},
|
|
256
|
-
|
|
257
|
-
try {
|
|
258
|
-
return result(await api('GET', `/v1/replica/${args.id}/chats`));
|
|
259
|
-
} catch (e) {
|
|
260
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
235
|
+
(args) => api('GET', `/v1/replica/${args.id}/chats`)
|
|
263
236
|
);
|
|
264
237
|
|
|
265
238
|
registerTool(
|
|
@@ -273,13 +246,9 @@ registerTool(
|
|
|
273
246
|
},
|
|
274
247
|
},
|
|
275
248
|
async (args) => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
return result(await api('POST', `/v1/replica/${args.id}/chats`, body));
|
|
280
|
-
} catch (e) {
|
|
281
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
282
|
-
}
|
|
249
|
+
const body: Record<string, unknown> = { provider: args.provider };
|
|
250
|
+
if (args.title) body.title = args.title;
|
|
251
|
+
return api('POST', `/v1/replica/${args.id}/chats`, body);
|
|
283
252
|
}
|
|
284
253
|
);
|
|
285
254
|
|
|
@@ -292,13 +261,7 @@ registerTool(
|
|
|
292
261
|
chat_id: z.string().describe('Chat ID to delete'),
|
|
293
262
|
},
|
|
294
263
|
},
|
|
295
|
-
|
|
296
|
-
try {
|
|
297
|
-
return result(await api('DELETE', `/v1/replica/${args.id}/chats/${args.chat_id}`));
|
|
298
|
-
} catch (e) {
|
|
299
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
264
|
+
(args) => api('DELETE', `/v1/replica/${args.id}/chats/${args.chat_id}`)
|
|
302
265
|
);
|
|
303
266
|
|
|
304
267
|
// ---------------------------------------------------------------------------
|
|
@@ -315,33 +278,28 @@ registerTool(
|
|
|
315
278
|
},
|
|
316
279
|
},
|
|
317
280
|
async (args) => {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const response = await api<ReadReplicaHistoryResponse>('GET', `/v1/replica/${args.id}/history${q ? '?' + q : ''}`);
|
|
281
|
+
const params = new URLSearchParams();
|
|
282
|
+
if (args.chat_id) params.set('chat_id', args.chat_id as string);
|
|
283
|
+
const q = params.toString();
|
|
284
|
+
const response = await api<ReadReplicaHistoryResponse>('GET', `/v1/replica/${args.id}/history${q ? '?' + q : ''}`);
|
|
323
285
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
286
|
+
if (response.waking) {
|
|
287
|
+
return {
|
|
288
|
+
status: 'waking',
|
|
289
|
+
message: 'Workspace is waking from sleep. Retry in 30-90 seconds.',
|
|
290
|
+
};
|
|
291
|
+
}
|
|
330
292
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const messages = parseAgentEvents(response.events, agentType);
|
|
293
|
+
const agentType = (response.coding_agent || 'claude') as AgentProvider;
|
|
294
|
+
const messages = parseAgentEvents(response.events, agentType);
|
|
334
295
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
} catch (e) {
|
|
343
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
344
|
-
}
|
|
296
|
+
return {
|
|
297
|
+
thread_id: response.thread_id,
|
|
298
|
+
coding_agent: response.coding_agent,
|
|
299
|
+
total: response.total,
|
|
300
|
+
has_more: response.has_more,
|
|
301
|
+
messages,
|
|
302
|
+
};
|
|
345
303
|
}
|
|
346
304
|
);
|
|
347
305
|
|
|
@@ -353,13 +311,7 @@ registerTool(
|
|
|
353
311
|
id: z.string().describe('Replica ID'),
|
|
354
312
|
},
|
|
355
313
|
},
|
|
356
|
-
|
|
357
|
-
try {
|
|
358
|
-
return result(await api('GET', `/v1/replica/${args.id}/hooks`));
|
|
359
|
-
} catch (e) {
|
|
360
|
-
return result(e instanceof Error ? e.message : String(e), true);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
314
|
+
(args) => api('GET', `/v1/replica/${args.id}/hooks`)
|
|
363
315
|
);
|
|
364
316
|
|
|
365
317
|
const transport = new StdioServerTransport();
|