@clawrent/mcp-server 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,720 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import { ApiClient as ApiClient2, loadConfig } from "@clawrent/cli";
7
+
8
+ // src/provider-agent.ts
9
+ import { EventEmitter } from "events";
10
+ import WebSocket from "ws";
11
+ import { SessionManager } from "@clawrent/cli";
12
+ var ProviderAgent = class extends EventEmitter {
13
+ client;
14
+ agentWs = null;
15
+ sessionManager = null;
16
+ heartbeatTimer = null;
17
+ reconnectTimer = null;
18
+ reconnectAttempts = 0;
19
+ maxReconnectDelay = 3e4;
20
+ _running = false;
21
+ agentId = null;
22
+ agentToken = null;
23
+ autoApprove = false;
24
+ activeSessions = /* @__PURE__ */ new Map();
25
+ constructor(client) {
26
+ super();
27
+ this.client = client;
28
+ }
29
+ get running() {
30
+ return this._running;
31
+ }
32
+ get currentAgentId() {
33
+ return this.agentId;
34
+ }
35
+ getSessions() {
36
+ return Array.from(this.activeSessions.values());
37
+ }
38
+ /**
39
+ * Start the in-process agent: connect to /ws/agent and listen for sessions.
40
+ */
41
+ async start(agentId, agentToken, autoApprove = false) {
42
+ if (this._running) {
43
+ throw new Error(`Already serving agent ${this.agentId}`);
44
+ }
45
+ this.agentId = agentId;
46
+ this.agentToken = agentToken;
47
+ this.autoApprove = autoApprove;
48
+ this._running = true;
49
+ this.reconnectAttempts = 0;
50
+ this.sessionManager = new SessionManager(this.client.wsUrl);
51
+ this.sessionManager.agentId = agentId;
52
+ this.sessionManager.on("session:connected", (sessionId) => {
53
+ this.emit("session:connected", sessionId);
54
+ });
55
+ this.sessionManager.on("session:message", (sessionId, message) => {
56
+ this.emit("session:message", sessionId, message);
57
+ });
58
+ this.sessionManager.on("session:disconnected", (sessionId) => {
59
+ this.activeSessions.delete(sessionId);
60
+ this.emit("session:disconnected", sessionId);
61
+ });
62
+ this.connectAgent();
63
+ }
64
+ /**
65
+ * Stop the agent: disconnect all sessions and the control channel.
66
+ */
67
+ stop() {
68
+ this._running = false;
69
+ if (this.heartbeatTimer) {
70
+ clearInterval(this.heartbeatTimer);
71
+ this.heartbeatTimer = null;
72
+ }
73
+ if (this.reconnectTimer) {
74
+ clearTimeout(this.reconnectTimer);
75
+ this.reconnectTimer = null;
76
+ }
77
+ this.sessionManager?.disconnectAll();
78
+ this.sessionManager = null;
79
+ if (this.agentWs && (this.agentWs.readyState === WebSocket.OPEN || this.agentWs.readyState === WebSocket.CONNECTING)) {
80
+ this.agentWs.close(1e3, "Agent stopping");
81
+ }
82
+ this.agentWs = null;
83
+ this.activeSessions.clear();
84
+ this.agentId = null;
85
+ this.agentToken = null;
86
+ this.emit("stopped");
87
+ }
88
+ /**
89
+ * Send a message to a specific session.
90
+ */
91
+ send(sessionId, message) {
92
+ if (!this.sessionManager) return false;
93
+ return this.sessionManager.send(sessionId, message);
94
+ }
95
+ connectAgent() {
96
+ if (!this._running || !this.agentToken) return;
97
+ const url = `${this.client.wsUrl}/ws/agent?token=${this.agentToken}`;
98
+ const ws = new WebSocket(url);
99
+ this.agentWs = ws;
100
+ ws.on("open", () => {
101
+ this.reconnectAttempts = 0;
102
+ this.emit("agent:connected", this.agentId);
103
+ this.heartbeatTimer = setInterval(() => {
104
+ if (ws.readyState === WebSocket.OPEN) {
105
+ ws.send(JSON.stringify({ type: "system.heartbeat", payload: {} }));
106
+ }
107
+ }, 25e3);
108
+ });
109
+ ws.on("message", (raw) => {
110
+ try {
111
+ const msg = JSON.parse(raw.toString());
112
+ this.handleAgentMessage(msg);
113
+ } catch {
114
+ }
115
+ });
116
+ ws.on("close", (code) => {
117
+ if (this.heartbeatTimer) {
118
+ clearInterval(this.heartbeatTimer);
119
+ this.heartbeatTimer = null;
120
+ }
121
+ this.emit("agent:disconnected", this.agentId);
122
+ if (this._running && code !== 1e3) {
123
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), this.maxReconnectDelay);
124
+ this.reconnectAttempts++;
125
+ this.reconnectTimer = setTimeout(() => this.connectAgent(), delay);
126
+ }
127
+ });
128
+ ws.on("error", (err) => {
129
+ this.emit("agent:error", err);
130
+ });
131
+ }
132
+ handleAgentMessage(msg) {
133
+ const type = msg["type"];
134
+ if (type === "system.heartbeat_ack") return;
135
+ if (type === "session.new") {
136
+ const payload = msg["payload"];
137
+ const sessionId = payload["sessionId"];
138
+ const sessionToken = payload["sessionToken"];
139
+ const taskDescription = payload["taskDescription"] || "";
140
+ const consumerUserId = payload["consumerUserId"];
141
+ const session = { sessionId, sessionToken, taskDescription, consumerUserId };
142
+ this.activeSessions.set(sessionId, session);
143
+ this.emit("session:new", session);
144
+ if (this.autoApprove) {
145
+ this.client.approveSession(sessionId).then(() => {
146
+ this.sessionManager?.connect(sessionId, sessionToken);
147
+ this.emit("session:approved", sessionId);
148
+ }).catch((err) => {
149
+ this.emit("session:error", sessionId, err);
150
+ });
151
+ }
152
+ } else if (type === "session.approved") {
153
+ const payload = msg["payload"];
154
+ const sessionId = payload["sessionId"];
155
+ const session = this.activeSessions.get(sessionId);
156
+ if (session) {
157
+ this.sessionManager?.connect(sessionId, session.sessionToken);
158
+ }
159
+ }
160
+ }
161
+ };
162
+
163
+ // src/tools/consumer-tools.ts
164
+ import { z } from "zod";
165
+ function registerConsumerTools(server, client) {
166
+ server.tool(
167
+ "clawrent_browse",
168
+ "Browse available agents on the ClawRent marketplace",
169
+ {
170
+ search: z.string().optional().describe("Search agents by name"),
171
+ category: z.string().optional().describe("Filter by category"),
172
+ page: z.number().optional().describe("Page number (default: 1)"),
173
+ limit: z.number().optional().describe("Results per page (default: 20)")
174
+ },
175
+ async ({ search, category, page, limit }) => {
176
+ const result = await client.browse({ search, category, page, limit });
177
+ return {
178
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
179
+ };
180
+ }
181
+ );
182
+ server.tool(
183
+ "clawrent_agent_details",
184
+ "Get detailed information about a specific agent by its slug",
185
+ {
186
+ slug: z.string().describe("Agent slug (URL-friendly identifier)")
187
+ },
188
+ async ({ slug }) => {
189
+ const result = await client.getAgent(slug);
190
+ return {
191
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
192
+ };
193
+ }
194
+ );
195
+ server.tool(
196
+ "clawrent_rent_agent",
197
+ "Rent an agent by creating a new session. Returns session details including sessionId and sessionToken.",
198
+ {
199
+ agentId: z.string().describe("ID of the agent to rent"),
200
+ taskDescription: z.string().describe("Description of the task (10-2000 chars)"),
201
+ permissions: z.string().optional().describe("Granted permissions as JSON string (default: {})")
202
+ },
203
+ async ({ agentId, taskDescription, permissions }) => {
204
+ let grantedPermissions = {};
205
+ if (permissions) {
206
+ try {
207
+ grantedPermissions = JSON.parse(permissions);
208
+ } catch {
209
+ return {
210
+ content: [{ type: "text", text: "Error: Invalid JSON for permissions" }],
211
+ isError: true
212
+ };
213
+ }
214
+ }
215
+ const result = await client.rent({ agentId, taskDescription, grantedPermissions });
216
+ return {
217
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
218
+ };
219
+ }
220
+ );
221
+ server.tool(
222
+ "clawrent_list_sessions",
223
+ "List your sessions on the platform",
224
+ {
225
+ role: z.string().optional().describe("Filter by role: consumer or provider"),
226
+ status: z.string().optional().describe("Filter by status (e.g., active, completed, pending_approval)"),
227
+ page: z.number().optional().describe("Page number"),
228
+ limit: z.number().optional().describe("Results per page")
229
+ },
230
+ async ({ role, status, page, limit }) => {
231
+ const result = await client.getSessions({ role, status, page, limit });
232
+ return {
233
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
234
+ };
235
+ }
236
+ );
237
+ server.tool(
238
+ "clawrent_end_session",
239
+ "End an active session. Triggers billing settlement.",
240
+ {
241
+ sessionId: z.string().describe("ID of the session to end")
242
+ },
243
+ async ({ sessionId }) => {
244
+ const result = await client.endSession(sessionId);
245
+ return {
246
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
247
+ };
248
+ }
249
+ );
250
+ server.tool(
251
+ "clawrent_session_messages",
252
+ "Get message history for a session",
253
+ {
254
+ sessionId: z.string().describe("Session ID")
255
+ },
256
+ async ({ sessionId }) => {
257
+ const result = await client.getSessionMessages(sessionId);
258
+ return {
259
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
260
+ };
261
+ }
262
+ );
263
+ server.tool(
264
+ "clawrent_check_balance",
265
+ "Check your wallet balance on the ClawRent platform",
266
+ {},
267
+ async () => {
268
+ const result = await client.getBalance();
269
+ return {
270
+ content: [{ type: "text", text: `Balance: ${result.balance}` }]
271
+ };
272
+ }
273
+ );
274
+ server.tool(
275
+ "clawrent_topup",
276
+ "Top up your wallet balance",
277
+ {
278
+ amount: z.string().describe('Amount to top up (e.g., "100.00")')
279
+ },
280
+ async ({ amount }) => {
281
+ const result = await client.topUp(amount);
282
+ return {
283
+ content: [{ type: "text", text: `New balance: ${result.balance}` }]
284
+ };
285
+ }
286
+ );
287
+ server.tool(
288
+ "clawrent_create_order",
289
+ "Create an order to rent one or more agents. Each item creates an associated session. Optionally checkout from cart.",
290
+ {
291
+ items: z.string().describe('JSON array of order items: [{"providerAgentId":"...","taskDescription":"...","consumerAgentId":"..."}]'),
292
+ note: z.string().optional().describe("Order note"),
293
+ fromCart: z.boolean().optional().describe("If true, clear cart after order creation")
294
+ },
295
+ async ({ items, note, fromCart }) => {
296
+ let parsedItems;
297
+ try {
298
+ parsedItems = JSON.parse(items);
299
+ } catch {
300
+ return {
301
+ content: [{ type: "text", text: "Error: Invalid JSON for items array" }],
302
+ isError: true
303
+ };
304
+ }
305
+ const result = await client.createOrder({ items: parsedItems, note, fromCart });
306
+ return {
307
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
308
+ };
309
+ }
310
+ );
311
+ server.tool(
312
+ "clawrent_list_orders",
313
+ "List your orders",
314
+ {
315
+ status: z.string().optional().describe("Filter by status (pending, active, completed, cancelled)"),
316
+ page: z.number().optional().describe("Page number"),
317
+ limit: z.number().optional().describe("Results per page")
318
+ },
319
+ async ({ status, page, limit }) => {
320
+ const result = await client.getOrders({ status, page, limit });
321
+ return {
322
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
323
+ };
324
+ }
325
+ );
326
+ server.tool(
327
+ "clawrent_order_detail",
328
+ "Get detailed information about a specific order including its items",
329
+ {
330
+ orderId: z.string().describe("Order ID")
331
+ },
332
+ async ({ orderId }) => {
333
+ const result = await client.getOrder(orderId);
334
+ return {
335
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
336
+ };
337
+ }
338
+ );
339
+ server.tool(
340
+ "clawrent_cancel_order",
341
+ "Cancel an order. Only pending/active orders can be cancelled.",
342
+ {
343
+ orderId: z.string().describe("Order ID")
344
+ },
345
+ async ({ orderId }) => {
346
+ const result = await client.cancelOrder(orderId);
347
+ return {
348
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
349
+ };
350
+ }
351
+ );
352
+ server.tool(
353
+ "clawrent_list_cart",
354
+ "View your shopping cart items",
355
+ {},
356
+ async () => {
357
+ const result = await client.getCart();
358
+ return {
359
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
360
+ };
361
+ }
362
+ );
363
+ server.tool(
364
+ "clawrent_add_to_cart",
365
+ "Add an agent to your shopping cart",
366
+ {
367
+ providerAgentId: z.string().describe("Agent ID to add"),
368
+ taskDescription: z.string().describe("Task description for the agent (10-2000 chars)")
369
+ },
370
+ async ({ providerAgentId, taskDescription }) => {
371
+ const result = await client.addToCart({ providerAgentId, taskDescription });
372
+ return {
373
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
374
+ };
375
+ }
376
+ );
377
+ server.tool(
378
+ "clawrent_remove_from_cart",
379
+ "Remove a specific item from the shopping cart",
380
+ {
381
+ itemId: z.string().describe("Cart item ID to remove")
382
+ },
383
+ async ({ itemId }) => {
384
+ const result = await client.removeFromCart(itemId);
385
+ return {
386
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
387
+ };
388
+ }
389
+ );
390
+ server.tool(
391
+ "clawrent_clear_cart",
392
+ "Clear all items from the shopping cart",
393
+ {},
394
+ async () => {
395
+ const result = await client.clearCart();
396
+ return {
397
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
398
+ };
399
+ }
400
+ );
401
+ server.tool(
402
+ "clawrent_add_favorite",
403
+ "Add an agent to your favorites",
404
+ {
405
+ agentId: z.string().describe("Agent ID to favorite")
406
+ },
407
+ async ({ agentId }) => {
408
+ const result = await client.addFavorite(agentId);
409
+ return {
410
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
411
+ };
412
+ }
413
+ );
414
+ server.tool(
415
+ "clawrent_remove_favorite",
416
+ "Remove an agent from your favorites",
417
+ {
418
+ agentId: z.string().describe("Agent ID to unfavorite")
419
+ },
420
+ async ({ agentId }) => {
421
+ const result = await client.removeFavorite(agentId);
422
+ return {
423
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
424
+ };
425
+ }
426
+ );
427
+ server.tool(
428
+ "clawrent_list_favorites",
429
+ "List your favorited agents",
430
+ {
431
+ page: z.number().optional().describe("Page number"),
432
+ limit: z.number().optional().describe("Results per page")
433
+ },
434
+ async ({ page, limit }) => {
435
+ const result = await client.listFavorites({ page, limit });
436
+ return {
437
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
438
+ };
439
+ }
440
+ );
441
+ }
442
+
443
+ // src/tools/provider-tools.ts
444
+ import { z as z2 } from "zod";
445
+ function registerProviderTools(server, client, providerAgent) {
446
+ server.tool(
447
+ "clawrent_register_agent",
448
+ "Register a new agent on the ClawRent platform",
449
+ {
450
+ name: z2.string().describe("Agent name (1-100 chars)"),
451
+ slug: z2.string().describe("URL-friendly slug (lowercase, hyphens)"),
452
+ description: z2.string().describe("Agent description (10-500 chars)"),
453
+ longDescription: z2.string().optional().describe("Detailed description (max 5000 chars)"),
454
+ pricingModel: z2.enum(["per_token", "per_session", "per_minute"]).optional().describe("Pricing model (default: per_session)"),
455
+ priceAmount: z2.string().optional().describe("Price amount (default: 1.00)"),
456
+ currency: z2.enum(["CNY", "USD"]).optional().describe("Currency (default: CNY)"),
457
+ hostingType: z2.enum(["self_hosted", "platform_hosted"]).optional().describe("Hosting type (default: self_hosted)"),
458
+ approvalMode: z2.enum(["manual", "auto"]).optional().describe("Session approval mode (default: manual)"),
459
+ maxConcurrentSessions: z2.number().optional().describe("Max concurrent sessions (default: 5)")
460
+ },
461
+ async (params) => {
462
+ const data = {
463
+ name: params.name,
464
+ slug: params.slug,
465
+ description: params.description
466
+ };
467
+ if (params.longDescription) data["longDescription"] = params.longDescription;
468
+ if (params.pricingModel) data["pricingModel"] = params.pricingModel;
469
+ if (params.priceAmount) data["priceAmount"] = params.priceAmount;
470
+ if (params.currency) data["currency"] = params.currency;
471
+ if (params.hostingType) data["hostingType"] = params.hostingType;
472
+ if (params.approvalMode) data["approvalMode"] = params.approvalMode;
473
+ if (params.maxConcurrentSessions) data["maxConcurrentSessions"] = params.maxConcurrentSessions;
474
+ const result = await client.registerAgent(data);
475
+ return {
476
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
477
+ };
478
+ }
479
+ );
480
+ server.tool(
481
+ "clawrent_publish_agent",
482
+ "Publish an agent (changes status from draft to pending_review)",
483
+ {
484
+ agentId: z2.string().describe("Agent ID")
485
+ },
486
+ async ({ agentId }) => {
487
+ const result = await client.publishAgent(agentId);
488
+ return {
489
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
490
+ };
491
+ }
492
+ );
493
+ server.tool(
494
+ "clawrent_activate_agent",
495
+ "Activate an agent (changes status from pending_review to active). Requires agent token and active WS connection.",
496
+ {
497
+ agentId: z2.string().describe("Agent ID")
498
+ },
499
+ async ({ agentId }) => {
500
+ const result = await client.activateAgent(agentId);
501
+ return {
502
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
503
+ };
504
+ }
505
+ );
506
+ server.tool(
507
+ "clawrent_set_agent_status",
508
+ "Set agent online status (online, offline, or busy)",
509
+ {
510
+ agentId: z2.string().describe("Agent ID"),
511
+ onlineStatus: z2.enum(["online", "offline", "busy"]).describe("Target online status")
512
+ },
513
+ async ({ agentId, onlineStatus }) => {
514
+ const result = await client.setOnlineStatus(agentId, onlineStatus);
515
+ return {
516
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
517
+ };
518
+ }
519
+ );
520
+ server.tool(
521
+ "clawrent_list_my_agents",
522
+ "List agents owned by the current user",
523
+ {
524
+ status: z2.string().optional().describe("Filter by status (draft, pending_review, active, suspended)"),
525
+ page: z2.number().optional().describe("Page number"),
526
+ limit: z2.number().optional().describe("Results per page")
527
+ },
528
+ async ({ status, page, limit }) => {
529
+ const result = await client.getMyAgents({ status, page, limit });
530
+ return {
531
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
532
+ };
533
+ }
534
+ );
535
+ server.tool(
536
+ "clawrent_approve_session",
537
+ "Approve a pending session request",
538
+ {
539
+ sessionId: z2.string().describe("Session ID to approve")
540
+ },
541
+ async ({ sessionId }) => {
542
+ const result = await client.approveSession(sessionId);
543
+ return {
544
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
545
+ };
546
+ }
547
+ );
548
+ server.tool(
549
+ "clawrent_generate_agent_token",
550
+ "Generate or regenerate an agent token for WebSocket authentication. The token is shown only once.",
551
+ {
552
+ agentId: z2.string().describe("Agent ID")
553
+ },
554
+ async ({ agentId }) => {
555
+ const result = await client.generateAgentToken(agentId);
556
+ return {
557
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
558
+ };
559
+ }
560
+ );
561
+ server.tool(
562
+ "clawrent_revoke_agent_token",
563
+ "Revoke an agent token. The agent will be disconnected and cannot reconnect until a new token is generated.",
564
+ {
565
+ agentId: z2.string().describe("Agent ID")
566
+ },
567
+ async ({ agentId }) => {
568
+ const result = await client.revokeAgentToken(agentId);
569
+ return {
570
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
571
+ };
572
+ }
573
+ );
574
+ server.tool(
575
+ "clawrent_start_serving",
576
+ "Start serving as a provider agent. Connects to the platform via WebSocket in-process (no subprocess). Listens for incoming session requests and auto-approves them if enabled.",
577
+ {
578
+ agentId: z2.string().describe("Agent ID to serve"),
579
+ agentToken: z2.string().describe("Agent token for WebSocket authentication"),
580
+ autoApprove: z2.boolean().optional().describe("Automatically approve incoming sessions (default: true)")
581
+ },
582
+ async ({ agentId, agentToken, autoApprove }) => {
583
+ if (providerAgent.running) {
584
+ return {
585
+ content: [{ type: "text", text: `Already serving agent ${providerAgent.currentAgentId}. Stop it first with clawrent_stop_serving.` }],
586
+ isError: true
587
+ };
588
+ }
589
+ try {
590
+ await providerAgent.start(agentId, agentToken, autoApprove ?? true);
591
+ return {
592
+ content: [{
593
+ type: "text",
594
+ text: `Agent ${agentId} is now serving in-process.
595
+ Auto-approve: ${autoApprove ?? true}
596
+ Waiting for incoming sessions via /ws/agent channel.`
597
+ }]
598
+ };
599
+ } catch (err) {
600
+ return {
601
+ content: [{ type: "text", text: `Failed to start serving: ${err instanceof Error ? err.message : String(err)}` }],
602
+ isError: true
603
+ };
604
+ }
605
+ }
606
+ );
607
+ server.tool(
608
+ "clawrent_stop_serving",
609
+ "Stop the in-process provider agent. Disconnects all sessions and the agent control channel.",
610
+ {},
611
+ async () => {
612
+ if (!providerAgent.running) {
613
+ return {
614
+ content: [{ type: "text", text: "No agent is currently serving." }]
615
+ };
616
+ }
617
+ const agentId = providerAgent.currentAgentId;
618
+ providerAgent.stop();
619
+ return {
620
+ content: [{ type: "text", text: `Agent ${agentId} stopped serving.` }]
621
+ };
622
+ }
623
+ );
624
+ server.tool(
625
+ "clawrent_send_session_message",
626
+ "Send a message to an active session as the provider agent. Requires clawrent_start_serving to be active.",
627
+ {
628
+ sessionId: z2.string().describe("Session ID"),
629
+ type: z2.string().optional().describe("Message type (default: result.success)"),
630
+ payload: z2.string().describe("Message payload as JSON string")
631
+ },
632
+ async ({ sessionId, type, payload }) => {
633
+ if (!providerAgent.running) {
634
+ return {
635
+ content: [{ type: "text", text: "No agent is currently serving. Start with clawrent_start_serving first." }],
636
+ isError: true
637
+ };
638
+ }
639
+ let parsedPayload;
640
+ try {
641
+ parsedPayload = JSON.parse(payload);
642
+ } catch {
643
+ return {
644
+ content: [{ type: "text", text: "Error: Invalid JSON for payload" }],
645
+ isError: true
646
+ };
647
+ }
648
+ const sent = providerAgent.send(sessionId, {
649
+ type: type ?? "result.success",
650
+ payload: parsedPayload
651
+ });
652
+ if (!sent) {
653
+ return {
654
+ content: [{ type: "text", text: `Session ${sessionId} is not connected or not found.` }],
655
+ isError: true
656
+ };
657
+ }
658
+ return {
659
+ content: [{ type: "text", text: `Message sent to session ${sessionId}.` }]
660
+ };
661
+ }
662
+ );
663
+ server.tool(
664
+ "clawrent_serving_status",
665
+ "Check the current serving status: whether an agent is active, which sessions are connected.",
666
+ {},
667
+ async () => {
668
+ if (!providerAgent.running) {
669
+ return {
670
+ content: [{ type: "text", text: JSON.stringify({ serving: false }, null, 2) }]
671
+ };
672
+ }
673
+ const sessions = providerAgent.getSessions();
674
+ return {
675
+ content: [{
676
+ type: "text",
677
+ text: JSON.stringify({
678
+ serving: true,
679
+ agentId: providerAgent.currentAgentId,
680
+ activeSessions: sessions.length,
681
+ sessions: sessions.map((s) => ({
682
+ sessionId: s.sessionId,
683
+ taskDescription: s.taskDescription,
684
+ consumerUserId: s.consumerUserId
685
+ }))
686
+ }, null, 2)
687
+ }]
688
+ };
689
+ }
690
+ );
691
+ }
692
+
693
+ // src/index.ts
694
+ async function main() {
695
+ const config = loadConfig();
696
+ const client = new ApiClient2(config);
697
+ const providerAgent = new ProviderAgent(client);
698
+ const server = new McpServer({
699
+ name: "clawrent",
700
+ version: "0.1.0"
701
+ });
702
+ registerConsumerTools(server, client);
703
+ registerProviderTools(server, client, providerAgent);
704
+ process.on("SIGINT", () => {
705
+ providerAgent.stop();
706
+ process.exit(0);
707
+ });
708
+ process.on("SIGTERM", () => {
709
+ providerAgent.stop();
710
+ process.exit(0);
711
+ });
712
+ const transport = new StdioServerTransport();
713
+ await server.connect(transport);
714
+ }
715
+ main().catch((err) => {
716
+ process.stderr.write(`MCP Server error: ${err instanceof Error ? err.message : String(err)}
717
+ `);
718
+ process.exit(1);
719
+ });
720
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/provider-agent.ts","../src/tools/consumer-tools.ts","../src/tools/provider-tools.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { ApiClient, loadConfig } from '@clawrent/cli';\r\nimport { ProviderAgent } from './provider-agent.js';\r\nimport { registerConsumerTools } from './tools/consumer-tools.js';\r\nimport { registerProviderTools } from './tools/provider-tools.js';\r\n\r\nasync function main(): Promise<void> {\r\n const config = loadConfig();\r\n const client = new ApiClient(config);\r\n\r\n // In-process provider agent (shared singleton across all provider tools)\r\n const providerAgent = new ProviderAgent(client);\r\n\r\n const server = new McpServer({\r\n name: 'clawrent',\r\n version: '0.1.0',\r\n });\r\n\r\n // Register all tools\r\n registerConsumerTools(server, client);\r\n registerProviderTools(server, client, providerAgent);\r\n\r\n // Cleanup on exit\r\n process.on('SIGINT', () => {\r\n providerAgent.stop();\r\n process.exit(0);\r\n });\r\n process.on('SIGTERM', () => {\r\n providerAgent.stop();\r\n process.exit(0);\r\n });\r\n\r\n // Connect via stdio transport\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n}\r\n\r\nmain().catch((err) => {\r\n process.stderr.write(`MCP Server error: ${err instanceof Error ? err.message : String(err)}\\n`);\r\n process.exit(1);\r\n});\r\n","import { EventEmitter } from 'node:events';\r\nimport WebSocket from 'ws';\r\nimport { ApiClient, SessionManager } from '@clawrent/cli';\r\n\r\nexport interface ActiveSession {\r\n sessionId: string;\r\n sessionToken: string;\r\n taskDescription: string;\r\n consumerUserId?: string;\r\n}\r\n\r\n/**\r\n * ProviderAgent runs an in-process WebSocket connection to the\r\n * /ws/agent control channel, replacing the need to spawn a CLI subprocess.\r\n * It manages session lifecycle and delegates session-level WS to SessionManager.\r\n */\r\nexport class ProviderAgent extends EventEmitter {\r\n private client: ApiClient;\r\n private agentWs: WebSocket | null = null;\r\n private sessionManager: SessionManager | null = null;\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\r\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\n private reconnectAttempts = 0;\r\n private maxReconnectDelay = 30_000;\r\n private _running = false;\r\n\r\n private agentId: string | null = null;\r\n private agentToken: string | null = null;\r\n private autoApprove = false;\r\n private activeSessions = new Map<string, ActiveSession>();\r\n\r\n constructor(client: ApiClient) {\r\n super();\r\n this.client = client;\r\n }\r\n\r\n get running(): boolean {\r\n return this._running;\r\n }\r\n\r\n get currentAgentId(): string | null {\r\n return this.agentId;\r\n }\r\n\r\n getSessions(): ActiveSession[] {\r\n return Array.from(this.activeSessions.values());\r\n }\r\n\r\n /**\r\n * Start the in-process agent: connect to /ws/agent and listen for sessions.\r\n */\r\n async start(agentId: string, agentToken: string, autoApprove = false): Promise<void> {\r\n if (this._running) {\r\n throw new Error(`Already serving agent ${this.agentId}`);\r\n }\r\n\r\n this.agentId = agentId;\r\n this.agentToken = agentToken;\r\n this.autoApprove = autoApprove;\r\n this._running = true;\r\n this.reconnectAttempts = 0;\r\n\r\n // Create session manager for per-session WS connections\r\n this.sessionManager = new SessionManager(this.client.wsUrl);\r\n this.sessionManager.agentId = agentId;\r\n\r\n this.sessionManager.on('session:connected', (sessionId: string) => {\r\n this.emit('session:connected', sessionId);\r\n });\r\n\r\n this.sessionManager.on('session:message', (sessionId: string, message: Record<string, unknown>) => {\r\n this.emit('session:message', sessionId, message);\r\n });\r\n\r\n this.sessionManager.on('session:disconnected', (sessionId: string) => {\r\n this.activeSessions.delete(sessionId);\r\n this.emit('session:disconnected', sessionId);\r\n });\r\n\r\n this.connectAgent();\r\n }\r\n\r\n /**\r\n * Stop the agent: disconnect all sessions and the control channel.\r\n */\r\n stop(): void {\r\n this._running = false;\r\n\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n if (this.reconnectTimer) {\r\n clearTimeout(this.reconnectTimer);\r\n this.reconnectTimer = null;\r\n }\r\n\r\n this.sessionManager?.disconnectAll();\r\n this.sessionManager = null;\r\n\r\n if (this.agentWs && (this.agentWs.readyState === WebSocket.OPEN || this.agentWs.readyState === WebSocket.CONNECTING)) {\r\n this.agentWs.close(1000, 'Agent stopping');\r\n }\r\n this.agentWs = null;\r\n\r\n this.activeSessions.clear();\r\n this.agentId = null;\r\n this.agentToken = null;\r\n\r\n this.emit('stopped');\r\n }\r\n\r\n /**\r\n * Send a message to a specific session.\r\n */\r\n send(sessionId: string, message: Record<string, unknown>): boolean {\r\n if (!this.sessionManager) return false;\r\n return this.sessionManager.send(sessionId, message);\r\n }\r\n\r\n private connectAgent(): void {\r\n if (!this._running || !this.agentToken) return;\r\n\r\n const url = `${this.client.wsUrl}/ws/agent?token=${this.agentToken}`;\r\n const ws = new WebSocket(url);\r\n this.agentWs = ws;\r\n\r\n ws.on('open', () => {\r\n this.reconnectAttempts = 0;\r\n this.emit('agent:connected', this.agentId);\r\n\r\n // Start heartbeat\r\n this.heartbeatTimer = setInterval(() => {\r\n if (ws.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ type: 'system.heartbeat', payload: {} }));\r\n }\r\n }, 25_000);\r\n });\r\n\r\n ws.on('message', (raw) => {\r\n try {\r\n const msg = JSON.parse(raw.toString()) as Record<string, unknown>;\r\n this.handleAgentMessage(msg);\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n });\r\n\r\n ws.on('close', (code) => {\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n this.heartbeatTimer = null;\r\n }\r\n\r\n this.emit('agent:disconnected', this.agentId);\r\n\r\n // Reconnect on abnormal close if still running\r\n if (this._running && code !== 1000) {\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), this.maxReconnectDelay);\r\n this.reconnectAttempts++;\r\n this.reconnectTimer = setTimeout(() => this.connectAgent(), delay);\r\n }\r\n });\r\n\r\n ws.on('error', (err) => {\r\n this.emit('agent:error', err);\r\n });\r\n }\r\n\r\n private handleAgentMessage(msg: Record<string, unknown>): void {\r\n const type = msg['type'] as string;\r\n\r\n if (type === 'system.heartbeat_ack') return;\r\n\r\n if (type === 'session.new') {\r\n const payload = msg['payload'] as Record<string, unknown>;\r\n const sessionId = payload['sessionId'] as string;\r\n const sessionToken = payload['sessionToken'] as string;\r\n const taskDescription = (payload['taskDescription'] as string) || '';\r\n const consumerUserId = payload['consumerUserId'] as string | undefined;\r\n\r\n const session: ActiveSession = { sessionId, sessionToken, taskDescription, consumerUserId };\r\n this.activeSessions.set(sessionId, session);\r\n\r\n this.emit('session:new', session);\r\n\r\n if (this.autoApprove) {\r\n // Auto-approve and connect\r\n this.client.approveSession(sessionId).then(() => {\r\n this.sessionManager?.connect(sessionId, sessionToken);\r\n this.emit('session:approved', sessionId);\r\n }).catch((err) => {\r\n this.emit('session:error', sessionId, err);\r\n });\r\n }\r\n } else if (type === 'session.approved') {\r\n const payload = msg['payload'] as Record<string, unknown>;\r\n const sessionId = payload['sessionId'] as string;\r\n const session = this.activeSessions.get(sessionId);\r\n if (session) {\r\n this.sessionManager?.connect(sessionId, session.sessionToken);\r\n }\r\n }\r\n }\r\n}\r\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { z } from 'zod';\r\nimport type { ApiClient } from '@clawrent/cli';\r\n\r\nexport function registerConsumerTools(server: McpServer, client: ApiClient): void {\r\n // --- Marketplace ---\r\n\r\n server.tool(\r\n 'clawrent_browse',\r\n 'Browse available agents on the ClawRent marketplace',\r\n {\r\n search: z.string().optional().describe('Search agents by name'),\r\n category: z.string().optional().describe('Filter by category'),\r\n page: z.number().optional().describe('Page number (default: 1)'),\r\n limit: z.number().optional().describe('Results per page (default: 20)'),\r\n },\r\n async ({ search, category, page, limit }) => {\r\n const result = await client.browse({ search, category, page, limit });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_agent_details',\r\n 'Get detailed information about a specific agent by its slug',\r\n {\r\n slug: z.string().describe('Agent slug (URL-friendly identifier)'),\r\n },\r\n async ({ slug }) => {\r\n const result = await client.getAgent(slug);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- Sessions ---\r\n\r\n server.tool(\r\n 'clawrent_rent_agent',\r\n 'Rent an agent by creating a new session. Returns session details including sessionId and sessionToken.',\r\n {\r\n agentId: z.string().describe('ID of the agent to rent'),\r\n taskDescription: z.string().describe('Description of the task (10-2000 chars)'),\r\n permissions: z.string().optional().describe('Granted permissions as JSON string (default: {})'),\r\n },\r\n async ({ agentId, taskDescription, permissions }) => {\r\n let grantedPermissions: Record<string, unknown> = {};\r\n if (permissions) {\r\n try {\r\n grantedPermissions = JSON.parse(permissions) as Record<string, unknown>;\r\n } catch {\r\n return {\r\n content: [{ type: 'text' as const, text: 'Error: Invalid JSON for permissions' }],\r\n isError: true,\r\n };\r\n }\r\n }\r\n const result = await client.rent({ agentId, taskDescription, grantedPermissions });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_list_sessions',\r\n 'List your sessions on the platform',\r\n {\r\n role: z.string().optional().describe('Filter by role: consumer or provider'),\r\n status: z.string().optional().describe('Filter by status (e.g., active, completed, pending_approval)'),\r\n page: z.number().optional().describe('Page number'),\r\n limit: z.number().optional().describe('Results per page'),\r\n },\r\n async ({ role, status, page, limit }) => {\r\n const result = await client.getSessions({ role, status, page, limit });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_end_session',\r\n 'End an active session. Triggers billing settlement.',\r\n {\r\n sessionId: z.string().describe('ID of the session to end'),\r\n },\r\n async ({ sessionId }) => {\r\n const result = await client.endSession(sessionId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_session_messages',\r\n 'Get message history for a session',\r\n {\r\n sessionId: z.string().describe('Session ID'),\r\n },\r\n async ({ sessionId }) => {\r\n const result = await client.getSessionMessages(sessionId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- Billing ---\r\n\r\n server.tool(\r\n 'clawrent_check_balance',\r\n 'Check your wallet balance on the ClawRent platform',\r\n {},\r\n async () => {\r\n const result = await client.getBalance();\r\n return {\r\n content: [{ type: 'text' as const, text: `Balance: ${result.balance}` }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_topup',\r\n 'Top up your wallet balance',\r\n {\r\n amount: z.string().describe('Amount to top up (e.g., \"100.00\")'),\r\n },\r\n async ({ amount }) => {\r\n const result = await client.topUp(amount);\r\n return {\r\n content: [{ type: 'text' as const, text: `New balance: ${result.balance}` }],\r\n };\r\n },\r\n );\r\n\r\n // --- Orders ---\r\n\r\n server.tool(\r\n 'clawrent_create_order',\r\n 'Create an order to rent one or more agents. Each item creates an associated session. Optionally checkout from cart.',\r\n {\r\n items: z.string().describe('JSON array of order items: [{\"providerAgentId\":\"...\",\"taskDescription\":\"...\",\"consumerAgentId\":\"...\"}]'),\r\n note: z.string().optional().describe('Order note'),\r\n fromCart: z.boolean().optional().describe('If true, clear cart after order creation'),\r\n },\r\n async ({ items, note, fromCart }) => {\r\n let parsedItems: Array<{ providerAgentId: string; consumerAgentId?: string; taskDescription: string }>;\r\n try {\r\n parsedItems = JSON.parse(items) as typeof parsedItems;\r\n } catch {\r\n return {\r\n content: [{ type: 'text' as const, text: 'Error: Invalid JSON for items array' }],\r\n isError: true,\r\n };\r\n }\r\n const result = await client.createOrder({ items: parsedItems, note, fromCart });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_list_orders',\r\n 'List your orders',\r\n {\r\n status: z.string().optional().describe('Filter by status (pending, active, completed, cancelled)'),\r\n page: z.number().optional().describe('Page number'),\r\n limit: z.number().optional().describe('Results per page'),\r\n },\r\n async ({ status, page, limit }) => {\r\n const result = await client.getOrders({ status, page, limit });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_order_detail',\r\n 'Get detailed information about a specific order including its items',\r\n {\r\n orderId: z.string().describe('Order ID'),\r\n },\r\n async ({ orderId }) => {\r\n const result = await client.getOrder(orderId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_cancel_order',\r\n 'Cancel an order. Only pending/active orders can be cancelled.',\r\n {\r\n orderId: z.string().describe('Order ID'),\r\n },\r\n async ({ orderId }) => {\r\n const result = await client.cancelOrder(orderId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- Cart ---\r\n\r\n server.tool(\r\n 'clawrent_list_cart',\r\n 'View your shopping cart items',\r\n {},\r\n async () => {\r\n const result = await client.getCart();\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_add_to_cart',\r\n 'Add an agent to your shopping cart',\r\n {\r\n providerAgentId: z.string().describe('Agent ID to add'),\r\n taskDescription: z.string().describe('Task description for the agent (10-2000 chars)'),\r\n },\r\n async ({ providerAgentId, taskDescription }) => {\r\n const result = await client.addToCart({ providerAgentId, taskDescription });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_remove_from_cart',\r\n 'Remove a specific item from the shopping cart',\r\n {\r\n itemId: z.string().describe('Cart item ID to remove'),\r\n },\r\n async ({ itemId }) => {\r\n const result = await client.removeFromCart(itemId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_clear_cart',\r\n 'Clear all items from the shopping cart',\r\n {},\r\n async () => {\r\n const result = await client.clearCart();\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- Favorites ---\r\n\r\n server.tool(\r\n 'clawrent_add_favorite',\r\n 'Add an agent to your favorites',\r\n {\r\n agentId: z.string().describe('Agent ID to favorite'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.addFavorite(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_remove_favorite',\r\n 'Remove an agent from your favorites',\r\n {\r\n agentId: z.string().describe('Agent ID to unfavorite'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.removeFavorite(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_list_favorites',\r\n 'List your favorited agents',\r\n {\r\n page: z.number().optional().describe('Page number'),\r\n limit: z.number().optional().describe('Results per page'),\r\n },\r\n async ({ page, limit }) => {\r\n const result = await client.listFavorites({ page, limit });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n}\r\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\r\nimport { z } from 'zod';\r\nimport type { ApiClient } from '@clawrent/cli';\r\nimport type { ProviderAgent } from '../provider-agent.js';\r\n\r\nexport function registerProviderTools(server: McpServer, client: ApiClient, providerAgent: ProviderAgent): void {\r\n server.tool(\r\n 'clawrent_register_agent',\r\n 'Register a new agent on the ClawRent platform',\r\n {\r\n name: z.string().describe('Agent name (1-100 chars)'),\r\n slug: z.string().describe('URL-friendly slug (lowercase, hyphens)'),\r\n description: z.string().describe('Agent description (10-500 chars)'),\r\n longDescription: z.string().optional().describe('Detailed description (max 5000 chars)'),\r\n pricingModel: z.enum(['per_token', 'per_session', 'per_minute']).optional().describe('Pricing model (default: per_session)'),\r\n priceAmount: z.string().optional().describe('Price amount (default: 1.00)'),\r\n currency: z.enum(['CNY', 'USD']).optional().describe('Currency (default: CNY)'),\r\n hostingType: z.enum(['self_hosted', 'platform_hosted']).optional().describe('Hosting type (default: self_hosted)'),\r\n approvalMode: z.enum(['manual', 'auto']).optional().describe('Session approval mode (default: manual)'),\r\n maxConcurrentSessions: z.number().optional().describe('Max concurrent sessions (default: 5)'),\r\n },\r\n async (params) => {\r\n const data: Record<string, unknown> = {\r\n name: params.name,\r\n slug: params.slug,\r\n description: params.description,\r\n };\r\n if (params.longDescription) data['longDescription'] = params.longDescription;\r\n if (params.pricingModel) data['pricingModel'] = params.pricingModel;\r\n if (params.priceAmount) data['priceAmount'] = params.priceAmount;\r\n if (params.currency) data['currency'] = params.currency;\r\n if (params.hostingType) data['hostingType'] = params.hostingType;\r\n if (params.approvalMode) data['approvalMode'] = params.approvalMode;\r\n if (params.maxConcurrentSessions) data['maxConcurrentSessions'] = params.maxConcurrentSessions;\r\n\r\n const result = await client.registerAgent(data);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_publish_agent',\r\n 'Publish an agent (changes status from draft to pending_review)',\r\n {\r\n agentId: z.string().describe('Agent ID'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.publishAgent(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_activate_agent',\r\n 'Activate an agent (changes status from pending_review to active). Requires agent token and active WS connection.',\r\n {\r\n agentId: z.string().describe('Agent ID'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.activateAgent(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_set_agent_status',\r\n 'Set agent online status (online, offline, or busy)',\r\n {\r\n agentId: z.string().describe('Agent ID'),\r\n onlineStatus: z.enum(['online', 'offline', 'busy']).describe('Target online status'),\r\n },\r\n async ({ agentId, onlineStatus }) => {\r\n const result = await client.setOnlineStatus(agentId, onlineStatus);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_list_my_agents',\r\n 'List agents owned by the current user',\r\n {\r\n status: z.string().optional().describe('Filter by status (draft, pending_review, active, suspended)'),\r\n page: z.number().optional().describe('Page number'),\r\n limit: z.number().optional().describe('Results per page'),\r\n },\r\n async ({ status, page, limit }) => {\r\n const result = await client.getMyAgents({ status, page, limit });\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_approve_session',\r\n 'Approve a pending session request',\r\n {\r\n sessionId: z.string().describe('Session ID to approve'),\r\n },\r\n async ({ sessionId }) => {\r\n const result = await client.approveSession(sessionId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- Token Management ---\r\n\r\n server.tool(\r\n 'clawrent_generate_agent_token',\r\n 'Generate or regenerate an agent token for WebSocket authentication. The token is shown only once.',\r\n {\r\n agentId: z.string().describe('Agent ID'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.generateAgentToken(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_revoke_agent_token',\r\n 'Revoke an agent token. The agent will be disconnected and cannot reconnect until a new token is generated.',\r\n {\r\n agentId: z.string().describe('Agent ID'),\r\n },\r\n async ({ agentId }) => {\r\n const result = await client.revokeAgentToken(agentId);\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],\r\n };\r\n },\r\n );\r\n\r\n // --- In-process Serve ---\r\n\r\n server.tool(\r\n 'clawrent_start_serving',\r\n 'Start serving as a provider agent. Connects to the platform via WebSocket in-process (no subprocess). Listens for incoming session requests and auto-approves them if enabled.',\r\n {\r\n agentId: z.string().describe('Agent ID to serve'),\r\n agentToken: z.string().describe('Agent token for WebSocket authentication'),\r\n autoApprove: z.boolean().optional().describe('Automatically approve incoming sessions (default: true)'),\r\n },\r\n async ({ agentId, agentToken, autoApprove }) => {\r\n if (providerAgent.running) {\r\n return {\r\n content: [{ type: 'text' as const, text: `Already serving agent ${providerAgent.currentAgentId}. Stop it first with clawrent_stop_serving.` }],\r\n isError: true,\r\n };\r\n }\r\n\r\n try {\r\n await providerAgent.start(agentId, agentToken, autoApprove ?? true);\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: `Agent ${agentId} is now serving in-process.\\nAuto-approve: ${autoApprove ?? true}\\nWaiting for incoming sessions via /ws/agent channel.`,\r\n }],\r\n };\r\n } catch (err: unknown) {\r\n return {\r\n content: [{ type: 'text' as const, text: `Failed to start serving: ${err instanceof Error ? err.message : String(err)}` }],\r\n isError: true,\r\n };\r\n }\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_stop_serving',\r\n 'Stop the in-process provider agent. Disconnects all sessions and the agent control channel.',\r\n {},\r\n async () => {\r\n if (!providerAgent.running) {\r\n return {\r\n content: [{ type: 'text' as const, text: 'No agent is currently serving.' }],\r\n };\r\n }\r\n\r\n const agentId = providerAgent.currentAgentId;\r\n providerAgent.stop();\r\n return {\r\n content: [{ type: 'text' as const, text: `Agent ${agentId} stopped serving.` }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_send_session_message',\r\n 'Send a message to an active session as the provider agent. Requires clawrent_start_serving to be active.',\r\n {\r\n sessionId: z.string().describe('Session ID'),\r\n type: z.string().optional().describe('Message type (default: result.success)'),\r\n payload: z.string().describe('Message payload as JSON string'),\r\n },\r\n async ({ sessionId, type, payload }) => {\r\n if (!providerAgent.running) {\r\n return {\r\n content: [{ type: 'text' as const, text: 'No agent is currently serving. Start with clawrent_start_serving first.' }],\r\n isError: true,\r\n };\r\n }\r\n\r\n let parsedPayload: Record<string, unknown>;\r\n try {\r\n parsedPayload = JSON.parse(payload) as Record<string, unknown>;\r\n } catch {\r\n return {\r\n content: [{ type: 'text' as const, text: 'Error: Invalid JSON for payload' }],\r\n isError: true,\r\n };\r\n }\r\n\r\n const sent = providerAgent.send(sessionId, {\r\n type: type ?? 'result.success',\r\n payload: parsedPayload,\r\n });\r\n\r\n if (!sent) {\r\n return {\r\n content: [{ type: 'text' as const, text: `Session ${sessionId} is not connected or not found.` }],\r\n isError: true,\r\n };\r\n }\r\n\r\n return {\r\n content: [{ type: 'text' as const, text: `Message sent to session ${sessionId}.` }],\r\n };\r\n },\r\n );\r\n\r\n server.tool(\r\n 'clawrent_serving_status',\r\n 'Check the current serving status: whether an agent is active, which sessions are connected.',\r\n {},\r\n async () => {\r\n if (!providerAgent.running) {\r\n return {\r\n content: [{ type: 'text' as const, text: JSON.stringify({ serving: false }, null, 2) }],\r\n };\r\n }\r\n\r\n const sessions = providerAgent.getSessions();\r\n return {\r\n content: [{\r\n type: 'text' as const,\r\n text: JSON.stringify({\r\n serving: true,\r\n agentId: providerAgent.currentAgentId,\r\n activeSessions: sessions.length,\r\n sessions: sessions.map(s => ({\r\n sessionId: s.sessionId,\r\n taskDescription: s.taskDescription,\r\n consumerUserId: s.consumerUserId,\r\n })),\r\n }, null, 2),\r\n }],\r\n };\r\n },\r\n );\r\n}\r\n"],"mappings":";;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,aAAAA,YAAW,kBAAkB;;;ACFtC,SAAS,oBAAoB;AAC7B,OAAO,eAAe;AACtB,SAAoB,sBAAsB;AAcnC,IAAM,gBAAN,cAA4B,aAAa;AAAA,EACtC;AAAA,EACA,UAA4B;AAAA,EAC5B,iBAAwC;AAAA,EACxC,iBAAwD;AAAA,EACxD,iBAAuD;AAAA,EACvD,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,WAAW;AAAA,EAEX,UAAyB;AAAA,EACzB,aAA4B;AAAA,EAC5B,cAAc;AAAA,EACd,iBAAiB,oBAAI,IAA2B;AAAA,EAExD,YAAY,QAAmB;AAC7B,UAAM;AACN,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,iBAAgC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,cAA+B;AAC7B,WAAO,MAAM,KAAK,KAAK,eAAe,OAAO,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,SAAiB,YAAoB,cAAc,OAAsB;AACnF,QAAI,KAAK,UAAU;AACjB,YAAM,IAAI,MAAM,yBAAyB,KAAK,OAAO,EAAE;AAAA,IACzD;AAEA,SAAK,UAAU;AACf,SAAK,aAAa;AAClB,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,oBAAoB;AAGzB,SAAK,iBAAiB,IAAI,eAAe,KAAK,OAAO,KAAK;AAC1D,SAAK,eAAe,UAAU;AAE9B,SAAK,eAAe,GAAG,qBAAqB,CAAC,cAAsB;AACjE,WAAK,KAAK,qBAAqB,SAAS;AAAA,IAC1C,CAAC;AAED,SAAK,eAAe,GAAG,mBAAmB,CAAC,WAAmB,YAAqC;AACjG,WAAK,KAAK,mBAAmB,WAAW,OAAO;AAAA,IACjD,CAAC;AAED,SAAK,eAAe,GAAG,wBAAwB,CAAC,cAAsB;AACpE,WAAK,eAAe,OAAO,SAAS;AACpC,WAAK,KAAK,wBAAwB,SAAS;AAAA,IAC7C,CAAC;AAED,SAAK,aAAa;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAa;AACX,SAAK,WAAW;AAEhB,QAAI,KAAK,gBAAgB;AACvB,oBAAc,KAAK,cAAc;AACjC,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,gBAAgB;AACvB,mBAAa,KAAK,cAAc;AAChC,WAAK,iBAAiB;AAAA,IACxB;AAEA,SAAK,gBAAgB,cAAc;AACnC,SAAK,iBAAiB;AAEtB,QAAI,KAAK,YAAY,KAAK,QAAQ,eAAe,UAAU,QAAQ,KAAK,QAAQ,eAAe,UAAU,aAAa;AACpH,WAAK,QAAQ,MAAM,KAAM,gBAAgB;AAAA,IAC3C;AACA,SAAK,UAAU;AAEf,SAAK,eAAe,MAAM;AAC1B,SAAK,UAAU;AACf,SAAK,aAAa;AAElB,SAAK,KAAK,SAAS;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,WAAmB,SAA2C;AACjE,QAAI,CAAC,KAAK,eAAgB,QAAO;AACjC,WAAO,KAAK,eAAe,KAAK,WAAW,OAAO;AAAA,EACpD;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,WAAY;AAExC,UAAM,MAAM,GAAG,KAAK,OAAO,KAAK,mBAAmB,KAAK,UAAU;AAClE,UAAM,KAAK,IAAI,UAAU,GAAG;AAC5B,SAAK,UAAU;AAEf,OAAG,GAAG,QAAQ,MAAM;AAClB,WAAK,oBAAoB;AACzB,WAAK,KAAK,mBAAmB,KAAK,OAAO;AAGzC,WAAK,iBAAiB,YAAY,MAAM;AACtC,YAAI,GAAG,eAAe,UAAU,MAAM;AACpC,aAAG,KAAK,KAAK,UAAU,EAAE,MAAM,oBAAoB,SAAS,CAAC,EAAE,CAAC,CAAC;AAAA,QACnE;AAAA,MACF,GAAG,IAAM;AAAA,IACX,CAAC;AAED,OAAG,GAAG,WAAW,CAAC,QAAQ;AACxB,UAAI;AACF,cAAM,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC;AACrC,aAAK,mBAAmB,GAAG;AAAA,MAC7B,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,CAAC,SAAS;AACvB,UAAI,KAAK,gBAAgB;AACvB,sBAAc,KAAK,cAAc;AACjC,aAAK,iBAAiB;AAAA,MACxB;AAEA,WAAK,KAAK,sBAAsB,KAAK,OAAO;AAG5C,UAAI,KAAK,YAAY,SAAS,KAAM;AAClC,cAAM,QAAQ,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,KAAK,iBAAiB,GAAG,KAAK,iBAAiB;AACzF,aAAK;AACL,aAAK,iBAAiB,WAAW,MAAM,KAAK,aAAa,GAAG,KAAK;AAAA,MACnE;AAAA,IACF,CAAC;AAED,OAAG,GAAG,SAAS,CAAC,QAAQ;AACtB,WAAK,KAAK,eAAe,GAAG;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,KAAoC;AAC7D,UAAM,OAAO,IAAI,MAAM;AAEvB,QAAI,SAAS,uBAAwB;AAErC,QAAI,SAAS,eAAe;AAC1B,YAAM,UAAU,IAAI,SAAS;AAC7B,YAAM,YAAY,QAAQ,WAAW;AACrC,YAAM,eAAe,QAAQ,cAAc;AAC3C,YAAM,kBAAmB,QAAQ,iBAAiB,KAAgB;AAClE,YAAM,iBAAiB,QAAQ,gBAAgB;AAE/C,YAAM,UAAyB,EAAE,WAAW,cAAc,iBAAiB,eAAe;AAC1F,WAAK,eAAe,IAAI,WAAW,OAAO;AAE1C,WAAK,KAAK,eAAe,OAAO;AAEhC,UAAI,KAAK,aAAa;AAEpB,aAAK,OAAO,eAAe,SAAS,EAAE,KAAK,MAAM;AAC/C,eAAK,gBAAgB,QAAQ,WAAW,YAAY;AACpD,eAAK,KAAK,oBAAoB,SAAS;AAAA,QACzC,CAAC,EAAE,MAAM,CAAC,QAAQ;AAChB,eAAK,KAAK,iBAAiB,WAAW,GAAG;AAAA,QAC3C,CAAC;AAAA,MACH;AAAA,IACF,WAAW,SAAS,oBAAoB;AACtC,YAAM,UAAU,IAAI,SAAS;AAC7B,YAAM,YAAY,QAAQ,WAAW;AACrC,YAAM,UAAU,KAAK,eAAe,IAAI,SAAS;AACjD,UAAI,SAAS;AACX,aAAK,gBAAgB,QAAQ,WAAW,QAAQ,YAAY;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AACF;;;AC3MA,SAAS,SAAS;AAGX,SAAS,sBAAsB,QAAmB,QAAyB;AAGhF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,MAC7D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MAC/D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,IACxE;AAAA,IACA,OAAO,EAAE,QAAQ,UAAU,MAAM,MAAM,MAAM;AAC3C,YAAM,SAAS,MAAM,OAAO,OAAO,EAAE,QAAQ,UAAU,MAAM,MAAM,CAAC;AACpE,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM,EAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,IAClE;AAAA,IACA,OAAO,EAAE,KAAK,MAAM;AAClB,YAAM,SAAS,MAAM,OAAO,SAAS,IAAI;AACzC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,MACtD,iBAAiB,EAAE,OAAO,EAAE,SAAS,yCAAyC;AAAA,MAC9E,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,IAChG;AAAA,IACA,OAAO,EAAE,SAAS,iBAAiB,YAAY,MAAM;AACnD,UAAI,qBAA8C,CAAC;AACnD,UAAI,aAAa;AACf,YAAI;AACF,+BAAqB,KAAK,MAAM,WAAW;AAAA,QAC7C,QAAQ;AACN,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC;AAAA,YAChF,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAS,MAAM,OAAO,KAAK,EAAE,SAAS,iBAAiB,mBAAmB,CAAC;AACjF,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,MAC3E,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,MACrG,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAClD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC1D;AAAA,IACA,OAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,MAAM;AACvC,YAAM,SAAS,MAAM,OAAO,YAAY,EAAE,MAAM,QAAQ,MAAM,MAAM,CAAC;AACrE,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAW,EAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,IAC3D;AAAA,IACA,OAAO,EAAE,UAAU,MAAM;AACvB,YAAM,SAAS,MAAM,OAAO,WAAW,SAAS;AAChD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAW,EAAE,OAAO,EAAE,SAAS,YAAY;AAAA,IAC7C;AAAA,IACA,OAAO,EAAE,UAAU,MAAM;AACvB,YAAM,SAAS,MAAM,OAAO,mBAAmB,SAAS;AACxD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,WAAW;AACvC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,OAAO,OAAO,GAAG,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,IACjE;AAAA,IACA,OAAO,EAAE,OAAO,MAAM;AACpB,YAAM,SAAS,MAAM,OAAO,MAAM,MAAM;AACxC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,gBAAgB,OAAO,OAAO,GAAG,CAAC;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO,EAAE,OAAO,EAAE,SAAS,wGAAwG;AAAA,MACnI,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,YAAY;AAAA,MACjD,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,IACtF;AAAA,IACA,OAAO,EAAE,OAAO,MAAM,SAAS,MAAM;AACnC,UAAI;AACJ,UAAI;AACF,sBAAc,KAAK,MAAM,KAAK;AAAA,MAChC,QAAQ;AACN,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC;AAAA,UAChF,SAAS;AAAA,QACX;AAAA,MACF;AACA,YAAM,SAAS,MAAM,OAAO,YAAY,EAAE,OAAO,aAAa,MAAM,SAAS,CAAC;AAC9E,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,MACjG,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAClD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC1D;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM,MAAM,MAAM;AACjC,YAAM,SAAS,MAAM,OAAO,UAAU,EAAE,QAAQ,MAAM,MAAM,CAAC;AAC7D,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,SAAS,OAAO;AAC5C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,YAAY,OAAO;AAC/C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,QAAQ;AACpC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,iBAAiB,EAAE,OAAO,EAAE,SAAS,iBAAiB;AAAA,MACtD,iBAAiB,EAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,IACvF;AAAA,IACA,OAAO,EAAE,iBAAiB,gBAAgB,MAAM;AAC9C,YAAM,SAAS,MAAM,OAAO,UAAU,EAAE,iBAAiB,gBAAgB,CAAC;AAC1E,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ,EAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,IACtD;AAAA,IACA,OAAO,EAAE,OAAO,MAAM;AACpB,YAAM,SAAS,MAAM,OAAO,eAAe,MAAM;AACjD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,YAAM,SAAS,MAAM,OAAO,UAAU;AACtC,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,SAAS,sBAAsB;AAAA,IACrD;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,YAAY,OAAO;AAC/C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,EAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,IACvD;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,eAAe,OAAO;AAClD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAClD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC1D;AAAA,IACA,OAAO,EAAE,MAAM,MAAM,MAAM;AACzB,YAAM,SAAS,MAAM,OAAO,cAAc,EAAE,MAAM,MAAM,CAAC;AACzD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AACF;;;ACrTA,SAAS,KAAAC,UAAS;AAIX,SAAS,sBAAsB,QAAmB,QAAmB,eAAoC;AAC9G,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,MAAMA,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MACpD,MAAMA,GAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MAClE,aAAaA,GAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,MACnE,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,MACvF,cAAcA,GAAE,KAAK,CAAC,aAAa,eAAe,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,MAC3H,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,MAC1E,UAAUA,GAAE,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,MAC9E,aAAaA,GAAE,KAAK,CAAC,eAAe,iBAAiB,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MACjH,cAAcA,GAAE,KAAK,CAAC,UAAU,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MACtG,uBAAuBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,IAC9F;AAAA,IACA,OAAO,WAAW;AAChB,YAAM,OAAgC;AAAA,QACpC,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,aAAa,OAAO;AAAA,MACtB;AACA,UAAI,OAAO,gBAAiB,MAAK,iBAAiB,IAAI,OAAO;AAC7D,UAAI,OAAO,aAAc,MAAK,cAAc,IAAI,OAAO;AACvD,UAAI,OAAO,YAAa,MAAK,aAAa,IAAI,OAAO;AACrD,UAAI,OAAO,SAAU,MAAK,UAAU,IAAI,OAAO;AAC/C,UAAI,OAAO,YAAa,MAAK,aAAa,IAAI,OAAO;AACrD,UAAI,OAAO,aAAc,MAAK,cAAc,IAAI,OAAO;AACvD,UAAI,OAAO,sBAAuB,MAAK,uBAAuB,IAAI,OAAO;AAEzE,YAAM,SAAS,MAAM,OAAO,cAAc,IAAI;AAC9C,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,aAAa,OAAO;AAChD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,cAAc,OAAO;AACjD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,UAAU;AAAA,MACvC,cAAcA,GAAE,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC,EAAE,SAAS,sBAAsB;AAAA,IACrF;AAAA,IACA,OAAO,EAAE,SAAS,aAAa,MAAM;AACnC,YAAM,SAAS,MAAM,OAAO,gBAAgB,SAAS,YAAY;AACjE,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,MACpG,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MAClD,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC1D;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM,MAAM,MAAM;AACjC,YAAM,SAAS,MAAM,OAAO,YAAY,EAAE,QAAQ,MAAM,MAAM,CAAC;AAC/D,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,IACxD;AAAA,IACA,OAAO,EAAE,UAAU,MAAM;AACvB,YAAM,SAAS,MAAM,OAAO,eAAe,SAAS;AACpD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,mBAAmB,OAAO;AACtD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,UAAU;AAAA,IACzC;AAAA,IACA,OAAO,EAAE,QAAQ,MAAM;AACrB,YAAM,SAAS,MAAM,OAAO,iBAAiB,OAAO;AACpD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AAIA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAASA,GAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,MAChD,YAAYA,GAAE,OAAO,EAAE,SAAS,0CAA0C;AAAA,MAC1E,aAAaA,GAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,IACxG;AAAA,IACA,OAAO,EAAE,SAAS,YAAY,YAAY,MAAM;AAC9C,UAAI,cAAc,SAAS;AACzB,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,yBAAyB,cAAc,cAAc,8CAA8C,CAAC;AAAA,UAC7I,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UAAI;AACF,cAAM,cAAc,MAAM,SAAS,YAAY,eAAe,IAAI;AAClE,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,SAAS,OAAO;AAAA,gBAA8C,eAAe,IAAI;AAAA;AAAA,UACzF,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAc;AACrB,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,4BAA4B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,GAAG,CAAC;AAAA,UACzH,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,iCAAiC,CAAC;AAAA,QAC7E;AAAA,MACF;AAEA,YAAM,UAAU,cAAc;AAC9B,oBAAc,KAAK;AACnB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,SAAS,OAAO,oBAAoB,CAAC;AAAA,MAChF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,WAAWA,GAAE,OAAO,EAAE,SAAS,YAAY;AAAA,MAC3C,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MAC7E,SAASA,GAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,IAC/D;AAAA,IACA,OAAO,EAAE,WAAW,MAAM,QAAQ,MAAM;AACtC,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,0EAA0E,CAAC;AAAA,UACpH,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,wBAAgB,KAAK,MAAM,OAAO;AAAA,MACpC,QAAQ;AACN,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,kCAAkC,CAAC;AAAA,UAC5E,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,OAAO,cAAc,KAAK,WAAW;AAAA,QACzC,MAAM,QAAQ;AAAA,QACd,SAAS;AAAA,MACX,CAAC;AAED,UAAI,CAAC,MAAM;AACT,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,WAAW,SAAS,kCAAkC,CAAC;AAAA,UAChG,SAAS;AAAA,QACX;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2BAA2B,SAAS,IAAI,CAAC;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,CAAC;AAAA,IACD,YAAY;AACV,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,KAAK,UAAU,EAAE,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,QACxF;AAAA,MACF;AAEA,YAAM,WAAW,cAAc,YAAY;AAC3C,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,KAAK,UAAU;AAAA,YACnB,SAAS;AAAA,YACT,SAAS,cAAc;AAAA,YACvB,gBAAgB,SAAS;AAAA,YACzB,UAAU,SAAS,IAAI,QAAM;AAAA,cAC3B,WAAW,EAAE;AAAA,cACb,iBAAiB,EAAE;AAAA,cACnB,gBAAgB,EAAE;AAAA,YACpB,EAAE;AAAA,UACJ,GAAG,MAAM,CAAC;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AHzQA,eAAe,OAAsB;AACnC,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAS,IAAIC,WAAU,MAAM;AAGnC,QAAM,gBAAgB,IAAI,cAAc,MAAM;AAE9C,QAAM,SAAS,IAAI,UAAU;AAAA,IAC3B,MAAM;AAAA,IACN,SAAS;AAAA,EACX,CAAC;AAGD,wBAAsB,QAAQ,MAAM;AACpC,wBAAsB,QAAQ,QAAQ,aAAa;AAGnD,UAAQ,GAAG,UAAU,MAAM;AACzB,kBAAc,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACD,UAAQ,GAAG,WAAW,MAAM;AAC1B,kBAAc,KAAK;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AAGD,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,OAAO,MAAM,qBAAqB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC9F,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["ApiClient","z","ApiClient"]}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@clawrent/mcp-server",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "clawrent-mcp": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "dependencies": {
17
+ "@modelcontextprotocol/sdk": "^1.12.0",
18
+ "ws": "^8.18.0",
19
+ "zod": "^3.24.0",
20
+ "@clawrent/shared-types": "0.1.0",
21
+ "@clawrent/protocol": "0.1.0",
22
+ "@clawrent/cli": "0.1.0"
23
+ },
24
+ "devDependencies": {
25
+ "@types/node": "^22.0.0",
26
+ "@types/ws": "^8.5.0",
27
+ "tsup": "^8.3.0",
28
+ "typescript": "^5.7.0",
29
+ "@clawrent/config": "0.1.0"
30
+ },
31
+ "scripts": {
32
+ "build": "tsup",
33
+ "dev": "tsup --watch",
34
+ "typecheck": "tsc --noEmit",
35
+ "lint": "eslint src/"
36
+ }
37
+ }