@kynver-app/mcp-agent-os 0.3.45 → 0.3.47
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.
|
@@ -4,7 +4,7 @@ import { createServer } from "node:http";
|
|
|
4
4
|
import { timingSafeEqual } from "node:crypto";
|
|
5
5
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
6
|
export const MAX_SSE_BODY_BYTES = 1 * 1024 * 1024;
|
|
7
|
-
const FORBIDDEN_QUERY_KEYS = ["secret", "userId"];
|
|
7
|
+
const FORBIDDEN_QUERY_KEYS = ["apiKey", "secret", "userId"];
|
|
8
8
|
export function headerValue(req, name) {
|
|
9
9
|
const v = req.headers[name];
|
|
10
10
|
return typeof v === "string" ? v : Array.isArray(v) ? (v[0] ?? null) : null;
|
|
@@ -19,9 +19,6 @@ export function timingSafeEqualString(a, b) {
|
|
|
19
19
|
export function hasForbiddenQueryAuth(url) {
|
|
20
20
|
return FORBIDDEN_QUERY_KEYS.some((key) => url.searchParams.has(key));
|
|
21
21
|
}
|
|
22
|
-
function queryApiKey(url) {
|
|
23
|
-
return url.searchParams.get("apiKey")?.trim() ?? "";
|
|
24
|
-
}
|
|
25
22
|
export function resolveListenHost() {
|
|
26
23
|
const configured = process.env.MCP_SSE_HOST?.trim();
|
|
27
24
|
return configured || "127.0.0.1";
|
|
@@ -130,7 +127,7 @@ function resolveInternalAuth(req, serviceSecret) {
|
|
|
130
127
|
}
|
|
131
128
|
function verifyPostAuth(req, url, sessionAuth, serviceSecret) {
|
|
132
129
|
if (sessionAuth.kind === "apiKey") {
|
|
133
|
-
const token = bearerToken(req)
|
|
130
|
+
const token = bearerToken(req);
|
|
134
131
|
return token.length > 0 && timingSafeEqualString(token, sessionAuth.apiKey);
|
|
135
132
|
}
|
|
136
133
|
const internal = resolveInternalAuth(req, serviceSecret);
|
|
@@ -170,7 +167,6 @@ export function startKynverMcpSseServer(options) {
|
|
|
170
167
|
const maxSessionsPerUser = intFromEnv("MCP_SSE_MAX_SESSIONS_PER_USER", 20);
|
|
171
168
|
const idleTimeoutMs = intFromEnv("MCP_SSE_IDLE_TIMEOUT_MS", 5 * 60 * 1000);
|
|
172
169
|
const rateLimitPerMin = intFromEnv("MCP_SSE_RATE_LIMIT_PER_MIN", 120);
|
|
173
|
-
const rejectQueryApiKey = /^(1|true|yes)$/i.test(process.env.MCP_SSE_REJECT_QUERY_APIKEY ?? "");
|
|
174
170
|
const rateLimiter = createFixedWindowRateLimiter(rateLimitPerMin, 60 * 1000);
|
|
175
171
|
// Close idle SSE sessions so a flood of half-open connections can't pin memory.
|
|
176
172
|
const idleSweep = setInterval(() => {
|
|
@@ -198,15 +194,6 @@ export function startKynverMcpSseServer(options) {
|
|
|
198
194
|
});
|
|
199
195
|
return;
|
|
200
196
|
}
|
|
201
|
-
if (url.searchParams.has("apiKey")) {
|
|
202
|
-
if (rejectQueryApiKey) {
|
|
203
|
-
json(res, 400, {
|
|
204
|
-
error: "apiKey via query param is disabled. Use Authorization: Bearer <key>.",
|
|
205
|
-
});
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
console.warn("[MCP SSE] WARNING: apiKey in query string may leak via logs. Prefer Authorization header when your client supports it.");
|
|
209
|
-
}
|
|
210
197
|
let userId = null;
|
|
211
198
|
let auth = null;
|
|
212
199
|
const internal = serviceSecret ? resolveInternalAuth(req, serviceSecret) : null;
|
|
@@ -215,7 +202,7 @@ export function startKynverMcpSseServer(options) {
|
|
|
215
202
|
auth = internal.auth;
|
|
216
203
|
}
|
|
217
204
|
else {
|
|
218
|
-
const apiKey = bearerToken(req)
|
|
205
|
+
const apiKey = bearerToken(req);
|
|
219
206
|
if (apiKey) {
|
|
220
207
|
userId = await resolveUserFromApiKey(baseUrl, apiKey);
|
|
221
208
|
if (userId)
|
package/dist/server.js
CHANGED
|
@@ -11,6 +11,7 @@ import { z } from "zod";
|
|
|
11
11
|
import { get, post, patch } from "./lib/kynver-client.js";
|
|
12
12
|
import { registerPlanTools } from "./tools/plans.js";
|
|
13
13
|
import { registerPlanProgressTools } from "./tools/plan-progress.js";
|
|
14
|
+
import { registerPlanToFactoryTools } from "./tools/plan-to-factory.js";
|
|
14
15
|
import { registerTaskTools } from "./tools/tasks.js";
|
|
15
16
|
import { registerActionRequiredTools } from "./tools/action-required.js";
|
|
16
17
|
import { registerGraphTools } from "./tools/graph.js";
|
|
@@ -709,6 +710,7 @@ export function createAgentOsServer() {
|
|
|
709
710
|
// First-class AgentOS plans (Phase 5A): versioned operational artifacts.
|
|
710
711
|
registerPlanTools({ register, resolveToolSlug, jsonResult, compact });
|
|
711
712
|
registerPlanProgressTools({ register, resolveToolSlug, jsonResult, compact });
|
|
713
|
+
registerPlanToFactoryTools({ register, resolveToolSlug, jsonResult, compact });
|
|
712
714
|
// Action Required inbox: agent_os_ask_human + agent_os_await_action (slice 1).
|
|
713
715
|
registerActionRequiredTools({ register, jsonResult, compact });
|
|
714
716
|
// Operational graph insights — Agent SEE (agent_os_graph_query).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { post } from "../lib/kynver-client.js";
|
|
3
|
+
export function registerPlanToFactoryTools({ register, resolveToolSlug, jsonResult, }) {
|
|
4
|
+
const slugField = z
|
|
5
|
+
.string()
|
|
6
|
+
.optional()
|
|
7
|
+
.describe("AgentOS workspace slug. Omit to use env or the server-discovered primary.");
|
|
8
|
+
register("agent_os_plan_run_factory", "Run a plan through the factory: decompose progress rows, mint parent + child harness tasks, wire dependencies and owned paths, and return the next runnable slice.", {
|
|
9
|
+
planId: z.string(),
|
|
10
|
+
dryRun: z.boolean().optional(),
|
|
11
|
+
command: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe('Operator phrase; defaults to "run this plan through the factory".'),
|
|
15
|
+
slug: slugField,
|
|
16
|
+
}, async (args) => {
|
|
17
|
+
const s = await resolveToolSlug(args.slug);
|
|
18
|
+
return jsonResult(await post(`/agent-os/${s}/plans/${args.planId}/run-factory`, {
|
|
19
|
+
dryRun: args.dryRun,
|
|
20
|
+
command: args.command,
|
|
21
|
+
}));
|
|
22
|
+
});
|
|
23
|
+
}
|
package/dist/tools/tasks.js
CHANGED
|
@@ -147,7 +147,7 @@ export function registerTaskTools({ register, resolveToolSlug, jsonResult, compa
|
|
|
147
147
|
scheduledFor,
|
|
148
148
|
dependsOnTaskIds,
|
|
149
149
|
lastSummary: z.string().optional().describe("Latest progress summary."),
|
|
150
|
-
blocker: z.string().optional(),
|
|
150
|
+
blocker: z.string().nullable().optional().describe("Blocker text, or null to clear it."),
|
|
151
151
|
branch: z.string().optional(),
|
|
152
152
|
worktreePath: z.string().optional(),
|
|
153
153
|
prUrl: z.string().optional(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kynver-app/mcp-agent-os",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Kynver Agentic OS MCP server
|
|
3
|
+
"version": "0.3.47",
|
|
4
|
+
"description": "Kynver Agentic OS MCP server \u2014 slug-keyed agent identity, goals, projects, sessions, and long-term memory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kynver-mcp-agent-os": "dist/index.js"
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"build": "node --max-old-space-size=8192 ../../node_modules/typescript/bin/tsc",
|
|
19
19
|
"dev": "node --max-old-space-size=8192 ../../node_modules/typescript/bin/tsc --watch",
|
|
20
20
|
"start": "node dist/index.js",
|
|
21
|
+
"prepublishOnly": "npm run build && node ../../scripts/npm-publish-guard.mjs",
|
|
21
22
|
"start:sse": "node dist/sse.js"
|
|
22
23
|
},
|
|
23
24
|
"engines": {
|