@gramatr/mcp 0.0.5

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 (61) hide show
  1. package/dist/bin/gramatr-mcp.d.ts +18 -0
  2. package/dist/bin/gramatr-mcp.d.ts.map +1 -0
  3. package/dist/bin/gramatr-mcp.js +69 -0
  4. package/dist/bin/gramatr-mcp.js.map +1 -0
  5. package/dist/bin/setup.d.ts +13 -0
  6. package/dist/bin/setup.d.ts.map +1 -0
  7. package/dist/bin/setup.js +93 -0
  8. package/dist/bin/setup.js.map +1 -0
  9. package/dist/cache/lru-cache.d.ts +57 -0
  10. package/dist/cache/lru-cache.d.ts.map +1 -0
  11. package/dist/cache/lru-cache.js +159 -0
  12. package/dist/cache/lru-cache.js.map +1 -0
  13. package/dist/intelligence/packet2-fetcher.d.ts +33 -0
  14. package/dist/intelligence/packet2-fetcher.d.ts.map +1 -0
  15. package/dist/intelligence/packet2-fetcher.js +87 -0
  16. package/dist/intelligence/packet2-fetcher.js.map +1 -0
  17. package/dist/intelligence/session-manager.d.ts +22 -0
  18. package/dist/intelligence/session-manager.d.ts.map +1 -0
  19. package/dist/intelligence/session-manager.js +85 -0
  20. package/dist/intelligence/session-manager.js.map +1 -0
  21. package/dist/metrics/collector.d.ts +51 -0
  22. package/dist/metrics/collector.d.ts.map +1 -0
  23. package/dist/metrics/collector.js +123 -0
  24. package/dist/metrics/collector.js.map +1 -0
  25. package/dist/proxy/remote-client.d.ts +16 -0
  26. package/dist/proxy/remote-client.d.ts.map +1 -0
  27. package/dist/proxy/remote-client.js +109 -0
  28. package/dist/proxy/remote-client.js.map +1 -0
  29. package/dist/proxy/tool-proxy.d.ts +26 -0
  30. package/dist/proxy/tool-proxy.d.ts.map +1 -0
  31. package/dist/proxy/tool-proxy.js +123 -0
  32. package/dist/proxy/tool-proxy.js.map +1 -0
  33. package/dist/proxy/tool-registry.d.ts +33 -0
  34. package/dist/proxy/tool-registry.d.ts.map +1 -0
  35. package/dist/proxy/tool-registry.js +48 -0
  36. package/dist/proxy/tool-registry.js.map +1 -0
  37. package/dist/queue/offline-queue.d.ts +41 -0
  38. package/dist/queue/offline-queue.d.ts.map +1 -0
  39. package/dist/queue/offline-queue.js +96 -0
  40. package/dist/queue/offline-queue.js.map +1 -0
  41. package/dist/queue/replay.d.ts +19 -0
  42. package/dist/queue/replay.d.ts.map +1 -0
  43. package/dist/queue/replay.js +60 -0
  44. package/dist/queue/replay.js.map +1 -0
  45. package/dist/server/auth.d.ts +23 -0
  46. package/dist/server/auth.d.ts.map +1 -0
  47. package/dist/server/auth.js +66 -0
  48. package/dist/server/auth.js.map +1 -0
  49. package/dist/server/server.d.ts +30 -0
  50. package/dist/server/server.d.ts.map +1 -0
  51. package/dist/server/server.js +92 -0
  52. package/dist/server/server.js.map +1 -0
  53. package/dist/tools/local-tools.d.ts +19 -0
  54. package/dist/tools/local-tools.d.ts.map +1 -0
  55. package/dist/tools/local-tools.js +161 -0
  56. package/dist/tools/local-tools.js.map +1 -0
  57. package/dist/tools/web-tools.d.ts +23 -0
  58. package/dist/tools/web-tools.d.ts.map +1 -0
  59. package/dist/tools/web-tools.js +203 -0
  60. package/dist/tools/web-tools.js.map +1 -0
  61. package/package.json +39 -0
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gramatr-mcp — Local MCP server entry point.
4
+ *
5
+ * Usage:
6
+ * gramatr-mcp Start the stdio MCP server (default)
7
+ * gramatr-mcp setup claude Auto-configure Claude Code MCP settings
8
+ * gramatr-mcp --version Print version
9
+ * gramatr-mcp --help Show help
10
+ *
11
+ * MCP clients configure this as:
12
+ * { "command": "node", "args": ["~/.gramatr/mcp/bin/gramatr-mcp.js"] }
13
+ *
14
+ * Or via npx (slower, checks npm on every invocation):
15
+ * { "command": "npx", "args": ["-y", "@gramatr/mcp"] }
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=gramatr-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gramatr-mcp.d.ts","sourceRoot":"","sources":["../../src/bin/gramatr-mcp.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gramatr-mcp — Local MCP server entry point.
4
+ *
5
+ * Usage:
6
+ * gramatr-mcp Start the stdio MCP server (default)
7
+ * gramatr-mcp setup claude Auto-configure Claude Code MCP settings
8
+ * gramatr-mcp --version Print version
9
+ * gramatr-mcp --help Show help
10
+ *
11
+ * MCP clients configure this as:
12
+ * { "command": "node", "args": ["~/.gramatr/mcp/bin/gramatr-mcp.js"] }
13
+ *
14
+ * Or via npx (slower, checks npm on every invocation):
15
+ * { "command": "npx", "args": ["-y", "@gramatr/mcp"] }
16
+ */
17
+ import { startServer } from '../server/server.js';
18
+ import { setupClaude } from './setup.js';
19
+ const args = process.argv.slice(2);
20
+ if (args.includes('--version') || args.includes('-v')) {
21
+ process.stdout.write('0.0.5\n');
22
+ process.exit(0);
23
+ }
24
+ if (args.includes('--help') || args.includes('-h')) {
25
+ process.stderr.write(`
26
+ gramatr-mcp — Local MCP server for grāmatr
27
+
28
+ Proxies all remote gramatr tools with local auth injection, caching,
29
+ offline queueing, and local web tools.
30
+
31
+ Usage:
32
+ gramatr-mcp Start the server (stdio)
33
+ gramatr-mcp setup claude Configure Claude Code to use this server
34
+ gramatr-mcp --version Print version
35
+ gramatr-mcp --help Show this help
36
+
37
+ Configuration:
38
+ Auth token: ~/.gramatr.json (token field)
39
+ Server URL: GRAMATR_URL env or ~/.gramatr.json server_url
40
+ API key: GRAMATR_API_KEY env (overrides token)
41
+
42
+ Setup:
43
+ gramatr-mcp setup claude Write MCP config to ~/.claude.json
44
+ gramatr-mcp setup claude --dry Preview without writing
45
+ `);
46
+ process.exit(0);
47
+ }
48
+ async function main() {
49
+ // Handle setup subcommand
50
+ if (args[0] === 'setup') {
51
+ const target = args[1];
52
+ const dryRun = args.includes('--dry');
53
+ if (target === 'claude') {
54
+ setupClaude(dryRun);
55
+ return;
56
+ }
57
+ process.stderr.write(`[gramatr-mcp] Unknown setup target: ${target}\n`);
58
+ process.stderr.write(' Supported: gramatr-mcp setup claude\n');
59
+ process.exit(1);
60
+ }
61
+ // Default: start the stdio server
62
+ await startServer();
63
+ }
64
+ main().catch((error) => {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ process.stderr.write(`[gramatr-mcp] Fatal: ${message}\n`);
67
+ process.exit(1);
68
+ });
69
+ //# sourceMappingURL=gramatr-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gramatr-mcp.js","sourceRoot":"","sources":["../../src/bin/gramatr-mcp.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;CAoBtB,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,0BAA0B;IAC1B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,MAAM,IAAI,CAAC,CAAC;QACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kCAAkC;IAClC,MAAM,WAAW,EAAE,CAAC;AACtB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * gramatr setup claude — auto-configure Claude Code to use the local MCP server.
3
+ *
4
+ * Writes the mcpServers entry into ~/.claude.json (Claude Code's global MCP config).
5
+ * Safe: reads existing config, merges in the gramatr server entry, writes back.
6
+ * Idempotent: running it twice produces the same result.
7
+ *
8
+ * Usage:
9
+ * gramatr-mcp setup claude Configure Claude Code
10
+ * gramatr-mcp setup claude --dry Run without writing
11
+ */
12
+ export declare function setupClaude(dryRun?: boolean): void;
13
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA2DH,wBAAgB,WAAW,CAAC,MAAM,UAAQ,GAAG,IAAI,CA+ChD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * gramatr setup claude — auto-configure Claude Code to use the local MCP server.
3
+ *
4
+ * Writes the mcpServers entry into ~/.claude.json (Claude Code's global MCP config).
5
+ * Safe: reads existing config, merges in the gramatr server entry, writes back.
6
+ * Idempotent: running it twice produces the same result.
7
+ *
8
+ * Usage:
9
+ * gramatr-mcp setup claude Configure Claude Code
10
+ * gramatr-mcp setup claude --dry Run without writing
11
+ */
12
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
13
+ import { join, resolve, dirname } from 'node:path';
14
+ import { fileURLToPath } from 'node:url';
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ // gramatr-allow: C1 — CLI entry point, reads HOME for config path
18
+ const HOME = process.env.HOME || process.env.USERPROFILE || '';
19
+ /**
20
+ * Resolve the path to the gramatr-mcp binary.
21
+ * Prefers the compiled dist version, falls back to npx.
22
+ */
23
+ function resolveBinaryPath() {
24
+ // Check if we're installed globally or locally
25
+ const localBin = resolve(__dirname, '../bin/gramatr-mcp.js');
26
+ if (existsSync(localBin)) {
27
+ return { command: 'node', args: [localBin] };
28
+ }
29
+ // Fallback to npx (slower but always works)
30
+ return { command: 'npx', args: ['-y', '@gramatr/mcp'] };
31
+ }
32
+ /**
33
+ * Get the Claude Code config file path.
34
+ * Claude Code stores global MCP config in ~/.claude.json
35
+ */
36
+ function getClaudeConfigPath() {
37
+ return join(HOME, '.claude.json');
38
+ }
39
+ /**
40
+ * Read existing Claude config or return empty.
41
+ */
42
+ function readClaudeConfig(configPath) {
43
+ try {
44
+ const raw = readFileSync(configPath, 'utf8');
45
+ return JSON.parse(raw);
46
+ }
47
+ catch {
48
+ return {};
49
+ }
50
+ }
51
+ export function setupClaude(dryRun = false) {
52
+ const configPath = getClaudeConfigPath();
53
+ const config = readClaudeConfig(configPath);
54
+ // Build the MCP server entry
55
+ const { command, args } = resolveBinaryPath();
56
+ const serverEntry = { command };
57
+ if (args.length > 0) {
58
+ serverEntry.args = args;
59
+ }
60
+ // Check if already configured
61
+ const existing = config.mcpServers?.['gramatr'];
62
+ if (existing) {
63
+ const existingCmd = existing.command;
64
+ const existingArgs = existing.args || [];
65
+ if (existingCmd === command && JSON.stringify(existingArgs) === JSON.stringify(args)) {
66
+ process.stderr.write('[gramatr-mcp] Claude Code already configured. No changes needed.\n');
67
+ return;
68
+ }
69
+ process.stderr.write('[gramatr-mcp] Updating existing gramatr MCP server config.\n');
70
+ }
71
+ // Merge into config
72
+ if (!config.mcpServers) {
73
+ config.mcpServers = {};
74
+ }
75
+ config.mcpServers['gramatr'] = serverEntry;
76
+ if (dryRun) {
77
+ process.stderr.write('[gramatr-mcp] Dry run — would write to: ' + configPath + '\n');
78
+ process.stderr.write(JSON.stringify(config.mcpServers['gramatr'], null, 2) + '\n');
79
+ return;
80
+ }
81
+ // Write back
82
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
83
+ process.stderr.write(`[gramatr-mcp] Configured Claude Code MCP server in ${configPath}\n`);
84
+ process.stderr.write('[gramatr-mcp] Restart Claude Code to pick up the change.\n');
85
+ // Show what was written
86
+ process.stderr.write('\n mcpServers.gramatr:\n');
87
+ process.stderr.write(` command: ${command}\n`);
88
+ if (args.length > 0) {
89
+ process.stderr.write(` args: ${JSON.stringify(args)}\n`);
90
+ }
91
+ process.stderr.write('\n');
92
+ }
93
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Simple in-memory LRU cache for reducing redundant remote round-trips.
3
+ *
4
+ * - Keyed by tool name + serialized args
5
+ * - TTL-based expiration (default 60s)
6
+ * - Evicts on mutation tools (create, update, delete, batch)
7
+ * - Max 100 entries, LRU eviction when full
8
+ * - Dies with the process — no persistence, no disk
9
+ */
10
+ export declare class LRUCache {
11
+ private cache;
12
+ private maxSize;
13
+ private ttlMs;
14
+ private hits;
15
+ private misses;
16
+ private evictions;
17
+ constructor(maxSize?: number, ttlMs?: number);
18
+ /**
19
+ * Build a cache key from tool name + args.
20
+ */
21
+ private key;
22
+ /**
23
+ * Check if a tool call is cacheable.
24
+ */
25
+ isCacheable(toolName: string): boolean;
26
+ /**
27
+ * Check if a tool is a mutation (triggers cache invalidation).
28
+ */
29
+ isMutation(toolName: string): boolean;
30
+ /**
31
+ * Get a cached result. Returns undefined on miss or expiry.
32
+ */
33
+ get(toolName: string, args: Record<string, unknown>): unknown | undefined;
34
+ /**
35
+ * Store a result in the cache.
36
+ */
37
+ set(toolName: string, args: Record<string, unknown>, value: unknown): void;
38
+ /**
39
+ * Clear the entire cache. Called on mutation tool calls.
40
+ */
41
+ clear(): void;
42
+ /**
43
+ * Get cache statistics for the local status tool.
44
+ */
45
+ stats(): {
46
+ size: number;
47
+ maxSize: number;
48
+ ttlMs: number;
49
+ hits: number;
50
+ misses: number;
51
+ evictions: number;
52
+ hitRate: string;
53
+ };
54
+ }
55
+ /** Singleton cache instance. */
56
+ export declare const cache: LRUCache;
57
+ //# sourceMappingURL=lru-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lru-cache.d.ts","sourceRoot":"","sources":["../../src/cache/lru-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+DH,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAK;gBAEV,OAAO,SAAmB,EAAE,KAAK,SAAiB;IAK9D;;OAEG;IACH,OAAO,CAAC,GAAG;IAIX;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIrC;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;IAsBzE;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAuB1E;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,KAAK,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAY5H;AAED,gCAAgC;AAChC,eAAO,MAAM,KAAK,UAAiB,CAAC"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Simple in-memory LRU cache for reducing redundant remote round-trips.
3
+ *
4
+ * - Keyed by tool name + serialized args
5
+ * - TTL-based expiration (default 60s)
6
+ * - Evicts on mutation tools (create, update, delete, batch)
7
+ * - Max 100 entries, LRU eviction when full
8
+ * - Dies with the process — no persistence, no disk
9
+ */
10
+ const DEFAULT_MAX_SIZE = 100;
11
+ const DEFAULT_TTL_MS = 60_000; // 60 seconds
12
+ /** Tools that mutate state — any call to these invalidates the entire cache. */
13
+ const MUTATION_TOOLS = new Set([
14
+ 'create_entity',
15
+ 'update_entity',
16
+ 'mark_entity_inactive',
17
+ 'reactivate_entity',
18
+ 'add_observation',
19
+ 'update_observation',
20
+ 'mark_observation_inactive',
21
+ 'create_relation',
22
+ 'batch_create_entities',
23
+ 'batch_add_observations',
24
+ 'batch_create_relations',
25
+ 'bulk_update_metadata',
26
+ 'change_embedding_model',
27
+ // gramatr_ prefixed mutations
28
+ 'gramatr_save_diary',
29
+ 'gramatr_save_handoff',
30
+ 'gramatr_save_prd',
31
+ 'gramatr_save_reflection',
32
+ 'gramatr_submit_feedback',
33
+ 'gramatr_update_criteria',
34
+ 'gramatr_update_hard_problem',
35
+ 'gramatr_session_start',
36
+ 'gramatr_session_end',
37
+ 'gramatr_batch_save_turns',
38
+ 'gramatr_phase_transition',
39
+ 'gramatr_classification_feedback',
40
+ 'gramatr_generation_feedback',
41
+ 'gramatr_suggestion_feedback',
42
+ 'gramatr_groom_knowledge',
43
+ 'gramatr_maintain_state',
44
+ 'gramatr_compose_agent',
45
+ 'gramatr_create_api_key',
46
+ 'gramatr_revoke_api_key',
47
+ 'gramatr_onboard_user',
48
+ 'gramatr_classifier_manage',
49
+ ]);
50
+ /** Tools that should never be cached (real-time or side-effectful). */
51
+ const UNCACHEABLE_TOOLS = new Set([
52
+ 'gramatr_doctor',
53
+ 'gramatr_get_metrics',
54
+ 'gramatr_route_request',
55
+ 'gramatr_execute_intent',
56
+ 'gramatr_summarize_turn',
57
+ 'gramatr_route_skills',
58
+ 'gramatr_invoke_agent',
59
+ 'gramatr_get_enrichment',
60
+ 'gramatr_competitive_position',
61
+ 'aggregate_stats',
62
+ ]);
63
+ export class LRUCache {
64
+ cache = new Map();
65
+ maxSize;
66
+ ttlMs;
67
+ hits = 0;
68
+ misses = 0;
69
+ evictions = 0;
70
+ constructor(maxSize = DEFAULT_MAX_SIZE, ttlMs = DEFAULT_TTL_MS) {
71
+ this.maxSize = maxSize;
72
+ this.ttlMs = ttlMs;
73
+ }
74
+ /**
75
+ * Build a cache key from tool name + args.
76
+ */
77
+ key(toolName, args) {
78
+ return `${toolName}:${JSON.stringify(args, Object.keys(args).sort())}`;
79
+ }
80
+ /**
81
+ * Check if a tool call is cacheable.
82
+ */
83
+ isCacheable(toolName) {
84
+ return !MUTATION_TOOLS.has(toolName) && !UNCACHEABLE_TOOLS.has(toolName);
85
+ }
86
+ /**
87
+ * Check if a tool is a mutation (triggers cache invalidation).
88
+ */
89
+ isMutation(toolName) {
90
+ return MUTATION_TOOLS.has(toolName);
91
+ }
92
+ /**
93
+ * Get a cached result. Returns undefined on miss or expiry.
94
+ */
95
+ get(toolName, args) {
96
+ const k = this.key(toolName, args);
97
+ const entry = this.cache.get(k);
98
+ if (!entry) {
99
+ this.misses++;
100
+ return undefined;
101
+ }
102
+ if (Date.now() > entry.expiresAt) {
103
+ this.cache.delete(k);
104
+ this.misses++;
105
+ return undefined;
106
+ }
107
+ // LRU: move to end (most recently used)
108
+ this.cache.delete(k);
109
+ this.cache.set(k, entry);
110
+ this.hits++;
111
+ return entry.value;
112
+ }
113
+ /**
114
+ * Store a result in the cache.
115
+ */
116
+ set(toolName, args, value) {
117
+ if (!this.isCacheable(toolName))
118
+ return;
119
+ const k = this.key(toolName, args);
120
+ // Delete first to reset position in Map iteration order
121
+ this.cache.delete(k);
122
+ // Evict oldest if full
123
+ while (this.cache.size >= this.maxSize) {
124
+ const oldest = this.cache.keys().next().value;
125
+ if (oldest !== undefined) {
126
+ this.cache.delete(oldest);
127
+ this.evictions++;
128
+ }
129
+ }
130
+ this.cache.set(k, {
131
+ value,
132
+ expiresAt: Date.now() + this.ttlMs,
133
+ });
134
+ }
135
+ /**
136
+ * Clear the entire cache. Called on mutation tool calls.
137
+ */
138
+ clear() {
139
+ this.cache.clear();
140
+ }
141
+ /**
142
+ * Get cache statistics for the local status tool.
143
+ */
144
+ stats() {
145
+ const total = this.hits + this.misses;
146
+ return {
147
+ size: this.cache.size,
148
+ maxSize: this.maxSize,
149
+ ttlMs: this.ttlMs,
150
+ hits: this.hits,
151
+ misses: this.misses,
152
+ evictions: this.evictions,
153
+ hitRate: total > 0 ? `${((this.hits / total) * 100).toFixed(1)}%` : '0%',
154
+ };
155
+ }
156
+ }
157
+ /** Singleton cache instance. */
158
+ export const cache = new LRUCache();
159
+ //# sourceMappingURL=lru-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lru-cache.js","sourceRoot":"","sources":["../../src/cache/lru-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Packet 2 Auto-Fetcher — automatically fetches enrichment when route_request
3
+ * returns packet_2_status: "pending".
4
+ *
5
+ * Flow:
6
+ * 1. Agent calls gramatr_route_request
7
+ * 2. Server returns Packet 1 immediately with enrichment_id
8
+ * 3. This module detects pending status, calls gramatr_get_enrichment
9
+ * 4. Merges Packet 2 into the response before returning to agent
10
+ *
11
+ * The agent never has to manually call gramatr_get_enrichment — it just works.
12
+ */
13
+ interface ToolCallResult {
14
+ content: Array<{
15
+ type: string;
16
+ text: string;
17
+ }>;
18
+ isError?: boolean;
19
+ }
20
+ /**
21
+ * Check if a tool result is a route_request response with pending Packet 2.
22
+ */
23
+ export declare function hasPendingPacket2(result: ToolCallResult): {
24
+ pending: boolean;
25
+ enrichmentId?: string;
26
+ };
27
+ /**
28
+ * Fetch Packet 2 enrichment and merge into the original response.
29
+ * Retries up to 3 times with 500ms delay (enrichment may still be generating).
30
+ */
31
+ export declare function fetchAndMergePacket2(result: ToolCallResult, enrichmentId: string): Promise<ToolCallResult>;
32
+ export {};
33
+ //# sourceMappingURL=packet2-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packet2-fetcher.d.ts","sourceRoot":"","sources":["../../src/intelligence/packet2-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,UAAU,cAAc;IACtB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAKD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAarG;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAkCzB"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Packet 2 Auto-Fetcher — automatically fetches enrichment when route_request
3
+ * returns packet_2_status: "pending".
4
+ *
5
+ * Flow:
6
+ * 1. Agent calls gramatr_route_request
7
+ * 2. Server returns Packet 1 immediately with enrichment_id
8
+ * 3. This module detects pending status, calls gramatr_get_enrichment
9
+ * 4. Merges Packet 2 into the response before returning to agent
10
+ *
11
+ * The agent never has to manually call gramatr_get_enrichment — it just works.
12
+ */
13
+ import { callRemoteTool } from '../proxy/remote-client.js';
14
+ const MAX_RETRIES = 3;
15
+ const RETRY_DELAY_MS = 500;
16
+ /**
17
+ * Check if a tool result is a route_request response with pending Packet 2.
18
+ */
19
+ export function hasPendingPacket2(result) {
20
+ if (!result.content?.[0]?.text)
21
+ return { pending: false };
22
+ try {
23
+ const data = JSON.parse(result.content[0].text);
24
+ if (data.packet_2_status === 'pending' && data.enrichment_id) {
25
+ return { pending: true, enrichmentId: data.enrichment_id };
26
+ }
27
+ }
28
+ catch {
29
+ // Not JSON or not the expected shape
30
+ }
31
+ return { pending: false };
32
+ }
33
+ /**
34
+ * Fetch Packet 2 enrichment and merge into the original response.
35
+ * Retries up to 3 times with 500ms delay (enrichment may still be generating).
36
+ */
37
+ export async function fetchAndMergePacket2(result, enrichmentId) {
38
+ let enrichment = null;
39
+ for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
40
+ try {
41
+ enrichment = await callRemoteTool('gramatr_get_enrichment', {
42
+ enrichment_id: enrichmentId,
43
+ });
44
+ // Check if enrichment is ready
45
+ const enrichResult = enrichment;
46
+ if (enrichResult?.content?.[0]?.text) {
47
+ const enrichData = JSON.parse(enrichResult.content[0].text);
48
+ if (enrichData.status !== 'pending') {
49
+ // Enrichment is ready — merge it
50
+ return mergePackets(result, enrichResult);
51
+ }
52
+ }
53
+ }
54
+ catch {
55
+ // Enrichment call failed — continue with retries
56
+ }
57
+ // Wait before retrying
58
+ if (attempt < MAX_RETRIES - 1) {
59
+ await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));
60
+ }
61
+ }
62
+ // Enrichment not ready after retries — return original Packet 1 as-is
63
+ // The agent can still work with Packet 1 alone
64
+ process.stderr.write(`[gramatr-mcp] Packet 2 not ready after ${MAX_RETRIES} retries, returning Packet 1 only\n`);
65
+ return result;
66
+ }
67
+ /**
68
+ * Merge Packet 2 enrichment into the Packet 1 response.
69
+ * Adds enrichment data under a `packet_2` key in the response.
70
+ */
71
+ function mergePackets(packet1, packet2) {
72
+ try {
73
+ const p1Data = JSON.parse(packet1.content[0].text);
74
+ const p2Data = JSON.parse(packet2.content[0].text);
75
+ // Merge Packet 2 into Packet 1
76
+ p1Data.packet_2 = p2Data;
77
+ p1Data.packet_2_status = 'merged';
78
+ return {
79
+ content: [{ type: 'text', text: JSON.stringify(p1Data) }],
80
+ };
81
+ }
82
+ catch {
83
+ // If merge fails, return Packet 1 unchanged
84
+ return packet1;
85
+ }
86
+ }
87
+ //# sourceMappingURL=packet2-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packet2-fetcher.js","sourceRoot":"","sources":["../../src/intelligence/packet2-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Session Manager — automatic session lifecycle for the local MCP server.
3
+ *
4
+ * - Auto session_start on first proxied tool call
5
+ * - Auto session_end on process exit (SIGTERM, SIGINT)
6
+ * - Tracks session ID for correlation
7
+ * - Tracks tool call count for session metrics
8
+ */
9
+ /**
10
+ * Ensure a session is started. Called before the first proxied tool call.
11
+ * Idempotent — only starts once per process lifetime.
12
+ */
13
+ export declare function ensureSession(): Promise<void>;
14
+ /**
15
+ * Get the current session ID (for correlation).
16
+ */
17
+ export declare function getSessionId(): string | null;
18
+ /**
19
+ * Get the tool call count for the current session.
20
+ */
21
+ export declare function getToolCallCount(): number;
22
+ //# sourceMappingURL=session-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/intelligence/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA6CnD;AAuBD;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAE5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}