cross-agent-teams-mcp 0.5.12 → 0.5.14
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/cli.js +82 -10
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/daemon/server.ts +26 -4
- package/src/mcp/transport.ts +88 -13
package/dist/cli.js
CHANGED
|
@@ -3659,6 +3659,37 @@ function mountMcp(app, db, fanout, channelWakeFanout, opts = {}) {
|
|
|
3659
3659
|
getSessionOrigin: (connectionId) => sessions.get(connectionId)?.originInfo
|
|
3660
3660
|
});
|
|
3661
3661
|
const sessionOwners = /* @__PURE__ */ new Map();
|
|
3662
|
+
function normalizeGcOptions(opts2) {
|
|
3663
|
+
if (typeof opts2 === "number") {
|
|
3664
|
+
return { idleMs: opts2, maxAgeMs: opts2, maxSessions: Number.POSITIVE_INFINITY };
|
|
3665
|
+
}
|
|
3666
|
+
const idleMs = opts2?.idleMs ?? 3e5;
|
|
3667
|
+
return {
|
|
3668
|
+
idleMs,
|
|
3669
|
+
maxAgeMs: opts2?.maxAgeMs ?? idleMs,
|
|
3670
|
+
maxSessions: opts2?.maxSessions ?? Number.POSITIVE_INFINITY
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
function closeOrphanSession(session, now, reason) {
|
|
3674
|
+
const ageS = Math.floor((now - session.createdAt) / 1e3);
|
|
3675
|
+
const idleS = Math.floor((now - session.lastActivityAt) / 1e3);
|
|
3676
|
+
try {
|
|
3677
|
+
log(`mcp orphan session reap: sid=${session.sessionId} age_s=${ageS} idle_s=${idleS} reason=${reason}`);
|
|
3678
|
+
} catch {
|
|
3679
|
+
}
|
|
3680
|
+
try {
|
|
3681
|
+
void session.transport.close();
|
|
3682
|
+
} catch {
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3685
|
+
function enforceOrphanSessionLimit(now, maxSessions, candidates) {
|
|
3686
|
+
if (!Number.isFinite(maxSessions)) return;
|
|
3687
|
+
const orphans = (candidates ?? Array.from(sessions.values())).filter((session) => session.agentIdHolder.current === void 0).sort((a, b) => a.createdAt - b.createdAt);
|
|
3688
|
+
if (orphans.length <= maxSessions) return;
|
|
3689
|
+
for (const session of orphans.slice(0, orphans.length - maxSessions)) {
|
|
3690
|
+
closeOrphanSession(session, now, "max_sessions");
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3662
3693
|
function createSession() {
|
|
3663
3694
|
const server = new McpServer(
|
|
3664
3695
|
{ name: "cross-agent-teams-mcp", version: "0.1.0" },
|
|
@@ -3724,6 +3755,9 @@ function mountMcp(app, db, fanout, channelWakeFanout, opts = {}) {
|
|
|
3724
3755
|
clientInfo: void 0,
|
|
3725
3756
|
originInfo: { origin: "local", remote_addr: null }
|
|
3726
3757
|
});
|
|
3758
|
+
if (opts.orphanSessionLimit !== void 0) {
|
|
3759
|
+
enforceOrphanSessionLimit(now2, opts.orphanSessionLimit);
|
|
3760
|
+
}
|
|
3727
3761
|
}
|
|
3728
3762
|
});
|
|
3729
3763
|
transport.onclose = () => {
|
|
@@ -3860,18 +3894,40 @@ function mountMcp(app, db, fanout, channelWakeFanout, opts = {}) {
|
|
|
3860
3894
|
await session.transport.handleRequest(req.raw, reply.raw);
|
|
3861
3895
|
return reply;
|
|
3862
3896
|
});
|
|
3863
|
-
function reapOrphanSessions(now,
|
|
3897
|
+
function reapOrphanSessions(now, opts2) {
|
|
3898
|
+
const gc = normalizeGcOptions(opts2);
|
|
3899
|
+
const survivors = [];
|
|
3864
3900
|
for (const session of sessions.values()) {
|
|
3865
3901
|
if (session.agentIdHolder.current !== void 0) continue;
|
|
3866
3902
|
const idleMs = now - session.lastActivityAt;
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3903
|
+
const ageMs = now - session.createdAt;
|
|
3904
|
+
if (idleMs >= gc.idleMs) {
|
|
3905
|
+
closeOrphanSession(session, now, "idle");
|
|
3906
|
+
continue;
|
|
3907
|
+
}
|
|
3908
|
+
if (ageMs >= gc.maxAgeMs) {
|
|
3909
|
+
closeOrphanSession(session, now, "max_age");
|
|
3910
|
+
continue;
|
|
3871
3911
|
}
|
|
3912
|
+
survivors.push(session);
|
|
3872
3913
|
}
|
|
3914
|
+
enforceOrphanSessionLimit(now, gc.maxSessions, survivors);
|
|
3873
3915
|
}
|
|
3874
|
-
|
|
3916
|
+
function sessionMetrics() {
|
|
3917
|
+
let registered = 0;
|
|
3918
|
+
let orphan = 0;
|
|
3919
|
+
for (const session of sessions.values()) {
|
|
3920
|
+
if (session.agentIdHolder.current === void 0) orphan += 1;
|
|
3921
|
+
else registered += 1;
|
|
3922
|
+
}
|
|
3923
|
+
return {
|
|
3924
|
+
total: sessions.size,
|
|
3925
|
+
registered,
|
|
3926
|
+
orphan,
|
|
3927
|
+
fanout: fanout.peek().length
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
return { reapOrphanSessions, sessionMetrics };
|
|
3875
3931
|
}
|
|
3876
3932
|
|
|
3877
3933
|
// src/daemon/cleanup.ts
|
|
@@ -4051,7 +4107,9 @@ function bindHostCoversIpv4Loopback(host) {
|
|
|
4051
4107
|
// src/daemon/server.ts
|
|
4052
4108
|
var DEFAULT_KEEP_ALIVE_TIMEOUT_MS = 12e4;
|
|
4053
4109
|
var DEFAULT_ORPHAN_GC_INTERVAL_MS = 6e4;
|
|
4054
|
-
var DEFAULT_ORPHAN_GC_IDLE_MS =
|
|
4110
|
+
var DEFAULT_ORPHAN_GC_IDLE_MS = 3e5;
|
|
4111
|
+
var DEFAULT_ORPHAN_GC_MAX_AGE_MS = 3e5;
|
|
4112
|
+
var DEFAULT_ORPHAN_GC_MAX_SESSIONS = 100;
|
|
4055
4113
|
function parsePositiveInt(raw, fallback) {
|
|
4056
4114
|
const n = Number(raw);
|
|
4057
4115
|
return Number.isInteger(n) && n > 0 ? n : fallback;
|
|
@@ -4074,8 +4132,17 @@ async function buildServer(opts) {
|
|
|
4074
4132
|
;
|
|
4075
4133
|
req.xatsPeer = classifyPeerAddress(req.raw.socket.remoteAddress);
|
|
4076
4134
|
});
|
|
4077
|
-
|
|
4078
|
-
const mcp = mountMcp(app, db, fanout, channelWakeFanout, {
|
|
4135
|
+
const orphanGcMaxSessions = opts.orphanGcMaxSessions ?? parsePositiveInt(process.env.ORPHAN_GC_MAX_SESSIONS, DEFAULT_ORPHAN_GC_MAX_SESSIONS);
|
|
4136
|
+
const mcp = mountMcp(app, db, fanout, channelWakeFanout, {
|
|
4137
|
+
context,
|
|
4138
|
+
orphanSessionLimit: orphanGcMaxSessions
|
|
4139
|
+
});
|
|
4140
|
+
app.get("/health", async () => ({
|
|
4141
|
+
ok: true,
|
|
4142
|
+
version,
|
|
4143
|
+
uptime_seconds: Math.floor((Date.now() - startedAt) / 1e3),
|
|
4144
|
+
mcp_sessions: mcp.sessionMetrics()
|
|
4145
|
+
}));
|
|
4079
4146
|
const cleanupIntervalMs = opts.cleanupIntervalMs ?? Number(process.env.CLEANUP_INTERVAL_MS ?? 60 * 60 * 1e3);
|
|
4080
4147
|
const interval = setInterval(() => {
|
|
4081
4148
|
try {
|
|
@@ -4086,9 +4153,14 @@ async function buildServer(opts) {
|
|
|
4086
4153
|
if (typeof interval.unref === "function") interval.unref();
|
|
4087
4154
|
const orphanGcIntervalMs = opts.orphanGcIntervalMs ?? parsePositiveInt(process.env.ORPHAN_GC_INTERVAL_MS, DEFAULT_ORPHAN_GC_INTERVAL_MS);
|
|
4088
4155
|
const orphanGcIdleMs = opts.orphanGcIdleMs ?? parsePositiveInt(process.env.ORPHAN_GC_IDLE_MS, DEFAULT_ORPHAN_GC_IDLE_MS);
|
|
4156
|
+
const orphanGcMaxAgeMs = opts.orphanGcMaxAgeMs ?? parsePositiveInt(process.env.ORPHAN_GC_MAX_AGE_MS, DEFAULT_ORPHAN_GC_MAX_AGE_MS);
|
|
4089
4157
|
const orphanGcInterval = setInterval(() => {
|
|
4090
4158
|
try {
|
|
4091
|
-
mcp.reapOrphanSessions(Date.now(),
|
|
4159
|
+
mcp.reapOrphanSessions(Date.now(), {
|
|
4160
|
+
idleMs: orphanGcIdleMs,
|
|
4161
|
+
maxAgeMs: orphanGcMaxAgeMs,
|
|
4162
|
+
maxSessions: orphanGcMaxSessions
|
|
4163
|
+
});
|
|
4092
4164
|
} catch {
|
|
4093
4165
|
}
|
|
4094
4166
|
}, orphanGcIntervalMs);
|