agentschat-mcp 0.11.2 → 0.11.4
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 +1 -1
- package/package.json +1 -1
- package/src/server.ts +26 -30
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ That's it. Your agent auto-registers and starts receiving @mentions and DMs. Use
|
|
|
24
24
|
|
|
25
25
|
## Layered Tool Disclosure
|
|
26
26
|
|
|
27
|
-
`agentschat-mcp` v0.11.
|
|
27
|
+
`agentschat-mcp` v0.11.4 no longer dumps the full tool surface into context by default.
|
|
28
28
|
|
|
29
29
|
- Core tools stay always visible for common chat/channel workflows.
|
|
30
30
|
- Extended groups are discovered via `list_tool_groups`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentschat-mcp",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.4",
|
|
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
|
@@ -369,7 +369,7 @@ function filterVisibleTools<T extends { name: string }>(tools: T[]): T[] {
|
|
|
369
369
|
|
|
370
370
|
// MCP Server
|
|
371
371
|
const server = new Server(
|
|
372
|
-
{ name: "agentschat", version: "0.11.
|
|
372
|
+
{ name: "agentschat", version: "0.11.4" },
|
|
373
373
|
{
|
|
374
374
|
capabilities: {
|
|
375
375
|
experimental: { "claude/channel": {} },
|
|
@@ -2092,36 +2092,24 @@ function saveLastSeenMessageTs(m: Map<string, string>) {
|
|
|
2092
2092
|
}
|
|
2093
2093
|
const lastSeenMessageTs = loadLastSeenMessageTs();
|
|
2094
2094
|
|
|
2095
|
+
function normalizeTimestampForCursor(ts: string | undefined, mode: "before" | "after"): string | undefined {
|
|
2096
|
+
if (!ts || typeof ts !== "string") return ts;
|
|
2097
|
+
const m = ts.match(/^(.*\.)(\d+)(Z)$/);
|
|
2098
|
+
if (!m) return ts;
|
|
2099
|
+
const frac = m[2];
|
|
2100
|
+
if (frac.length >= 9) return ts;
|
|
2101
|
+
const padChar = mode === "before" ? "9" : "0";
|
|
2102
|
+
return m[1] + frac + padChar.repeat(9 - frac.length) + m[3];
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2095
2105
|
// Local ingress dedup for live WS + reconnect backfill races.
|
|
2096
2106
|
//
|
|
2097
2107
|
// `lastSeenMessageTs` is a cursor, not message identity. A reconnect can
|
|
2098
2108
|
// legitimately receive the same persisted message once via live WS and once
|
|
2099
2109
|
// via REST backfill; timestamp guards alone would either fail to drop that
|
|
2100
2110
|
// duplicate or drop older out-of-order messages that were never processed.
|
|
2101
|
-
const
|
|
2102
|
-
function loadDeliveredMessageIds(): Set<string> {
|
|
2103
|
-
try {
|
|
2104
|
-
const raw = require("fs").readFileSync(deliveredMessageIdsFile, "utf-8");
|
|
2105
|
-
const parsed = JSON.parse(raw);
|
|
2106
|
-
return new Set(Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : []);
|
|
2107
|
-
} catch { return new Set(); }
|
|
2108
|
-
}
|
|
2109
|
-
function saveDeliveredMessageIds(ids: Set<string>) {
|
|
2110
|
-
try {
|
|
2111
|
-
require("fs").writeFileSync(deliveredMessageIdsFile, JSON.stringify([...ids]));
|
|
2112
|
-
} catch {}
|
|
2113
|
-
}
|
|
2114
|
-
const deliveredMessageIds = loadDeliveredMessageIds();
|
|
2111
|
+
const deliveredMessageIds = new Set<string>();
|
|
2115
2112
|
const MAX_DELIVERED_MESSAGE_IDS = 5000;
|
|
2116
|
-
let deliveredMessageIdsSaveTimer: ReturnType<typeof setTimeout> | null = null;
|
|
2117
|
-
function scheduleSaveDeliveredMessageIds() {
|
|
2118
|
-
if (deliveredMessageIdsSaveTimer) return;
|
|
2119
|
-
deliveredMessageIdsSaveTimer = setTimeout(() => {
|
|
2120
|
-
deliveredMessageIdsSaveTimer = null;
|
|
2121
|
-
saveDeliveredMessageIds(deliveredMessageIds);
|
|
2122
|
-
}, 1000);
|
|
2123
|
-
try { (deliveredMessageIdsSaveTimer as any).unref?.(); } catch {}
|
|
2124
|
-
}
|
|
2125
2113
|
function deliverySource(data: any): string {
|
|
2126
2114
|
return typeof data?.__source === "string" ? data.__source : "live";
|
|
2127
2115
|
}
|
|
@@ -2144,7 +2132,6 @@ function recordOrSkipDeliveredMessage(data: any): boolean {
|
|
|
2144
2132
|
deliveredMessageIds.clear();
|
|
2145
2133
|
for (const item of arr.slice(1000)) deliveredMessageIds.add(item);
|
|
2146
2134
|
}
|
|
2147
|
-
scheduleSaveDeliveredMessageIds();
|
|
2148
2135
|
return false;
|
|
2149
2136
|
}
|
|
2150
2137
|
// Channels we believe we're a member of. Populated from
|
|
@@ -2205,12 +2192,19 @@ async function backfillAllChannels(): Promise<void> {
|
|
|
2205
2192
|
// them anyway).
|
|
2206
2193
|
const replay = msgs.filter((m: any) =>
|
|
2207
2194
|
m && m.sender_id !== AGENT_ID && m.content !== "__typing__");
|
|
2208
|
-
|
|
2209
|
-
|
|
2195
|
+
const dedupedReplay = after
|
|
2196
|
+
? replay.filter((m: any) => {
|
|
2197
|
+
const msgTs = normalizeTimestampForCursor(m?.timestamp, "after");
|
|
2198
|
+
const afterTs = normalizeTimestampForCursor(after, "after");
|
|
2199
|
+
return typeof msgTs === "string" && typeof afterTs === "string" && msgTs > afterTs;
|
|
2200
|
+
})
|
|
2201
|
+
: replay;
|
|
2202
|
+
if (dedupedReplay.length === 0) continue;
|
|
2203
|
+
process.stderr.write(`[agentchat] Backfill ${channelId.slice(0, 12)}: ${dedupedReplay.length} missed msg(s)\n`);
|
|
2210
2204
|
// Sort ascending so replay order matches live chronology —
|
|
2211
2205
|
// lastSeenMessageTs advances monotonically.
|
|
2212
|
-
|
|
2213
|
-
for (const m of
|
|
2206
|
+
dedupedReplay.sort((a: any, b: any) => String(a.timestamp).localeCompare(String(b.timestamp)));
|
|
2207
|
+
for (const m of dedupedReplay) {
|
|
2214
2208
|
try {
|
|
2215
2209
|
// Wrap as a `message` envelope to match ws.onmessage shape.
|
|
2216
2210
|
if (currentHandleWSMessage) {
|
|
@@ -2293,7 +2287,9 @@ function connectWS() {
|
|
|
2293
2287
|
// this file is tiny (one row per channel).
|
|
2294
2288
|
if (typeof data.channel_id === "string" && typeof data.timestamp === "string") {
|
|
2295
2289
|
const prev = lastSeenMessageTs.get(data.channel_id) || "";
|
|
2296
|
-
|
|
2290
|
+
const currentTs = normalizeTimestampForCursor(data.timestamp, "after") || data.timestamp;
|
|
2291
|
+
const prevTs = normalizeTimestampForCursor(prev, "after") || prev;
|
|
2292
|
+
if (currentTs > prevTs) {
|
|
2297
2293
|
lastSeenMessageTs.set(data.channel_id, data.timestamp);
|
|
2298
2294
|
saveLastSeenMessageTs(lastSeenMessageTs);
|
|
2299
2295
|
}
|