@kynver-app/mcp-agent-os 0.3.62 → 0.3.65
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.
|
@@ -49,8 +49,13 @@ function getHeaders() {
|
|
|
49
49
|
const userId = ctx?.userId;
|
|
50
50
|
const serviceSecret = process.env.KYNVER_SERVICE_SECRET;
|
|
51
51
|
if (userId) {
|
|
52
|
+
const runnerToken = process.env.KYNVER_RUNNER_TOKEN?.trim();
|
|
53
|
+
if (runnerToken) {
|
|
54
|
+
headers["X-Kynver-Runner-Token"] = runnerToken;
|
|
55
|
+
return headers;
|
|
56
|
+
}
|
|
52
57
|
if (!serviceSecret) {
|
|
53
|
-
throw new Error("
|
|
58
|
+
throw new Error("User context requires authentication: set KYNVER_RUNNER_TOKEN (preferred) or KYNVER_SERVICE_SECRET in the MCP server environment.");
|
|
54
59
|
}
|
|
55
60
|
headers["X-Kynver-User-Id"] = userId;
|
|
56
61
|
headers["X-Kynver-Service-Secret"] = serviceSecret;
|
|
@@ -5,6 +5,13 @@ 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
7
|
const FORBIDDEN_QUERY_KEYS = ["apiKey", "secret", "userId"];
|
|
8
|
+
const TRUTHY_ENV = new Set(["1", "true", "yes", "on"]);
|
|
9
|
+
function isServiceSecretImpersonationRejectedInProduction() {
|
|
10
|
+
const override = process.env.KYNVER_ALLOW_SERVICE_SECRET_IMPERSONATION?.trim().toLowerCase();
|
|
11
|
+
if (override !== undefined && TRUTHY_ENV.has(override))
|
|
12
|
+
return false;
|
|
13
|
+
return process.env.NODE_ENV === "production" || process.env.VERCEL_ENV === "production";
|
|
14
|
+
}
|
|
8
15
|
export function headerValue(req, name) {
|
|
9
16
|
const v = req.headers[name];
|
|
10
17
|
return typeof v === "string" ? v : Array.isArray(v) ? (v[0] ?? null) : null;
|
|
@@ -121,6 +128,8 @@ function resolveInternalAuth(req, serviceSecret) {
|
|
|
121
128
|
const internalSecret = headerValue(req, "x-kynver-service-secret");
|
|
122
129
|
if (!internalUserId || !serviceSecret || !internalSecret)
|
|
123
130
|
return null;
|
|
131
|
+
if (isServiceSecretImpersonationRejectedInProduction())
|
|
132
|
+
return null;
|
|
124
133
|
if (!timingSafeEqualString(internalSecret, serviceSecret))
|
|
125
134
|
return null;
|
|
126
135
|
return { userId: internalUserId, auth: { kind: "internal", userId: internalUserId } };
|
package/dist/tools/graph.d.ts
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* returns server-computed insights (bottlenecks, per-owner load, orphans) over
|
|
6
6
|
* the operational graph. Read-only; the Kynver route enforces session +
|
|
7
7
|
* workspace scope. Kept in its own module so server.ts stays slim.
|
|
8
|
+
*
|
|
9
|
+
* agent_os_memory_graph_expand (PR10) proxies scoped memory-entity neighborhood
|
|
10
|
+
* expansion through the authenticated app route — handles/previews only.
|
|
8
11
|
*/
|
|
9
12
|
type ToolResult = {
|
|
10
13
|
content: {
|
package/dist/tools/graph.js
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* returns server-computed insights (bottlenecks, per-owner load, orphans) over
|
|
6
6
|
* the operational graph. Read-only; the Kynver route enforces session +
|
|
7
7
|
* workspace scope. Kept in its own module so server.ts stays slim.
|
|
8
|
+
*
|
|
9
|
+
* agent_os_memory_graph_expand (PR10) proxies scoped memory-entity neighborhood
|
|
10
|
+
* expansion through the authenticated app route — handles/previews only.
|
|
8
11
|
*/
|
|
9
12
|
import { z } from "zod";
|
|
10
13
|
import { get, post } from "../lib/kynver-client.js";
|
|
@@ -110,4 +113,41 @@ export function registerGraphTools({ register, resolveToolSlug, jsonResult }) {
|
|
|
110
113
|
source: "agent",
|
|
111
114
|
}));
|
|
112
115
|
});
|
|
116
|
+
register("agent_os_memory_graph_expand", [
|
|
117
|
+
"Expand a scoped memory-entity graph neighborhood from an opaque start handle.",
|
|
118
|
+
"Returns compact previews and expansion handles only — never raw entity IDs or full memory bodies.",
|
|
119
|
+
"Requires graph view + expansion security gates (scoped opt-in). Read-only.",
|
|
120
|
+
].join(" "), {
|
|
121
|
+
slug: z.string().optional().describe("AgentOS slug. Defaults to env/primary."),
|
|
122
|
+
startEntityHandle: z
|
|
123
|
+
.string()
|
|
124
|
+
.describe("Opaque graph entity handle (gent:…) issued by the server."),
|
|
125
|
+
grantToken: z
|
|
126
|
+
.string()
|
|
127
|
+
.describe("Signed expansion grant (kve:g:…) bound to this graph handle and envelope."),
|
|
128
|
+
purpose: z
|
|
129
|
+
.string()
|
|
130
|
+
.describe("Informational only — the server enforces the graph-expansion purpose bound into the grant and ignores this value."),
|
|
131
|
+
envelopeId: z.string().describe("Active context envelope id binding this expansion."),
|
|
132
|
+
asOf: z.string().optional().describe("Optional UTC ISO as-of instant for temporal filtering."),
|
|
133
|
+
maxDepth: z
|
|
134
|
+
.number()
|
|
135
|
+
.int()
|
|
136
|
+
.min(1)
|
|
137
|
+
.max(1)
|
|
138
|
+
.optional()
|
|
139
|
+
.describe("Traversal depth; the server caps expansion depth at 1."),
|
|
140
|
+
maxNodes: z.number().int().min(1).max(36).optional(),
|
|
141
|
+
}, async (args) => {
|
|
142
|
+
const slug = await resolveToolSlug(args.slug);
|
|
143
|
+
return jsonResult(await post(`/agent-os/${slug}/memory-graph/expand`, {
|
|
144
|
+
startEntityHandle: args.startEntityHandle,
|
|
145
|
+
grantToken: args.grantToken,
|
|
146
|
+
purpose: args.purpose,
|
|
147
|
+
envelopeId: args.envelopeId,
|
|
148
|
+
asOf: args.asOf,
|
|
149
|
+
maxDepth: args.maxDepth,
|
|
150
|
+
maxNodes: args.maxNodes,
|
|
151
|
+
}));
|
|
152
|
+
});
|
|
113
153
|
}
|
package/dist/tools/workbench.js
CHANGED
|
@@ -19,6 +19,20 @@ const commandKind = z.enum([
|
|
|
19
19
|
"yield",
|
|
20
20
|
"take",
|
|
21
21
|
]);
|
|
22
|
+
/** Keep in sync with COMMAND_CENTER_VIEW_MODES in command-center-url-state.ts */
|
|
23
|
+
const workbenchView = z.enum([
|
|
24
|
+
"overview",
|
|
25
|
+
"flow",
|
|
26
|
+
"marketing",
|
|
27
|
+
"projects",
|
|
28
|
+
"tasks",
|
|
29
|
+
"goals",
|
|
30
|
+
"dq",
|
|
31
|
+
"web",
|
|
32
|
+
"review",
|
|
33
|
+
"system",
|
|
34
|
+
"health",
|
|
35
|
+
]);
|
|
22
36
|
export function registerWorkbenchTools({ register, resolveToolSlug, jsonResult, }) {
|
|
23
37
|
register("agent_os_workbench_query", [
|
|
24
38
|
"Read the operator's current workbench focus (view mode, drilldown stack, focused entity)",
|
|
@@ -37,7 +51,7 @@ export function registerWorkbenchTools({ register, resolveToolSlug, jsonResult,
|
|
|
37
51
|
].join(" "), {
|
|
38
52
|
slug: z.string().optional(),
|
|
39
53
|
kind: commandKind,
|
|
40
|
-
view:
|
|
54
|
+
view: workbenchView.optional(),
|
|
41
55
|
target: z.string().optional().describe("EntityRef e.g. task:<id>, plan:<id>"),
|
|
42
56
|
push: z.boolean().optional().describe("For drill: push onto stack (default true)"),
|
|
43
57
|
panel: 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.65",
|
|
4
|
+
"description": "Kynver Agentic OS MCP server — 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"
|