@contextstream/mcp-server 0.3.72 → 0.3.73

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.
Files changed (2) hide show
  1. package/dist/index.js +247 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8431,6 +8431,86 @@ function getBundleInfo() {
8431
8431
  }));
8432
8432
  }
8433
8433
  var deferredTools = /* @__PURE__ */ new Map();
8434
+ var ROUTER_MODE = process.env.CONTEXTSTREAM_ROUTER_MODE === "true";
8435
+ var operationsRegistry = /* @__PURE__ */ new Map();
8436
+ function inferOperationCategory(name) {
8437
+ if (name.startsWith("session_") || name.startsWith("context_")) return "Session";
8438
+ if (name.startsWith("memory_")) return "Memory";
8439
+ if (name.startsWith("search_")) return "Search";
8440
+ if (name.startsWith("graph_")) return "Graph";
8441
+ if (name.startsWith("workspace")) return "Workspace";
8442
+ if (name.startsWith("project")) return "Project";
8443
+ if (name.startsWith("reminder")) return "Reminders";
8444
+ if (name.startsWith("slack_") || name.startsWith("github_") || name.startsWith("integration")) return "Integrations";
8445
+ if (name.startsWith("ai_")) return "AI";
8446
+ if (name === "auth_me" || name === "mcp_server_version" || name === "generate_editor_rules") return "Utility";
8447
+ if (name === "tools_enable_bundle" || name === "contextstream" || name === "contextstream_help") return "Meta";
8448
+ return "Other";
8449
+ }
8450
+ function getOperationCatalog(category) {
8451
+ const ops = {};
8452
+ for (const [name, config] of operationsRegistry) {
8453
+ const cat = config.category;
8454
+ if (category && cat.toLowerCase() !== category.toLowerCase()) continue;
8455
+ if (!ops[cat]) ops[cat] = [];
8456
+ ops[cat].push(name);
8457
+ }
8458
+ const lines = [];
8459
+ for (const [cat, names] of Object.entries(ops).sort()) {
8460
+ lines.push(`${cat}: ${names.join(", ")}`);
8461
+ }
8462
+ return lines.join("\n");
8463
+ }
8464
+ function getOperationSchema(name) {
8465
+ const op = operationsRegistry.get(name);
8466
+ if (!op) return null;
8467
+ const zodSchema = op.inputSchema;
8468
+ try {
8469
+ const shape = zodSchema?._def?.shape?.() || zodSchema?.shape || {};
8470
+ const properties = {};
8471
+ const required = [];
8472
+ for (const [key, field] of Object.entries(shape)) {
8473
+ const f = field;
8474
+ const isOptional = f?._def?.typeName === "ZodOptional" || f?.isOptional?.();
8475
+ const innerType = isOptional ? f?._def?.innerType : f;
8476
+ const typeName = innerType?._def?.typeName || "unknown";
8477
+ const description = f?._def?.description || innerType?._def?.description;
8478
+ let type = "string";
8479
+ if (typeName === "ZodNumber") type = "number";
8480
+ else if (typeName === "ZodBoolean") type = "boolean";
8481
+ else if (typeName === "ZodArray") type = "array";
8482
+ else if (typeName === "ZodObject") type = "object";
8483
+ else if (typeName === "ZodEnum") type = "enum";
8484
+ properties[key] = { type };
8485
+ if (description) properties[key].description = description;
8486
+ if (typeName === "ZodEnum") {
8487
+ properties[key].enum = innerType?._def?.values;
8488
+ }
8489
+ if (!isOptional) required.push(key);
8490
+ }
8491
+ return {
8492
+ name: op.name,
8493
+ title: op.title,
8494
+ description: op.description,
8495
+ category: op.category,
8496
+ schema: {
8497
+ type: "object",
8498
+ properties,
8499
+ required: required.length > 0 ? required : void 0
8500
+ }
8501
+ };
8502
+ } catch {
8503
+ return {
8504
+ name: op.name,
8505
+ title: op.title,
8506
+ description: op.description,
8507
+ category: op.category,
8508
+ schema: { type: "object" }
8509
+ };
8510
+ }
8511
+ }
8512
+ var OUTPUT_FORMAT = process.env.CONTEXTSTREAM_OUTPUT_FORMAT || "compact";
8513
+ var COMPACT_OUTPUT = OUTPUT_FORMAT === "compact";
8434
8514
  var TOOLSET_ALIASES = {
8435
8515
  // Light mode - minimal, fastest
8436
8516
  light: LIGHT_TOOLSET,
@@ -8493,8 +8573,9 @@ function resolveToolFilter() {
8493
8573
  console.error(`[ContextStream] Unknown CONTEXTSTREAM_TOOLSET "${toolsetRaw}". Using standard toolset.`);
8494
8574
  return { allowlist: STANDARD_TOOLSET, source: "standard", autoDetected: false };
8495
8575
  }
8496
- function formatContent(data) {
8497
- return JSON.stringify(data, null, 2);
8576
+ function formatContent(data, forceFormat) {
8577
+ const usePretty = forceFormat === "pretty" || !forceFormat && !COMPACT_OUTPUT;
8578
+ return usePretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
8498
8579
  }
8499
8580
  function toStructured(data) {
8500
8581
  if (data && typeof data === "object" && !Array.isArray(data)) {
@@ -8632,6 +8713,15 @@ function registerTools(server, client, sessionManager) {
8632
8713
  console.error(`[ContextStream] Progressive mode: ENABLED (starting with ${coreBundle.size} core tools)`);
8633
8714
  console.error("[ContextStream] Use tools_enable_bundle to unlock additional tool bundles dynamically.");
8634
8715
  }
8716
+ if (ROUTER_MODE) {
8717
+ console.error("[ContextStream] Router mode: ENABLED (all operations accessed via contextstream/contextstream_help)");
8718
+ console.error("[ContextStream] Only 2 tools registered. Use contextstream_help to see available operations.");
8719
+ }
8720
+ if (COMPACT_OUTPUT) {
8721
+ console.error("[ContextStream] Output format: COMPACT (minified JSON, ~30% fewer tokens per response)");
8722
+ } else {
8723
+ console.error("[ContextStream] Output format: pretty (set CONTEXTSTREAM_OUTPUT_FORMAT=compact for fewer tokens)");
8724
+ }
8635
8725
  let serverRef = server;
8636
8726
  const defaultProTools = /* @__PURE__ */ new Set([
8637
8727
  // AI endpoints (typically paid/credit-metered)
@@ -9015,13 +9105,35 @@ Upgrade: ${upgradeUrl2}` : "";
9015
9105
  console.error(`[ContextStream] Bundle '${bundleName}' enabled with ${toolsEnabled} tools.`);
9016
9106
  return { success: true, message: `Enabled bundle '${bundleName}' with ${toolsEnabled} tools.`, toolsEnabled };
9017
9107
  }
9108
+ const ROUTER_DIRECT_TOOLS = /* @__PURE__ */ new Set(["contextstream", "contextstream_help"]);
9018
9109
  function registerTool(name, config, handler) {
9019
9110
  if (toolAllowlist && !toolAllowlist.has(name)) {
9111
+ if (ROUTER_MODE && !ROUTER_DIRECT_TOOLS.has(name)) {
9112
+ operationsRegistry.set(name, {
9113
+ name,
9114
+ title: config.title,
9115
+ description: config.description,
9116
+ inputSchema: config.inputSchema,
9117
+ handler,
9118
+ category: inferOperationCategory(name)
9119
+ });
9120
+ }
9020
9121
  return;
9021
9122
  }
9022
9123
  if (!shouldRegisterIntegrationTool(name)) {
9023
9124
  return;
9024
9125
  }
9126
+ if (ROUTER_MODE && !ROUTER_DIRECT_TOOLS.has(name)) {
9127
+ operationsRegistry.set(name, {
9128
+ name,
9129
+ title: config.title,
9130
+ description: config.description,
9131
+ inputSchema: config.inputSchema,
9132
+ handler,
9133
+ category: inferOperationCategory(name)
9134
+ });
9135
+ return;
9136
+ }
9025
9137
  if (PROGRESSIVE_MODE && !isToolInEnabledBundles(name)) {
9026
9138
  deferredTools.set(name, { name, config, handler });
9027
9139
  return;
@@ -9147,6 +9259,137 @@ Example: Enable memory tools before using memory_create_event.`,
9147
9259
  return { content: [{ type: "text", text: formatContent(response) }], structuredContent: toStructured(response) };
9148
9260
  }
9149
9261
  );
9262
+ if (ROUTER_MODE) {
9263
+ serverRef.registerTool(
9264
+ "contextstream",
9265
+ {
9266
+ title: "ContextStream Operation",
9267
+ description: `Execute any ContextStream operation. Use contextstream_help to see available operations.
9268
+
9269
+ Example: contextstream({ op: "session_init", args: { folder_path: "/path/to/project" } })
9270
+
9271
+ This single tool replaces 50+ individual tools, dramatically reducing token overhead.
9272
+ All ContextStream functionality is accessible through this dispatcher.`,
9273
+ inputSchema: {
9274
+ type: "object",
9275
+ properties: {
9276
+ op: { type: "string", description: "Operation name (e.g., session_init, memory_create_event)" },
9277
+ args: { type: "object", description: "Operation arguments (varies by operation)" }
9278
+ },
9279
+ required: ["op"]
9280
+ },
9281
+ annotations: {
9282
+ readOnlyHint: false,
9283
+ destructiveHint: false,
9284
+ idempotentHint: false,
9285
+ openWorldHint: false
9286
+ }
9287
+ },
9288
+ async (input) => {
9289
+ const opName = input.op;
9290
+ const operation = operationsRegistry.get(opName);
9291
+ if (!operation) {
9292
+ const available = getOperationCatalog();
9293
+ return {
9294
+ content: [{
9295
+ type: "text",
9296
+ text: `Unknown operation: ${opName}
9297
+
9298
+ Available operations:
9299
+ ${available}
9300
+
9301
+ Use contextstream_help({ op: "operation_name" }) for details.`
9302
+ }],
9303
+ isError: true
9304
+ };
9305
+ }
9306
+ const args = input.args || {};
9307
+ const parsed = operation.inputSchema.safeParse(args);
9308
+ if (!parsed.success) {
9309
+ const schema = getOperationSchema(opName);
9310
+ return {
9311
+ content: [{
9312
+ type: "text",
9313
+ text: `Invalid arguments for ${opName}: ${parsed.error.message}
9314
+
9315
+ Expected schema:
9316
+ ${JSON.stringify(schema?.schema || {}, null, 2)}`
9317
+ }],
9318
+ isError: true
9319
+ };
9320
+ }
9321
+ try {
9322
+ return await operation.handler(parsed.data);
9323
+ } catch (error) {
9324
+ return {
9325
+ content: [{
9326
+ type: "text",
9327
+ text: `Error executing ${opName}: ${error?.message || String(error)}`
9328
+ }],
9329
+ isError: true
9330
+ };
9331
+ }
9332
+ }
9333
+ );
9334
+ serverRef.registerTool(
9335
+ "contextstream_help",
9336
+ {
9337
+ title: "ContextStream Help",
9338
+ description: `Get help on available ContextStream operations or schema for a specific operation.
9339
+
9340
+ Examples:
9341
+ - contextstream_help({}) - List all operations by category
9342
+ - contextstream_help({ op: "session_init" }) - Get schema for session_init
9343
+ - contextstream_help({ category: "Memory" }) - List memory operations only`,
9344
+ inputSchema: {
9345
+ type: "object",
9346
+ properties: {
9347
+ op: { type: "string", description: "Operation name to get schema for" },
9348
+ category: { type: "string", description: "Category to filter (Session, Memory, Search, Graph, etc.)" }
9349
+ }
9350
+ },
9351
+ annotations: {
9352
+ readOnlyHint: true,
9353
+ destructiveHint: false,
9354
+ idempotentHint: true,
9355
+ openWorldHint: false
9356
+ }
9357
+ },
9358
+ async (input) => {
9359
+ if (input.op) {
9360
+ const schema = getOperationSchema(input.op);
9361
+ if (!schema) {
9362
+ return {
9363
+ content: [{
9364
+ type: "text",
9365
+ text: `Unknown operation: ${input.op}
9366
+
9367
+ Use contextstream_help({}) to see available operations.`
9368
+ }],
9369
+ isError: true
9370
+ };
9371
+ }
9372
+ return {
9373
+ content: [{ type: "text", text: JSON.stringify(schema, null, 2) }],
9374
+ structuredContent: schema
9375
+ };
9376
+ }
9377
+ const catalog = getOperationCatalog(input.category);
9378
+ const result = {
9379
+ router_mode: true,
9380
+ total_operations: operationsRegistry.size,
9381
+ categories: catalog,
9382
+ usage: 'Call contextstream({ op: "operation_name", args: {...} }) to execute an operation.',
9383
+ hint: 'Use contextstream_help({ op: "operation_name" }) to see the schema for a specific operation.'
9384
+ };
9385
+ return {
9386
+ content: [{ type: "text", text: formatContent(result) }],
9387
+ structuredContent: toStructured(result)
9388
+ };
9389
+ }
9390
+ );
9391
+ console.error(`[ContextStream] Router mode: Registered 2 meta-tools, ${operationsRegistry.size} operations available via dispatcher.`);
9392
+ }
9150
9393
  registerTool(
9151
9394
  "workspaces_list",
9152
9395
  {
@@ -14534,6 +14777,8 @@ Environment variables:
14534
14777
  CONTEXTSTREAM_AUTO_HIDE_INTEGRATIONS Auto-hide Slack/GitHub tools when not connected (default: true)
14535
14778
  CONTEXTSTREAM_SCHEMA_MODE Schema verbosity: compact|full (default: full, compact reduces tokens)
14536
14779
  CONTEXTSTREAM_PROGRESSIVE_MODE Progressive disclosure: true|false (default: false, starts with ~13 core tools)
14780
+ CONTEXTSTREAM_ROUTER_MODE Router pattern: true|false (default: false, exposes only 2 meta-tools)
14781
+ CONTEXTSTREAM_OUTPUT_FORMAT Output verbosity: compact|pretty (default: compact, ~30% fewer tokens)
14537
14782
  CONTEXTSTREAM_PRO_TOOLS Optional comma-separated PRO tool names (default: AI tools)
14538
14783
  CONTEXTSTREAM_UPGRADE_URL Optional upgrade URL shown for PRO tools on Free plan
14539
14784
  CONTEXTSTREAM_ENABLE_PROMPTS Enable MCP prompts list (default: true)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@contextstream/mcp-server",
3
3
  "mcpName": "io.github.contextstreamio/mcp-server",
4
- "version": "0.3.72",
4
+ "version": "0.3.73",
5
5
  "description": "MCP server exposing ContextStream public API - code context, memory, search, and AI tools for developers",
6
6
  "type": "module",
7
7
  "license": "MIT",