mindgraph-mcp 0.23.0 → 0.25.0

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/server.d.mts CHANGED
@@ -1,6 +1,5 @@
1
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
1
+ import { Tool, Server } from '@modelcontextprotocol/server';
2
2
  import { MindGraph } from 'mindgraph';
3
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
4
3
 
5
4
  interface GeneratedToolDescriptor {
6
5
  name: string;
@@ -77,6 +76,10 @@ interface MemoryRuntimeConfig {
77
76
  /** Everything the request handlers close over. */
78
77
  interface ServerWiring {
79
78
  client: MindGraph;
79
+ /** Fields a local harness hook recorded for a call (see call-ledger.ts).
80
+ * Injected by the stdio entry so this module stays free of node:fs for the
81
+ * hosted bundle. */
82
+ resolveHookFields?: (name: string, args: Record<string, unknown>) => Record<string, unknown> | undefined;
80
83
  serverVersion: string;
81
84
  instructions: string;
82
85
  profile: string;
@@ -126,7 +129,9 @@ declare function createMindGraphServer(opts: MindGraphServerOptions): Server;
126
129
  /**
127
130
  * Serve one Streamable HTTP request statelessly (D6). The caller has already
128
131
  * verified the bearer and resolved `opts`; this helper owns only the JSON-RPC
129
- * surface: non-POST → 405, unparsable → 400, batches → 400, else the SDK.
132
+ * surface: non-POST → 405, unparsable → 400, batches → 400, else the SDK —
133
+ * the 2026-07-28 path for requests that carry the per-request envelope, the
134
+ * 2025 stateless path for every other client.
130
135
  */
131
136
  declare function handleHostedRequest(request: Request, opts: MindGraphServerOptions): Promise<Response>;
132
137
 
package/dist/server.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
1
+ import { Tool, Server } from '@modelcontextprotocol/server';
2
2
  import { MindGraph } from 'mindgraph';
3
- import { Tool } from '@modelcontextprotocol/sdk/types.js';
4
3
 
5
4
  interface GeneratedToolDescriptor {
6
5
  name: string;
@@ -77,6 +76,10 @@ interface MemoryRuntimeConfig {
77
76
  /** Everything the request handlers close over. */
78
77
  interface ServerWiring {
79
78
  client: MindGraph;
79
+ /** Fields a local harness hook recorded for a call (see call-ledger.ts).
80
+ * Injected by the stdio entry so this module stays free of node:fs for the
81
+ * hosted bundle. */
82
+ resolveHookFields?: (name: string, args: Record<string, unknown>) => Record<string, unknown> | undefined;
80
83
  serverVersion: string;
81
84
  instructions: string;
82
85
  profile: string;
@@ -126,7 +129,9 @@ declare function createMindGraphServer(opts: MindGraphServerOptions): Server;
126
129
  /**
127
130
  * Serve one Streamable HTTP request statelessly (D6). The caller has already
128
131
  * verified the bearer and resolved `opts`; this helper owns only the JSON-RPC
129
- * surface: non-POST → 405, unparsable → 400, batches → 400, else the SDK.
132
+ * surface: non-POST → 405, unparsable → 400, batches → 400, else the SDK —
133
+ * the 2026-07-28 path for requests that carry the per-request envelope, the
134
+ * 2025 stateless path for every other client.
130
135
  */
131
136
  declare function handleHostedRequest(request: Request, opts: MindGraphServerOptions): Promise<Response>;
132
137
 
package/dist/server.js CHANGED
@@ -35,9 +35,7 @@ __export(server_exports, {
35
35
  handleHostedRequest: () => handleHostedRequest
36
36
  });
37
37
  module.exports = __toCommonJS(server_exports);
38
- var import_server = require("@modelcontextprotocol/sdk/server/index.js");
39
- var import_webStandardStreamableHttp = require("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
40
- var import_types = require("@modelcontextprotocol/sdk/types.js");
38
+ var import_server = require("@modelcontextprotocol/server");
41
39
 
42
40
  // src/error-detail.ts
43
41
  var import_mindgraph = require("mindgraph");
@@ -331,6 +329,14 @@ function hiddenSections(payload) {
331
329
  function renderContext(response, maxChars) {
332
330
  const payload = obj(response);
333
331
  if (!payload) return void 0;
332
+ if (typeof payload.context_text === "string" && payload.context_text.length > 0) {
333
+ const text2 = payload.context_text;
334
+ if (maxChars !== void 0 && text2.length > maxChars) {
335
+ return `${text2.slice(0, maxChars)}
336
+ [truncated to ${maxChars} characters]`;
337
+ }
338
+ return text2;
339
+ }
334
340
  const graph = obj(payload.graph);
335
341
  const rawNodes = Array.isArray(graph?.nodes) ? graph.nodes : [];
336
342
  const shaped = rawNodes.filter(isNodeShaped);
@@ -4465,6 +4471,15 @@ var TOOLS = [
4465
4471
  type: "string",
4466
4472
  description: "ISO-8601 date (e.g. '2021-06') for context: nodes with validity windows are annotated as of this date instead of today"
4467
4473
  },
4474
+ as_of: {
4475
+ type: "string",
4476
+ description: "ISO-8601 date for context: answer with what had been STATED by this date (a node is admitted when one of its sources was stated on or before it; fact dates never exclude it). Use for 'what did we know / what was the value as of <date>' questions."
4477
+ },
4478
+ retrieval_mode: {
4479
+ type: "string",
4480
+ enum: ["normal", "exhaustive"],
4481
+ description: "context: 'exhaustive' widens retrieval for list/count questions ('how many different \u2026 across', 'what two \u2026'); omitted lets the server's cue decide."
4482
+ },
4468
4483
  created_after: {
4469
4484
  type: "number",
4470
4485
  description: "Unix seconds \u2014 'recent' action: only nodes ingested after this time"
@@ -5693,6 +5708,8 @@ async function handleRetrieve(client, args, profile) {
5693
5708
  salience_min,
5694
5709
  article_limit,
5695
5710
  valid_at,
5711
+ as_of,
5712
+ retrieval_mode,
5696
5713
  created_after,
5697
5714
  created_before,
5698
5715
  explain,
@@ -5721,9 +5738,15 @@ async function handleRetrieve(client, args, profile) {
5721
5738
  // the advertised knob must not get a silent no-op).
5722
5739
  ...article_limit !== void 0 ? { article_limit } : include_documents === false || profile === "coding" && !include_documents ? { article_limit: 0 } : {},
5723
5740
  valid_at,
5741
+ as_of,
5742
+ retrieval_mode,
5724
5743
  include_graph,
5725
5744
  graph_expansion_limit: graph_expansion_limit ?? 3,
5726
- graph_max_depth: graph_max_depth ?? 2
5745
+ graph_max_depth: graph_max_depth ?? 2,
5746
+ // Evidence plan R2: the server's canonical rendering under a token
5747
+ // budget derived from the character budget; the local renderer is
5748
+ // the fallback for servers that predate it.
5749
+ ...format === "json" ? {} : { format: "text", max_tokens: Math.max(256, Math.floor((max_output_chars ?? 24e3) / 4)) }
5727
5750
  }),
5728
5751
  (raw) => renderContext(raw, max_output_chars)
5729
5752
  );
@@ -6184,7 +6207,7 @@ function buildMindGraphServer(wiring) {
6184
6207
  instructions: wiring.instructions
6185
6208
  }
6186
6209
  );
6187
- server.setRequestHandler(import_types.ListToolsRequestSchema, async () => {
6210
+ server.setRequestHandler("tools/list", async () => {
6188
6211
  const generated = await getGeneratedTools(client, wiring.generatedTools);
6189
6212
  const tools = [...toolsForProfile(wiring.profile), ...generated.tools];
6190
6213
  if (!hosted) return { tools };
@@ -6195,9 +6218,14 @@ function buildMindGraphServer(wiring) {
6195
6218
  ]
6196
6219
  };
6197
6220
  });
6198
- server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
6221
+ server.setRequestHandler("tools/call", async (request) => {
6199
6222
  const { name, arguments: args } = request.params;
6200
- const rawArgs = { ...args || {} };
6223
+ const rawArgs = {
6224
+ ...args || {},
6225
+ // H1: session, lease and invocation fields the local hook recorded for
6226
+ // this exact call (stdio only; hosted mode has no local hook).
6227
+ ...hosted ? {} : wiring.resolveHookFields?.(name, args || {})
6228
+ };
6201
6229
  const toolArgs = { ...rawArgs };
6202
6230
  let governanceConfig = wiring.governance;
6203
6231
  if (hosted) {
@@ -6237,20 +6265,20 @@ function buildMindGraphServer(wiring) {
6237
6265
  }
6238
6266
  return handleTool(client, name, toolArgs, wiring.memory);
6239
6267
  });
6240
- server.setRequestHandler(import_types.ListPromptsRequestSchema, async () => {
6268
+ server.setRequestHandler("prompts/list", async () => {
6241
6269
  return { prompts: PROMPTS };
6242
6270
  });
6243
- server.setRequestHandler(import_types.GetPromptRequestSchema, async (request) => {
6271
+ server.setRequestHandler("prompts/get", async (request) => {
6244
6272
  const { name, arguments: args } = request.params;
6245
6273
  return getPrompt(name, args);
6246
6274
  });
6247
- server.setRequestHandler(import_types.ListResourcesRequestSchema, async () => {
6275
+ server.setRequestHandler("resources/list", async () => {
6248
6276
  return { resources: RESOURCES };
6249
6277
  });
6250
- server.setRequestHandler(import_types.ListResourceTemplatesRequestSchema, async () => {
6278
+ server.setRequestHandler("resources/templates/list", async () => {
6251
6279
  return { resourceTemplates: RESOURCE_TEMPLATES };
6252
6280
  });
6253
- server.setRequestHandler(import_types.ReadResourceRequestSchema, async (request) => {
6281
+ server.setRequestHandler("resources/read", async (request) => {
6254
6282
  return readGovernedResource(
6255
6283
  client,
6256
6284
  request.params.uri,
@@ -6316,8 +6344,21 @@ async function handleHostedRequest(request, opts) {
6316
6344
  if (Array.isArray(parsedBody)) {
6317
6345
  return jsonRpcError(400, -32600, "JSON-RPC batches are not accepted");
6318
6346
  }
6347
+ if (!await (0, import_server.isLegacyRequest)(request, parsedBody)) {
6348
+ const modern = (0, import_server.createMcpHandler)(() => createMindGraphServer(opts), {
6349
+ legacy: "reject"
6350
+ // Default response mode: one JSON body unless a handler emits a message
6351
+ // before its result. No tool does today; a tool that starts emitting
6352
+ // progress must also stop this function closing the handler on return.
6353
+ });
6354
+ try {
6355
+ return await modern.fetch(request, { parsedBody });
6356
+ } finally {
6357
+ await modern.close();
6358
+ }
6359
+ }
6319
6360
  const server = createMindGraphServer(opts);
6320
- const transport = new import_webStandardStreamableHttp.WebStandardStreamableHTTPServerTransport({
6361
+ const transport = new import_server.WebStandardStreamableHTTPServerTransport({
6321
6362
  sessionIdGenerator: void 0,
6322
6363
  enableJsonResponse: true
6323
6364
  });
package/dist/server.mjs CHANGED
@@ -1,15 +1,10 @@
1
1
  // src/server.ts
2
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
- import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
4
2
  import {
5
- CallToolRequestSchema,
6
- GetPromptRequestSchema,
7
- ListPromptsRequestSchema,
8
- ListResourcesRequestSchema,
9
- ListResourceTemplatesRequestSchema,
10
- ListToolsRequestSchema,
11
- ReadResourceRequestSchema
12
- } from "@modelcontextprotocol/sdk/types.js";
3
+ createMcpHandler,
4
+ isLegacyRequest,
5
+ Server,
6
+ WebStandardStreamableHTTPServerTransport
7
+ } from "@modelcontextprotocol/server";
13
8
 
14
9
  // src/error-detail.ts
15
10
  import { MindGraphError } from "mindgraph";
@@ -303,6 +298,14 @@ function hiddenSections(payload) {
303
298
  function renderContext(response, maxChars) {
304
299
  const payload = obj(response);
305
300
  if (!payload) return void 0;
301
+ if (typeof payload.context_text === "string" && payload.context_text.length > 0) {
302
+ const text2 = payload.context_text;
303
+ if (maxChars !== void 0 && text2.length > maxChars) {
304
+ return `${text2.slice(0, maxChars)}
305
+ [truncated to ${maxChars} characters]`;
306
+ }
307
+ return text2;
308
+ }
306
309
  const graph = obj(payload.graph);
307
310
  const rawNodes = Array.isArray(graph?.nodes) ? graph.nodes : [];
308
311
  const shaped = rawNodes.filter(isNodeShaped);
@@ -4452,6 +4455,15 @@ var TOOLS = [
4452
4455
  type: "string",
4453
4456
  description: "ISO-8601 date (e.g. '2021-06') for context: nodes with validity windows are annotated as of this date instead of today"
4454
4457
  },
4458
+ as_of: {
4459
+ type: "string",
4460
+ description: "ISO-8601 date for context: answer with what had been STATED by this date (a node is admitted when one of its sources was stated on or before it; fact dates never exclude it). Use for 'what did we know / what was the value as of <date>' questions."
4461
+ },
4462
+ retrieval_mode: {
4463
+ type: "string",
4464
+ enum: ["normal", "exhaustive"],
4465
+ description: "context: 'exhaustive' widens retrieval for list/count questions ('how many different \u2026 across', 'what two \u2026'); omitted lets the server's cue decide."
4466
+ },
4455
4467
  created_after: {
4456
4468
  type: "number",
4457
4469
  description: "Unix seconds \u2014 'recent' action: only nodes ingested after this time"
@@ -5680,6 +5692,8 @@ async function handleRetrieve(client, args, profile) {
5680
5692
  salience_min,
5681
5693
  article_limit,
5682
5694
  valid_at,
5695
+ as_of,
5696
+ retrieval_mode,
5683
5697
  created_after,
5684
5698
  created_before,
5685
5699
  explain,
@@ -5708,9 +5722,15 @@ async function handleRetrieve(client, args, profile) {
5708
5722
  // the advertised knob must not get a silent no-op).
5709
5723
  ...article_limit !== void 0 ? { article_limit } : include_documents === false || profile === "coding" && !include_documents ? { article_limit: 0 } : {},
5710
5724
  valid_at,
5725
+ as_of,
5726
+ retrieval_mode,
5711
5727
  include_graph,
5712
5728
  graph_expansion_limit: graph_expansion_limit ?? 3,
5713
- graph_max_depth: graph_max_depth ?? 2
5729
+ graph_max_depth: graph_max_depth ?? 2,
5730
+ // Evidence plan R2: the server's canonical rendering under a token
5731
+ // budget derived from the character budget; the local renderer is
5732
+ // the fallback for servers that predate it.
5733
+ ...format === "json" ? {} : { format: "text", max_tokens: Math.max(256, Math.floor((max_output_chars ?? 24e3) / 4)) }
5714
5734
  }),
5715
5735
  (raw) => renderContext(raw, max_output_chars)
5716
5736
  );
@@ -6171,7 +6191,7 @@ function buildMindGraphServer(wiring) {
6171
6191
  instructions: wiring.instructions
6172
6192
  }
6173
6193
  );
6174
- server.setRequestHandler(ListToolsRequestSchema, async () => {
6194
+ server.setRequestHandler("tools/list", async () => {
6175
6195
  const generated = await getGeneratedTools(client, wiring.generatedTools);
6176
6196
  const tools = [...toolsForProfile(wiring.profile), ...generated.tools];
6177
6197
  if (!hosted) return { tools };
@@ -6182,9 +6202,14 @@ function buildMindGraphServer(wiring) {
6182
6202
  ]
6183
6203
  };
6184
6204
  });
6185
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
6205
+ server.setRequestHandler("tools/call", async (request) => {
6186
6206
  const { name, arguments: args } = request.params;
6187
- const rawArgs = { ...args || {} };
6207
+ const rawArgs = {
6208
+ ...args || {},
6209
+ // H1: session, lease and invocation fields the local hook recorded for
6210
+ // this exact call (stdio only; hosted mode has no local hook).
6211
+ ...hosted ? {} : wiring.resolveHookFields?.(name, args || {})
6212
+ };
6188
6213
  const toolArgs = { ...rawArgs };
6189
6214
  let governanceConfig = wiring.governance;
6190
6215
  if (hosted) {
@@ -6224,20 +6249,20 @@ function buildMindGraphServer(wiring) {
6224
6249
  }
6225
6250
  return handleTool(client, name, toolArgs, wiring.memory);
6226
6251
  });
6227
- server.setRequestHandler(ListPromptsRequestSchema, async () => {
6252
+ server.setRequestHandler("prompts/list", async () => {
6228
6253
  return { prompts: PROMPTS };
6229
6254
  });
6230
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
6255
+ server.setRequestHandler("prompts/get", async (request) => {
6231
6256
  const { name, arguments: args } = request.params;
6232
6257
  return getPrompt(name, args);
6233
6258
  });
6234
- server.setRequestHandler(ListResourcesRequestSchema, async () => {
6259
+ server.setRequestHandler("resources/list", async () => {
6235
6260
  return { resources: RESOURCES };
6236
6261
  });
6237
- server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
6262
+ server.setRequestHandler("resources/templates/list", async () => {
6238
6263
  return { resourceTemplates: RESOURCE_TEMPLATES };
6239
6264
  });
6240
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
6265
+ server.setRequestHandler("resources/read", async (request) => {
6241
6266
  return readGovernedResource(
6242
6267
  client,
6243
6268
  request.params.uri,
@@ -6303,6 +6328,19 @@ async function handleHostedRequest(request, opts) {
6303
6328
  if (Array.isArray(parsedBody)) {
6304
6329
  return jsonRpcError(400, -32600, "JSON-RPC batches are not accepted");
6305
6330
  }
6331
+ if (!await isLegacyRequest(request, parsedBody)) {
6332
+ const modern = createMcpHandler(() => createMindGraphServer(opts), {
6333
+ legacy: "reject"
6334
+ // Default response mode: one JSON body unless a handler emits a message
6335
+ // before its result. No tool does today; a tool that starts emitting
6336
+ // progress must also stop this function closing the handler on return.
6337
+ });
6338
+ try {
6339
+ return await modern.fetch(request, { parsedBody });
6340
+ } finally {
6341
+ await modern.close();
6342
+ }
6343
+ }
6306
6344
  const server = createMindGraphServer(opts);
6307
6345
  const transport = new WebStandardStreamableHTTPServerTransport({
6308
6346
  sessionIdGenerator: void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph-mcp",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "MCP server for MindGraph \u2014 connect Claude Desktop, Claude Code, and any MCP client to your knowledge graph",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,11 +42,15 @@
42
42
  "agent"
43
43
  ],
44
44
  "license": "MIT",
45
+ "engines": {
46
+ "node": ">=20"
47
+ },
45
48
  "dependencies": {
46
- "@modelcontextprotocol/sdk": "^1.25.0",
47
- "mindgraph": "^0.16.0"
49
+ "@modelcontextprotocol/server": "^2.4.0",
50
+ "mindgraph": "^0.17.0"
48
51
  },
49
52
  "devDependencies": {
53
+ "@modelcontextprotocol/client": "^2.4.0",
50
54
  "@types/node": "^22.0.0",
51
55
  "tsup": "^8.0.0",
52
56
  "typescript": "^5.7.0",