adhdev 0.9.65 → 0.9.67

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.9.65",
3
+ "version": "0.9.67",
4
4
  "description": "ADHDev — Agent Dashboard Hub for Dev. Remote-control AI coding agents from anywhere.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,5 +1,27 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
3
25
 
4
26
  // src/server.ts
5
27
  var import_server = require("@modelcontextprotocol/sdk/server/index.js");
@@ -1242,6 +1264,248 @@ async function checkPendingCloud(transport, daemonId, format) {
1242
1264
  ${lines.join("\n\n")}`;
1243
1265
  }
1244
1266
 
1267
+ // src/tools/mesh-tools.ts
1268
+ function findNode(mesh, nodeId) {
1269
+ const node = mesh.nodes.find((n) => n.id === nodeId);
1270
+ if (!node) throw new Error(`Node '${nodeId}' is not a member of mesh '${mesh.name}'`);
1271
+ return node;
1272
+ }
1273
+ var MESH_STATUS_TOOL = {
1274
+ name: "mesh_status",
1275
+ description: "Get the current status of all nodes in the repo mesh \u2014 health, git state, active sessions. Use this to decide which node to send work to.",
1276
+ inputSchema: {
1277
+ type: "object",
1278
+ properties: {}
1279
+ }
1280
+ };
1281
+ var MESH_LIST_NODES_TOOL = {
1282
+ name: "mesh_list_nodes",
1283
+ description: "List all nodes in the mesh with their capabilities, platform, and workspace paths.",
1284
+ inputSchema: {
1285
+ type: "object",
1286
+ properties: {}
1287
+ }
1288
+ };
1289
+ var MESH_SEND_TASK_TOOL = {
1290
+ name: "mesh_send_task",
1291
+ description: "Send a natural-language task to an agent session on a mesh node. The agent will execute the task autonomously.",
1292
+ inputSchema: {
1293
+ type: "object",
1294
+ properties: {
1295
+ node_id: { type: "string", description: "Target node ID (from mesh_list_nodes)." },
1296
+ session_id: { type: "string", description: "Agent session ID on the target node." },
1297
+ message: { type: "string", description: "Natural-language task to send to the agent." }
1298
+ },
1299
+ required: ["node_id", "session_id", "message"]
1300
+ }
1301
+ };
1302
+ var MESH_READ_CHAT_TOOL = {
1303
+ name: "mesh_read_chat",
1304
+ description: "Read recent chat messages from a delegated agent session on a mesh node. Use this to check progress.",
1305
+ inputSchema: {
1306
+ type: "object",
1307
+ properties: {
1308
+ node_id: { type: "string", description: "Target node ID." },
1309
+ session_id: { type: "string", description: "Agent session ID to read from." },
1310
+ tail: { type: "number", description: "Number of recent messages to return (default: 10)." }
1311
+ },
1312
+ required: ["node_id", "session_id"]
1313
+ }
1314
+ };
1315
+ var MESH_LAUNCH_SESSION_TOOL = {
1316
+ name: "mesh_launch_session",
1317
+ description: "Launch a new agent session on a mesh node. Returns the session ID for subsequent send_task/read_chat calls.",
1318
+ inputSchema: {
1319
+ type: "object",
1320
+ properties: {
1321
+ node_id: { type: "string", description: "Target node ID." },
1322
+ type: { type: "string", description: 'Provider type (e.g. "claude-cli", "gemini-cli", "cursor").' }
1323
+ },
1324
+ required: ["node_id", "type"]
1325
+ }
1326
+ };
1327
+ var MESH_GIT_STATUS_TOOL = {
1328
+ name: "mesh_git_status",
1329
+ description: "Get git status for a mesh node workspace \u2014 branch, dirty state, changed files.",
1330
+ inputSchema: {
1331
+ type: "object",
1332
+ properties: {
1333
+ node_id: { type: "string", description: "Target node ID." }
1334
+ },
1335
+ required: ["node_id"]
1336
+ }
1337
+ };
1338
+ var MESH_CHECKPOINT_TOOL = {
1339
+ name: "mesh_checkpoint",
1340
+ description: "Create a git checkpoint (commit) on a mesh node workspace.",
1341
+ inputSchema: {
1342
+ type: "object",
1343
+ properties: {
1344
+ node_id: { type: "string", description: "Target node ID." },
1345
+ message: { type: "string", description: "Checkpoint commit message." }
1346
+ },
1347
+ required: ["node_id", "message"]
1348
+ }
1349
+ };
1350
+ var MESH_APPROVE_TOOL = {
1351
+ name: "mesh_approve",
1352
+ description: "Approve or reject a pending action on a delegated agent session.",
1353
+ inputSchema: {
1354
+ type: "object",
1355
+ properties: {
1356
+ node_id: { type: "string", description: "Target node ID." },
1357
+ session_id: { type: "string", description: "Agent session ID with pending approval." },
1358
+ action: { type: "string", enum: ["approve", "reject"], description: "Action to take." }
1359
+ },
1360
+ required: ["node_id", "session_id", "action"]
1361
+ }
1362
+ };
1363
+ var ALL_MESH_TOOLS = [
1364
+ MESH_STATUS_TOOL,
1365
+ MESH_LIST_NODES_TOOL,
1366
+ MESH_SEND_TASK_TOOL,
1367
+ MESH_READ_CHAT_TOOL,
1368
+ MESH_LAUNCH_SESSION_TOOL,
1369
+ MESH_GIT_STATUS_TOOL,
1370
+ MESH_CHECKPOINT_TOOL,
1371
+ MESH_APPROVE_TOOL
1372
+ ];
1373
+ async function meshStatus(ctx) {
1374
+ const { mesh, transport } = ctx;
1375
+ const results = [];
1376
+ for (const node of mesh.nodes) {
1377
+ const entry = {
1378
+ nodeId: node.id,
1379
+ workspace: node.workspace
1380
+ };
1381
+ try {
1382
+ if (isLocalTransport(transport)) {
1383
+ const statusResult = await transport.command("git_status", { workspace: node.workspace });
1384
+ const status = statusResult?.status ?? statusResult;
1385
+ entry.health = status?.isGitRepo ? status?.isDirty ? "dirty" : "online" : "degraded";
1386
+ entry.branch = status?.branch;
1387
+ entry.isDirty = status?.isDirty;
1388
+ entry.uncommittedChanges = status?.uncommittedChanges ?? 0;
1389
+ } else {
1390
+ entry.health = "unknown";
1391
+ entry.note = "Cloud status probe not yet implemented for mesh nodes";
1392
+ }
1393
+ } catch (e) {
1394
+ entry.health = "degraded";
1395
+ entry.error = e.message;
1396
+ }
1397
+ results.push(entry);
1398
+ }
1399
+ return JSON.stringify({
1400
+ meshId: mesh.id,
1401
+ meshName: mesh.name,
1402
+ repoIdentity: mesh.repoIdentity,
1403
+ policy: mesh.policy,
1404
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
1405
+ nodes: results
1406
+ }, null, 2);
1407
+ }
1408
+ async function meshListNodes(ctx) {
1409
+ const { mesh } = ctx;
1410
+ return JSON.stringify({
1411
+ meshId: mesh.id,
1412
+ meshName: mesh.name,
1413
+ nodes: mesh.nodes.map((n) => ({
1414
+ nodeId: n.id,
1415
+ workspace: n.workspace,
1416
+ repoRoot: n.repoRoot,
1417
+ isLocalWorktree: n.isLocalWorktree,
1418
+ policy: n.policy,
1419
+ userOverrides: n.userOverrides
1420
+ }))
1421
+ }, null, 2);
1422
+ }
1423
+ async function meshSendTask(ctx, args) {
1424
+ const node = findNode(ctx.mesh, args.node_id);
1425
+ if (node.policy.readOnly) {
1426
+ return JSON.stringify({ error: `Node '${args.node_id}' is read-only` });
1427
+ }
1428
+ if (isLocalTransport(ctx.transport)) {
1429
+ await ctx.transport.command("send_chat", {
1430
+ message: args.message,
1431
+ sessionId: args.session_id
1432
+ });
1433
+ return JSON.stringify({ success: true, nodeId: args.node_id, sessionId: args.session_id });
1434
+ } else {
1435
+ return JSON.stringify({ error: "Cloud mesh send_task not yet implemented" });
1436
+ }
1437
+ }
1438
+ async function meshReadChat(ctx, args) {
1439
+ findNode(ctx.mesh, args.node_id);
1440
+ if (isLocalTransport(ctx.transport)) {
1441
+ const result = await ctx.transport.command("read_chat", {
1442
+ sessionId: args.session_id,
1443
+ tailLimit: args.tail ?? 10
1444
+ });
1445
+ return JSON.stringify(result, null, 2);
1446
+ } else {
1447
+ return JSON.stringify({ error: "Cloud mesh read_chat not yet implemented" });
1448
+ }
1449
+ }
1450
+ async function meshLaunchSession(ctx, args) {
1451
+ const node = findNode(ctx.mesh, args.node_id);
1452
+ if (isLocalTransport(ctx.transport)) {
1453
+ const result = await ctx.transport.command("launch_cli", {
1454
+ type: args.type,
1455
+ dir: node.workspace
1456
+ });
1457
+ return JSON.stringify(result, null, 2);
1458
+ } else {
1459
+ return JSON.stringify({ error: "Cloud mesh launch_session not yet implemented" });
1460
+ }
1461
+ }
1462
+ async function meshGitStatus(ctx, args) {
1463
+ const node = findNode(ctx.mesh, args.node_id);
1464
+ if (isLocalTransport(ctx.transport)) {
1465
+ const statusResult = await ctx.transport.command("git_status", {
1466
+ workspace: node.workspace
1467
+ });
1468
+ const diffResult = await ctx.transport.command("git_diff_summary", {
1469
+ workspace: node.workspace
1470
+ });
1471
+ return JSON.stringify({
1472
+ nodeId: args.node_id,
1473
+ workspace: node.workspace,
1474
+ status: statusResult?.status ?? statusResult,
1475
+ diff: diffResult?.diffSummary ?? diffResult
1476
+ }, null, 2);
1477
+ } else {
1478
+ return JSON.stringify({ error: "Cloud mesh git_status not yet implemented" });
1479
+ }
1480
+ }
1481
+ async function meshCheckpoint(ctx, args) {
1482
+ const node = findNode(ctx.mesh, args.node_id);
1483
+ if (node.policy.readOnly) {
1484
+ return JSON.stringify({ error: `Node '${args.node_id}' is read-only \u2014 cannot checkpoint` });
1485
+ }
1486
+ if (isLocalTransport(ctx.transport)) {
1487
+ const result = await ctx.transport.command("git_checkpoint", {
1488
+ workspace: node.workspace,
1489
+ message: args.message
1490
+ });
1491
+ return JSON.stringify(result, null, 2);
1492
+ } else {
1493
+ return JSON.stringify({ error: "Cloud mesh checkpoint not yet implemented" });
1494
+ }
1495
+ }
1496
+ async function meshApprove(ctx, args) {
1497
+ findNode(ctx.mesh, args.node_id);
1498
+ if (isLocalTransport(ctx.transport)) {
1499
+ const result = await ctx.transport.command("resolve_action", {
1500
+ sessionId: args.session_id,
1501
+ action: args.action === "reject" ? "reject" : "approve"
1502
+ });
1503
+ return JSON.stringify(result, null, 2);
1504
+ } else {
1505
+ return JSON.stringify({ error: "Cloud mesh approve not yet implemented" });
1506
+ }
1507
+ }
1508
+
1245
1509
  // src/server.ts
1246
1510
  async function startMcpServer(opts) {
1247
1511
  const transport = opts.mode === "cloud" ? new CloudTransport({ apiKey: opts.apiKey, baseUrl: opts.baseUrl }) : new LocalTransport({ port: opts.port, password: opts.password });
@@ -1253,6 +1517,150 @@ async function startMcpServer(opts) {
1253
1517
  process.exit(1);
1254
1518
  }
1255
1519
  const isLocal = opts.mode === "local";
1520
+ if (opts.meshId) {
1521
+ let mesh;
1522
+ if (opts.mode === "cloud" && opts.apiKey) {
1523
+ try {
1524
+ const base = opts.baseUrl || "https://api.adhf.dev";
1525
+ const res = await fetch(`${base}/api/v1/repo-meshes/${opts.meshId}`, {
1526
+ headers: { "Authorization": `Bearer ${opts.apiKey}`, "Content-Type": "application/json" }
1527
+ });
1528
+ if (res.ok) {
1529
+ const data = await res.json();
1530
+ const rm = data.mesh;
1531
+ const nodes = data.nodes || [];
1532
+ let policy = {};
1533
+ try {
1534
+ policy = JSON.parse(rm.policy_json || rm.policy || "{}");
1535
+ } catch {
1536
+ }
1537
+ let coordinator = {};
1538
+ try {
1539
+ coordinator = JSON.parse(rm.coordinator_json || rm.coordinator_config || "{}");
1540
+ } catch {
1541
+ }
1542
+ mesh = {
1543
+ id: rm.id,
1544
+ name: rm.name,
1545
+ repoIdentity: rm.repo_identity,
1546
+ repoRemoteUrl: rm.repo_remote_url,
1547
+ defaultBranch: rm.default_branch,
1548
+ policy: {
1549
+ requirePreTaskCheckpoint: false,
1550
+ requirePostTaskCheckpoint: true,
1551
+ requireApprovalForPush: true,
1552
+ requireApprovalForDestructiveGit: true,
1553
+ dirtyWorkspaceBehavior: "warn",
1554
+ maxParallelTasks: 2,
1555
+ ...policy
1556
+ },
1557
+ coordinator,
1558
+ nodes: nodes.map((n) => ({
1559
+ id: n.id,
1560
+ workspace: n.workspace,
1561
+ repoRoot: n.repo_root,
1562
+ userOverrides: {},
1563
+ policy: {},
1564
+ isLocalWorktree: false
1565
+ })),
1566
+ createdAt: rm.created_at,
1567
+ updatedAt: rm.updated_at
1568
+ };
1569
+ process.stderr.write(`[adhdev-mcp] Loaded mesh config from cloud API
1570
+ `);
1571
+ }
1572
+ } catch (e) {
1573
+ process.stderr.write(`[adhdev-mcp] Cloud mesh fetch failed, falling back to local: ${e.message}
1574
+ `);
1575
+ }
1576
+ }
1577
+ if (!mesh) {
1578
+ try {
1579
+ const { getMesh } = await import("@adhdev/daemon-core");
1580
+ mesh = getMesh(opts.meshId);
1581
+ } catch (e) {
1582
+ process.stderr.write(`[adhdev-mcp] Failed to load mesh config: ${e.message}
1583
+ `);
1584
+ process.exit(1);
1585
+ }
1586
+ }
1587
+ if (!mesh) {
1588
+ process.stderr.write(`[adhdev-mcp] Mesh '${opts.meshId}' not found in ${opts.mode === "cloud" ? "cloud or local" : "local"} config. Use 'adhdev mesh list' to see available meshes.
1589
+ `);
1590
+ process.exit(1);
1591
+ }
1592
+ const meshCtx = { mesh, transport };
1593
+ let coordinatorPrompt = "";
1594
+ try {
1595
+ const { buildCoordinatorSystemPrompt } = await import("@adhdev/daemon-core");
1596
+ coordinatorPrompt = buildCoordinatorSystemPrompt({ mesh });
1597
+ } catch {
1598
+ coordinatorPrompt = `You are a Repo Mesh Coordinator for "${mesh.name}" (${mesh.repoIdentity}). Use mesh_* tools to orchestrate work.`;
1599
+ }
1600
+ const server2 = new import_server.Server(
1601
+ { name: "adhdev-mcp-server", version: "0.9.67" },
1602
+ { capabilities: { tools: {}, resources: {} } }
1603
+ );
1604
+ const { ListResourcesRequestSchema, ReadResourceRequestSchema } = await import("@modelcontextprotocol/sdk/types.js");
1605
+ server2.setRequestHandler(ListResourcesRequestSchema, async () => ({
1606
+ resources: [{
1607
+ uri: "coordinator://system-prompt",
1608
+ name: "Coordinator System Prompt",
1609
+ description: `System prompt for mesh "${mesh.name}" coordinator`,
1610
+ mimeType: "text/plain"
1611
+ }]
1612
+ }));
1613
+ server2.setRequestHandler(ReadResourceRequestSchema, async (req) => {
1614
+ if (req.params.uri === "coordinator://system-prompt") {
1615
+ return { contents: [{ uri: req.params.uri, mimeType: "text/plain", text: coordinatorPrompt }] };
1616
+ }
1617
+ throw new Error(`Unknown resource: ${req.params.uri}`);
1618
+ });
1619
+ server2.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({ tools: ALL_MESH_TOOLS }));
1620
+ server2.setRequestHandler(import_types.CallToolRequestSchema, async (req) => {
1621
+ const { name, arguments: args } = req.params;
1622
+ const a = args ?? {};
1623
+ try {
1624
+ let text;
1625
+ switch (name) {
1626
+ case "mesh_status":
1627
+ text = await meshStatus(meshCtx);
1628
+ break;
1629
+ case "mesh_list_nodes":
1630
+ text = await meshListNodes(meshCtx);
1631
+ break;
1632
+ case "mesh_send_task":
1633
+ text = await meshSendTask(meshCtx, a);
1634
+ break;
1635
+ case "mesh_read_chat":
1636
+ text = await meshReadChat(meshCtx, a);
1637
+ break;
1638
+ case "mesh_launch_session":
1639
+ text = await meshLaunchSession(meshCtx, a);
1640
+ break;
1641
+ case "mesh_git_status":
1642
+ text = await meshGitStatus(meshCtx, a);
1643
+ break;
1644
+ case "mesh_checkpoint":
1645
+ text = await meshCheckpoint(meshCtx, a);
1646
+ break;
1647
+ case "mesh_approve":
1648
+ text = await meshApprove(meshCtx, a);
1649
+ break;
1650
+ default:
1651
+ return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
1652
+ }
1653
+ return { content: [{ type: "text", text }] };
1654
+ } catch (err) {
1655
+ return { content: [{ type: "text", text: `Error: ${err?.message ?? String(err)}` }], isError: true };
1656
+ }
1657
+ });
1658
+ const stdioTransport2 = new import_stdio.StdioServerTransport();
1659
+ await server2.connect(stdioTransport2);
1660
+ process.stderr.write(`[adhdev-mcp] Server running in ${opts.mode} mesh mode \u2014 mesh: ${mesh.name} (${mesh.repoIdentity})
1661
+ `);
1662
+ return;
1663
+ }
1256
1664
  const allTools = [
1257
1665
  LIST_DAEMONS_TOOL,
1258
1666
  LIST_SESSIONS_TOOL,
@@ -1270,7 +1678,7 @@ async function startMcpServer(opts) {
1270
1678
  ...isLocal ? [SCREENSHOT_TOOL] : []
1271
1679
  ];
1272
1680
  const server = new import_server.Server(
1273
- { name: "adhdev-mcp-server", version: "0.9.65" },
1681
+ { name: "adhdev-mcp-server", version: "0.9.66" },
1274
1682
  { capabilities: { tools: {} } }
1275
1683
  );
1276
1684
  server.setRequestHandler(import_types.ListToolsRequestSchema, async () => ({ tools: allTools }));
@@ -1373,6 +1781,7 @@ function parseArgs(argv) {
1373
1781
  let baseUrl;
1374
1782
  let port;
1375
1783
  let password;
1784
+ let meshId;
1376
1785
  for (let i = 0; i < args.length; i++) {
1377
1786
  const arg = args[i];
1378
1787
  if ((arg === "--api-key" || arg === "-k") && args[i + 1]) {
@@ -1387,6 +1796,10 @@ function parseArgs(argv) {
1387
1796
  port = Number(arg.slice("--port=".length));
1388
1797
  } else if (arg === "--password" && args[i + 1]) {
1389
1798
  password = args[++i];
1799
+ } else if ((arg === "--repo-mesh" || arg === "--mesh") && args[i + 1]) {
1800
+ meshId = args[++i];
1801
+ } else if (arg?.startsWith("--repo-mesh=")) {
1802
+ meshId = arg.slice("--repo-mesh=".length);
1390
1803
  } else if (arg === "--help" || arg === "-h") {
1391
1804
  printHelp();
1392
1805
  process.exit(0);
@@ -1394,30 +1807,34 @@ function parseArgs(argv) {
1394
1807
  }
1395
1808
  if (!apiKey && process.env.ADHDEV_API_KEY) apiKey = process.env.ADHDEV_API_KEY;
1396
1809
  if (!password && process.env.ADHDEV_PASSWORD) password = process.env.ADHDEV_PASSWORD;
1810
+ if (!meshId && process.env.ADHDEV_MESH_ID) meshId = process.env.ADHDEV_MESH_ID;
1397
1811
  const mode = apiKey ? "cloud" : "local";
1398
- return { mode, port, password, apiKey, baseUrl };
1812
+ return { mode, port, password, apiKey, baseUrl, meshId };
1399
1813
  }
1400
1814
  function printHelp() {
1401
1815
  console.error(`
1402
1816
  adhdev-mcp \u2014 ADHDev MCP Server
1403
1817
 
1404
1818
  Usage:
1405
- adhdev-mcp Local mode (requires standalone daemon)
1406
- adhdev-mcp --api-key <key> Cloud mode (ADHDev cloud API)
1819
+ adhdev-mcp Local mode (requires standalone daemon)
1820
+ adhdev-mcp --api-key <key> Cloud mode (ADHDev cloud API)
1821
+ adhdev-mcp --repo-mesh <mesh_id> Mesh mode (coordinator-scoped tools)
1407
1822
 
1408
1823
  Options:
1409
- --port <n> Standalone daemon port (default: 3847)
1410
- --password <pass> Standalone daemon password (if set)
1411
- --api-key <key> ADHDev cloud API key (switches to cloud mode)
1412
- --base-url <url> Override cloud API base URL
1413
- --help Show this help
1824
+ --port <n> Standalone daemon port (default: 3847)
1825
+ --password <pass> Standalone daemon password (if set)
1826
+ --api-key <key> ADHDev cloud API key (switches to cloud mode)
1827
+ --base-url <url> Override cloud API base URL
1828
+ --repo-mesh <mesh_id> Enable mesh mode \u2014 exposes only mesh-scoped coordinator tools
1829
+ --help Show this help
1414
1830
 
1415
1831
  Environment variables:
1416
1832
  ADHDEV_API_KEY API key (cloud mode)
1417
1833
  ADHDEV_PASSWORD Daemon password (local mode)
1834
+ ADHDEV_MESH_ID Mesh ID (mesh mode)
1418
1835
 
1419
- Local mode tools: list_daemons, list_sessions, launch_session, stop_session, check_pending, read_chat, send_chat, approve, git_status, git_log, git_diff, git_checkpoint, git_push, screenshot
1420
- Cloud mode tools: list_daemons, list_sessions, launch_session, stop_session, check_pending, read_chat, send_chat, approve, git_status, git_log, git_diff, git_checkpoint, git_push
1836
+ Standard tools: list_daemons, list_sessions, launch_session, stop_session, check_pending, read_chat, send_chat, approve, git_status, git_log, git_diff, git_checkpoint, git_push, screenshot
1837
+ Mesh tools: mesh_status, mesh_list_nodes, mesh_send_task, mesh_read_chat, mesh_launch_session, mesh_git_status, mesh_checkpoint, mesh_approve
1421
1838
  `.trim());
1422
1839
  }
1423
1840
  startMcpServer(parseArgs(process.argv)).catch((err) => {