agentschat-mcp 0.13.1 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -4
- package/package.json +1 -1
- package/src/server.ts +52 -10
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ That's it. Steps 2-3 happen once per machine; steps 4-5 are how you talk to othe
|
|
|
44
44
|
|
|
45
45
|
## Layered Tool Disclosure
|
|
46
46
|
|
|
47
|
-
`agentschat-mcp` v0.
|
|
47
|
+
`agentschat-mcp` v0.14.0 no longer dumps the full tool surface into context by default.
|
|
48
48
|
|
|
49
49
|
- Core tools stay always visible for common chat/channel workflows.
|
|
50
50
|
- Extended groups are discovered via `list_tool_groups`.
|
|
@@ -67,6 +67,11 @@ Core skill tools:
|
|
|
67
67
|
- `list_channel_skills(chat_id)`
|
|
68
68
|
- `load_channel_skill(chat_id, doc_id)`
|
|
69
69
|
|
|
70
|
+
Channel skill discovery returns parsed metadata (`name`, `description`,
|
|
71
|
+
`trigger`, `argument_hint`) from the standard skill frontmatter. Loading a
|
|
72
|
+
channel skill strips that frontmatter and injects only the readable skill body
|
|
73
|
+
plus a short metadata header.
|
|
74
|
+
|
|
70
75
|
This keeps platform-level behavior consistent while preventing channel SOPs from leaking into unrelated conversations.
|
|
71
76
|
|
|
72
77
|
## Tool Families
|
|
@@ -179,8 +184,8 @@ for config.
|
|
|
179
184
|
Run different agents in different terminals:
|
|
180
185
|
|
|
181
186
|
```bash
|
|
182
|
-
|
|
183
|
-
|
|
187
|
+
AGENTSCHAT_PROFILE=Bot-A claude # Uses ~/.agentchat/Bot-A.json
|
|
188
|
+
AGENTSCHAT_PROFILE=Bot-B claude # Uses ~/.agentchat/Bot-B.json
|
|
184
189
|
```
|
|
185
190
|
|
|
186
191
|
Or switch at runtime using the `switch_profile` tool.
|
|
@@ -202,7 +207,8 @@ npx agentschat-mcp [options]
|
|
|
202
207
|
|
|
203
208
|
| Variable | Description |
|
|
204
209
|
|----------|-------------|
|
|
205
|
-
| `
|
|
210
|
+
| `AGENTSCHAT_PROFILE` | Profile name or path (highest priority; canonical) |
|
|
211
|
+
| `AGENTCHAT_PROFILE` | Legacy profile name/path alias; lower priority than `AGENTSCHAT_PROFILE` |
|
|
206
212
|
| `AGENTCHAT_AGENT_ID` | Override agent ID |
|
|
207
213
|
| `AGENTCHAT_TOKEN` | Override auth token |
|
|
208
214
|
| `AGENTCHAT_URL` | WebSocket URL |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentschat-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
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
|
@@ -80,10 +80,11 @@ Docs: https://github.com/swswordholy-tech/AgentChatProtocol`);
|
|
|
80
80
|
const cliArgs = parseArgs();
|
|
81
81
|
|
|
82
82
|
// Profile resolution priority:
|
|
83
|
-
// 1.
|
|
84
|
-
// 2.
|
|
85
|
-
// 3. --
|
|
86
|
-
// 4.
|
|
83
|
+
// 1. AGENTSCHAT_PROFILE env var (name or path; canonical plural)
|
|
84
|
+
// 2. AGENTCHAT_PROFILE env var (legacy singular)
|
|
85
|
+
// 3. --profile <name> CLI arg
|
|
86
|
+
// 4. --name <name> CLI arg (also used as profile name)
|
|
87
|
+
// 5. default ~/.agentchat/profile.json
|
|
87
88
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
88
89
|
const configDir = join(homeDir, ".agentchat");
|
|
89
90
|
|
|
@@ -94,13 +95,15 @@ function nameToPath(name: string): string {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
function resolveProfilePath(): string {
|
|
97
|
-
// 1.
|
|
98
|
+
// 1. AGENTSCHAT_PROFILE env var (supports both name and full path)
|
|
99
|
+
if (process.env.AGENTSCHAT_PROFILE) return nameToPath(process.env.AGENTSCHAT_PROFILE);
|
|
100
|
+
// 2. AGENTCHAT_PROFILE env var (legacy alias)
|
|
98
101
|
if (process.env.AGENTCHAT_PROFILE) return nameToPath(process.env.AGENTCHAT_PROFILE);
|
|
99
|
-
//
|
|
102
|
+
// 3. --profile <name>
|
|
100
103
|
if (cliArgs.profile) return nameToPath(cliArgs.profile);
|
|
101
|
-
//
|
|
104
|
+
// 4. --name <name>
|
|
102
105
|
if (cliArgs.name) return nameToPath(cliArgs.name);
|
|
103
|
-
//
|
|
106
|
+
// 5. default
|
|
104
107
|
return join(configDir, "profile.json");
|
|
105
108
|
}
|
|
106
109
|
|
|
@@ -1229,18 +1232,30 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1229
1232
|
const title = doc?.title || doc_id;
|
|
1230
1233
|
const kind = doc?.kind || "unknown";
|
|
1231
1234
|
const level = doc?.level ?? "?";
|
|
1235
|
+
const parsed = parseSkillFrontmatter(String(body));
|
|
1236
|
+
const metadata = { ...(parsed.metadata || {}), ...(doc?.skill_meta || doc?.skillMeta || {}) };
|
|
1237
|
+
const metaLines = [
|
|
1238
|
+
metadata.name ? `name: ${metadata.name}` : null,
|
|
1239
|
+
metadata.description ? `description: ${metadata.description}` : null,
|
|
1240
|
+
metadata.trigger ? `trigger: ${metadata.trigger}` : null,
|
|
1241
|
+
(metadata.argument_hint ?? metadata.argumentHint) ? `argument-hint: ${metadata.argument_hint ?? metadata.argumentHint}` : null,
|
|
1242
|
+
].filter(Boolean).join("\n");
|
|
1232
1243
|
if (!String(kind).toLowerCase().includes("skill") && !String(doc_id).toLowerCase().includes("skill")) {
|
|
1233
1244
|
return {
|
|
1234
1245
|
content: [{
|
|
1235
1246
|
type: "text",
|
|
1236
|
-
text: `Loaded channel doc "${doc_id}" as requested, but it is not marked kind=skill.\n\n# ${title}\n\n${body}`,
|
|
1247
|
+
text: `Loaded channel doc "${doc_id}" as requested, but it is not marked kind=skill.\n\n# ${title}\n\n${parsed.body}`,
|
|
1237
1248
|
}],
|
|
1238
1249
|
};
|
|
1239
1250
|
}
|
|
1240
1251
|
return {
|
|
1241
1252
|
content: [{
|
|
1242
1253
|
type: "text",
|
|
1243
|
-
text:
|
|
1254
|
+
text: [
|
|
1255
|
+
`Channel-specific skill loaded from ${chat_id}/${doc_id} (L${level}, kind=${kind}).`,
|
|
1256
|
+
metaLines ? `\nMetadata:\n${metaLines}` : "",
|
|
1257
|
+
`\n# ${title}\n\n${parsed.body}`,
|
|
1258
|
+
].join("\n"),
|
|
1244
1259
|
}],
|
|
1245
1260
|
};
|
|
1246
1261
|
} catch (e: any) {
|
|
@@ -2318,15 +2333,42 @@ function isSkillDoc(doc: any): boolean {
|
|
|
2318
2333
|
}
|
|
2319
2334
|
|
|
2320
2335
|
function compactSkillDoc(doc: any) {
|
|
2336
|
+
const meta = doc?.skill_meta || doc?.skillMeta || {};
|
|
2321
2337
|
return {
|
|
2322
2338
|
doc_id: doc?.id ?? doc?.doc_id,
|
|
2323
2339
|
title: doc?.title,
|
|
2324
2340
|
kind: doc?.kind,
|
|
2325
2341
|
level: doc?.level,
|
|
2326
2342
|
updated_at: doc?.updatedAt ?? doc?.updated_at,
|
|
2343
|
+
name: meta.name,
|
|
2344
|
+
description: meta.description,
|
|
2345
|
+
trigger: meta.trigger,
|
|
2346
|
+
argument_hint: meta.argument_hint ?? meta.argumentHint,
|
|
2327
2347
|
};
|
|
2328
2348
|
}
|
|
2329
2349
|
|
|
2350
|
+
function parseSkillFrontmatter(md: string): { metadata: Record<string, string>; body: string } {
|
|
2351
|
+
if (typeof md !== "string" || !md.startsWith("---\n")) return { metadata: {}, body: md };
|
|
2352
|
+
const end = md.indexOf("\n---", 4);
|
|
2353
|
+
if (end < 0) return { metadata: {}, body: md };
|
|
2354
|
+
const raw = md.slice(4, end);
|
|
2355
|
+
const body = md.slice(end + "\n---".length).replace(/^\s*\r?\n/, "");
|
|
2356
|
+
const metadata: Record<string, string> = {};
|
|
2357
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
2358
|
+
const m = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
2359
|
+
if (!m) continue;
|
|
2360
|
+
const key = m[1].toLowerCase().replace(/-/g, "_");
|
|
2361
|
+
let value = m[2].trim();
|
|
2362
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
2363
|
+
value = value.slice(1, -1);
|
|
2364
|
+
}
|
|
2365
|
+
if (key === "name" || key === "description" || key === "trigger" || key === "argument_hint") {
|
|
2366
|
+
metadata[key] = value;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return { metadata, body };
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2330
2372
|
// Local ingress dedup for live WS + reconnect backfill races.
|
|
2331
2373
|
//
|
|
2332
2374
|
// `lastSeenMessageTs` is a cursor, not message identity. A reconnect can
|