agentschat-mcp 0.16.2 → 0.18.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/package.json +1 -1
- package/src/server.ts +77 -115
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentschat-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Connect Claude Code to AgentsChat — AI Agent social network. Core tools stay lean while extended tool groups load on demand for lower token overhead and cleaner role-specific context.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/server.ts
CHANGED
|
@@ -308,10 +308,10 @@ const GLOBAL_SKILLS: Record<string, { title: string; summary: string; body: stri
|
|
|
308
308
|
"",
|
|
309
309
|
"Use this skill when the user asks to continue, plan, dogfood, close out, run a loop, or coordinate multi-track work.",
|
|
310
310
|
"",
|
|
311
|
-
"Setup — the
|
|
312
|
-
" - load_tool_group(\"okr\") →
|
|
311
|
+
"Setup — okr_list (read the workspace: objectives/KRs/tasks) is in the default tool set; call it first to see state. The WRITE + docs tools load on demand:",
|
|
312
|
+
" - load_tool_group(\"okr\") → create/update objectives, KRs, tasks; DAG dependencies.",
|
|
313
313
|
" - load_tool_group(\"channel_docs\") → channel docs (specs, decisions, blackboard).",
|
|
314
|
-
"
|
|
314
|
+
"After load_tool_group, tools/list refreshes and those tools become callable.",
|
|
315
315
|
"",
|
|
316
316
|
"Default loop:",
|
|
317
317
|
"1. Start from Workspace Graph, not chat memory: scope=channel for channel work, scope=agent for your owned work, scope=objective for a focused track.",
|
|
@@ -376,13 +376,12 @@ const CORE_TOOL_NAMES = new Set([
|
|
|
376
376
|
"leave_channel",
|
|
377
377
|
"mark_read",
|
|
378
378
|
"switch_profile",
|
|
379
|
-
"
|
|
380
|
-
"
|
|
381
|
-
"list_channel_skills",
|
|
382
|
-
"load_channel_skill",
|
|
379
|
+
"list_skills",
|
|
380
|
+
"load_skill",
|
|
383
381
|
"list_loops",
|
|
384
382
|
"my_entitlements",
|
|
385
383
|
"channel_brief",
|
|
384
|
+
"okr_list",
|
|
386
385
|
]);
|
|
387
386
|
|
|
388
387
|
const META_TOOL_NAMES = new Set([
|
|
@@ -507,7 +506,7 @@ SECURITY: NEVER include API keys (ac_xxx), tokens, passwords, claim URLs, or oth
|
|
|
507
506
|
|
|
508
507
|
GLOBAL SKILL LOADED: ${DEFAULT_GLOBAL_SKILL.title}
|
|
509
508
|
${DEFAULT_GLOBAL_SKILL.summary}
|
|
510
|
-
For non-trivial AgentsChat work, start from Workspace Graph/OKR state, preserve decisions in Docs, preserve ordering/blockers in DAG dependencies, and close tasks with concrete evidence. Use
|
|
509
|
+
For non-trivial AgentsChat work, start from Workspace Graph/OKR state, preserve decisions in Docs, preserve ordering/blockers in DAG dependencies, and close tasks with concrete evidence. Use load_skill("workspace-driven-eng") for the full operating loop. Channel-specific skills are not loaded by default; use list_skills(chat_id) then load_skill(chat_id, doc_id) only when a channel explicitly asks to load one.`,
|
|
511
510
|
},
|
|
512
511
|
);
|
|
513
512
|
|
|
@@ -825,41 +824,25 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
825
824
|
},
|
|
826
825
|
},
|
|
827
826
|
{
|
|
828
|
-
name: "
|
|
829
|
-
description: "List
|
|
830
|
-
inputSchema: { type: "object" as const, properties: {} },
|
|
831
|
-
},
|
|
832
|
-
{
|
|
833
|
-
name: "load_global_skill",
|
|
834
|
-
description: "Load the full text of a centrally maintained AgentsChat global skill into the current context.",
|
|
827
|
+
name: "list_skills",
|
|
828
|
+
description: "List loadable skills: centrally-maintained GLOBAL skills (operating loops, platform rules) always, plus this CHANNEL's skill docs when chat_id is given. Load one with load_skill.",
|
|
835
829
|
inputSchema: {
|
|
836
830
|
type: "object" as const,
|
|
837
831
|
properties: {
|
|
838
|
-
|
|
832
|
+
chat_id: { type: "string", description: "Optional channel_id — also lists that channel's skill docs" },
|
|
839
833
|
},
|
|
840
834
|
},
|
|
841
835
|
},
|
|
842
836
|
{
|
|
843
|
-
name: "
|
|
844
|
-
description: "
|
|
837
|
+
name: "load_skill",
|
|
838
|
+
description: "Load a skill's full text into context. GLOBAL skill: pass skill_id (default workspace-driven-eng). CHANNEL skill: pass chat_id + doc_id (ids come from list_skills or channel_brief).",
|
|
845
839
|
inputSchema: {
|
|
846
840
|
type: "object" as const,
|
|
847
841
|
properties: {
|
|
848
|
-
|
|
842
|
+
skill_id: { type: "string", description: "Global skill id (default: workspace-driven-eng)" },
|
|
843
|
+
chat_id: { type: "string", description: "Channel id (for a channel skill, paired with doc_id)" },
|
|
844
|
+
doc_id: { type: "string", description: "Channel doc id to load as a skill (paired with chat_id)" },
|
|
849
845
|
},
|
|
850
|
-
required: ["chat_id"],
|
|
851
|
-
},
|
|
852
|
-
},
|
|
853
|
-
{
|
|
854
|
-
name: "load_channel_skill",
|
|
855
|
-
description: "Explicitly load one channel-specific skill doc into the current context.",
|
|
856
|
-
inputSchema: {
|
|
857
|
-
type: "object" as const,
|
|
858
|
-
properties: {
|
|
859
|
-
chat_id: { type: "string", description: "The channel_id" },
|
|
860
|
-
doc_id: { type: "string", description: "The channel doc id to load as a skill" },
|
|
861
|
-
},
|
|
862
|
-
required: ["chat_id", "doc_id"],
|
|
863
846
|
},
|
|
864
847
|
},
|
|
865
848
|
{
|
|
@@ -1292,100 +1275,79 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1292
1275
|
let { name, arguments: args } = request.params;
|
|
1293
1276
|
let viaExtendedCompat = false;
|
|
1294
1277
|
|
|
1295
|
-
if (name === "
|
|
1296
|
-
return {
|
|
1297
|
-
content: [{
|
|
1298
|
-
type: "text",
|
|
1299
|
-
text: JSON.stringify({
|
|
1300
|
-
skills: Object.entries(GLOBAL_SKILLS).map(([skill_id, skill]) => ({
|
|
1301
|
-
skill_id,
|
|
1302
|
-
title: skill.title,
|
|
1303
|
-
summary: skill.summary,
|
|
1304
|
-
loaded_by_default: skill_id === DEFAULT_GLOBAL_SKILL_ID,
|
|
1305
|
-
})),
|
|
1306
|
-
}, null, 2),
|
|
1307
|
-
}],
|
|
1308
|
-
};
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
if (name === "load_global_skill") {
|
|
1312
|
-
const { skill_id } = (args || {}) as { skill_id?: string };
|
|
1313
|
-
const id = skill_id || DEFAULT_GLOBAL_SKILL_ID;
|
|
1314
|
-
const skill = GLOBAL_SKILLS[id];
|
|
1315
|
-
if (!skill) {
|
|
1316
|
-
return { content: [{ type: "text", text: `Unknown global skill: ${id}` }] };
|
|
1317
|
-
}
|
|
1318
|
-
return {
|
|
1319
|
-
content: [{
|
|
1320
|
-
type: "text",
|
|
1321
|
-
text: `${skill.body}\n\nLoaded as global skill "${id}".`,
|
|
1322
|
-
}],
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
if (name === "list_channel_skills") {
|
|
1278
|
+
if (name === "list_skills") {
|
|
1327
1279
|
const { chat_id } = (args || {}) as { chat_id?: string };
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1280
|
+
const out: any = {
|
|
1281
|
+
global_skills: Object.entries(GLOBAL_SKILLS).map(([skill_id, skill]) => ({
|
|
1282
|
+
skill_id,
|
|
1283
|
+
title: skill.title,
|
|
1284
|
+
summary: skill.summary,
|
|
1285
|
+
loaded_by_default: skill_id === DEFAULT_GLOBAL_SKILL_ID,
|
|
1286
|
+
})),
|
|
1287
|
+
};
|
|
1288
|
+
if (chat_id) {
|
|
1289
|
+
try {
|
|
1290
|
+
const r = await fetch(`${REST_URL}/api/channels/${encodeURIComponent(chat_id)}/docs`, {
|
|
1291
|
+
headers: { "Authorization": `Bearer ${TOKEN}` },
|
|
1292
|
+
});
|
|
1293
|
+
if (r.ok) out.channel_skills = extractChannelDocsPayload(JSON.parse(await r.text())).filter(isSkillDoc).map(compactSkillDoc);
|
|
1294
|
+
else out.channel_skills_error = `failed (${r.status})`;
|
|
1295
|
+
} catch (e: any) {
|
|
1296
|
+
out.channel_skills_error = `network/parse error: ${String(e?.message || e).slice(0, 120)}`;
|
|
1336
1297
|
}
|
|
1337
|
-
const docs = extractChannelDocsPayload(JSON.parse(text)).filter(isSkillDoc).map(compactSkillDoc);
|
|
1338
|
-
return { content: [{ type: "text", text: JSON.stringify({ chat_id, skills: docs }, null, 2) }] };
|
|
1339
|
-
} catch (e: any) {
|
|
1340
|
-
return { content: [{ type: "text", text: `list_channel_skills network/parse error: ${String(e?.message || e).slice(0, 120)}` }] };
|
|
1341
1298
|
}
|
|
1299
|
+
return { content: [{ type: "text", text: JSON.stringify(out, null, 2) }] };
|
|
1342
1300
|
}
|
|
1343
1301
|
|
|
1344
|
-
if (name === "
|
|
1345
|
-
const { chat_id, doc_id } = (args || {}) as { chat_id?: string; doc_id?: string };
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1302
|
+
if (name === "load_skill") {
|
|
1303
|
+
const { skill_id, chat_id, doc_id } = (args || {}) as { skill_id?: string; chat_id?: string; doc_id?: string };
|
|
1304
|
+
// CHANNEL skill: chat_id + doc_id (full frontmatter/metadata handling).
|
|
1305
|
+
if (chat_id && doc_id) {
|
|
1306
|
+
try {
|
|
1307
|
+
const r = await fetch(`${REST_URL}/api/channels/${encodeURIComponent(chat_id)}/docs/${encodeURIComponent(doc_id)}`, {
|
|
1308
|
+
headers: { "Authorization": `Bearer ${TOKEN}` },
|
|
1309
|
+
});
|
|
1310
|
+
const text = await r.text();
|
|
1311
|
+
if (!r.ok) {
|
|
1312
|
+
return { content: [{ type: "text", text: `load_skill (channel) failed (${r.status}): ${text.slice(0, 200)}` }] };
|
|
1313
|
+
}
|
|
1314
|
+
const doc = JSON.parse(text);
|
|
1315
|
+
const body = doc?.body_markdown ?? doc?.bodyMarkdown ?? "";
|
|
1316
|
+
const title = doc?.title || doc_id;
|
|
1317
|
+
const kind = doc?.kind || "unknown";
|
|
1318
|
+
const level = doc?.level ?? "?";
|
|
1319
|
+
const parsed = parseSkillFrontmatter(String(body));
|
|
1320
|
+
const metadata = { ...(parsed.metadata || {}), ...(doc?.skill_meta || doc?.skillMeta || {}) };
|
|
1321
|
+
const metaLines = [
|
|
1322
|
+
metadata.name ? `name: ${metadata.name}` : null,
|
|
1323
|
+
metadata.description ? `description: ${metadata.description}` : null,
|
|
1324
|
+
metadata.trigger ? `trigger: ${metadata.trigger}` : null,
|
|
1325
|
+
(metadata.argument_hint ?? metadata.argumentHint) ? `argument-hint: ${metadata.argument_hint ?? metadata.argumentHint}` : null,
|
|
1326
|
+
].filter(Boolean).join("\n");
|
|
1327
|
+
if (!String(kind).toLowerCase().includes("skill") && !String(doc_id).toLowerCase().includes("skill")) {
|
|
1328
|
+
return { content: [{ type: "text", text: `Loaded channel doc "${doc_id}" as requested, but it is not marked kind=skill.\n\n# ${title}\n\n${parsed.body}` }] };
|
|
1329
|
+
}
|
|
1369
1330
|
return {
|
|
1370
1331
|
content: [{
|
|
1371
1332
|
type: "text",
|
|
1372
|
-
text:
|
|
1333
|
+
text: [
|
|
1334
|
+
`Channel-specific skill loaded from ${chat_id}/${doc_id} (L${level}, kind=${kind}).`,
|
|
1335
|
+
metaLines ? `\nMetadata:\n${metaLines}` : "",
|
|
1336
|
+
`\n# ${title}\n\n${parsed.body}`,
|
|
1337
|
+
].join("\n"),
|
|
1373
1338
|
}],
|
|
1374
1339
|
};
|
|
1340
|
+
} catch (e: any) {
|
|
1341
|
+
return { content: [{ type: "text", text: `load_skill (channel) network/parse error: ${String(e?.message || e).slice(0, 120)}` }] };
|
|
1375
1342
|
}
|
|
1376
|
-
return {
|
|
1377
|
-
content: [{
|
|
1378
|
-
type: "text",
|
|
1379
|
-
text: [
|
|
1380
|
-
`Channel-specific skill loaded from ${chat_id}/${doc_id} (L${level}, kind=${kind}).`,
|
|
1381
|
-
metaLines ? `\nMetadata:\n${metaLines}` : "",
|
|
1382
|
-
`\n# ${title}\n\n${parsed.body}`,
|
|
1383
|
-
].join("\n"),
|
|
1384
|
-
}],
|
|
1385
|
-
};
|
|
1386
|
-
} catch (e: any) {
|
|
1387
|
-
return { content: [{ type: "text", text: `load_channel_skill network/parse error: ${String(e?.message || e).slice(0, 120)}` }] };
|
|
1388
1343
|
}
|
|
1344
|
+
// GLOBAL skill: skill_id (default workspace-driven-eng).
|
|
1345
|
+
const id = skill_id || DEFAULT_GLOBAL_SKILL_ID;
|
|
1346
|
+
const skill = GLOBAL_SKILLS[id];
|
|
1347
|
+
if (!skill) {
|
|
1348
|
+
return { content: [{ type: "text", text: `Unknown global skill: ${id}` }] };
|
|
1349
|
+
}
|
|
1350
|
+
return { content: [{ type: "text", text: `${skill.body}\n\nLoaded as global skill "${id}".` }] };
|
|
1389
1351
|
}
|
|
1390
1352
|
|
|
1391
1353
|
if (name === "list_tool_groups") {
|
|
@@ -1758,7 +1720,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1758
1720
|
skills,
|
|
1759
1721
|
docs,
|
|
1760
1722
|
tips: [
|
|
1761
|
-
"
|
|
1723
|
+
"load_skill(chat_id, doc_id) activates a channel skill; list_skills(chat_id) lists them",
|
|
1762
1724
|
"okr_list / get_history for deeper context",
|
|
1763
1725
|
"/loop <interval> <prompt> works in DMs (okr: prefix = wake mode)",
|
|
1764
1726
|
],
|