@abderraouf-yt/got-mcp 3.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 toumi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,361 @@
1
+ <p align="center">
2
+ <img src="docs/assets/hero-complex-graph.png" alt="GoT MCP β€” 13-node reasoning DAG visualized in cyber-industrial UI" width="100%" />
3
+ </p>
4
+
5
+ <h1 align="center">🧠 GOT MCP</h1>
6
+
7
+ <p align="center">
8
+ <strong>Graph of Thoughts MCP Server β€” Bounded, Auditable Reasoning for AI Agents</strong>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@abderraouf-yt/got-mcp"><img src="https://img.shields.io/npm/v/@abderraouf-yt/got-mcp?style=flat-square&color=00e5ff&label=npm" alt="npm version" /></a>
13
+ <a href="https://github.com/Abderraouf-yt/got-mcp"><img src="https://img.shields.io/github/stars/Abderraouf-yt/got-mcp?style=flat-square&color=ff00ff&label=stars" alt="GitHub stars" /></a>
14
+ <a href="#"><img src="https://img.shields.io/badge/node-%3E%3D20-00e5ff?style=flat-square" alt="Node.js" /></a>
15
+ <a href="#"><img src="https://img.shields.io/badge/MCP-1.26+-ff00ff?style=flat-square" alt="MCP SDK" /></a>
16
+ <a href="#"><img src="https://img.shields.io/badge/tools-10-00ff88?style=flat-square" alt="Tools" /></a>
17
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-yellow?style=flat-square" alt="License" /></a>
18
+ <a href="https://got-mcp-visualizer.netlify.app"><img src="https://img.shields.io/badge/demo-live-00e5ff?style=flat-square&logo=netlify" alt="Live Demo" /></a>
19
+ <a href="https://arxiv.org/abs/2308.09687"><img src="https://img.shields.io/badge/GoT-Besta%20et%20al.%202023-ff6b6b?style=flat-square" alt="GoT Paper" /></a>
20
+ </p>
21
+
22
+ <p align="center">
23
+ <a href="#-quick-start">⚑ Quick Start</a> β€’
24
+ <a href="https://got-mcp-visualizer.netlify.app">οΏ½ Live Demo</a> β€’
25
+ <a href="#-tools-10">πŸ›  Tools</a> β€’
26
+ <a href="#-how-it-thinks">🧬 How It Thinks</a> β€’
27
+ <a href="#-governance">πŸ”’ Governance</a> β€’
28
+ <a href="#-visualizer">πŸ“Š Visualizer</a>
29
+ </p>
30
+
31
+ ---
32
+
33
+ ## What is this?
34
+
35
+ > **Chain of Thought** reasons in a line. **Tree of Thought** can branch. **Graph of Thoughts** can branch, merge, contradict, prune dead ends, and converge on the winning path.
36
+
37
+ Thought Graph is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that gives AI agents **non-linear reasoning** β€” a directed acyclic graph where thoughts can branch into alternatives, get contradicted by evidence, and converge through weighted aggregation.
38
+
39
+ ```
40
+ Traditional AI: A β†’ B β†’ C β†’ D (linear, no backtracking)
41
+ Tree of Thought: A β†’ B₁, Bβ‚‚ (branching, no merging)
42
+ Graph of Thoughts: A β†’ B₁ ←contradictionβ†’ C₁, Bβ‚‚ β†’aggregateβ†’ D ← THIS
43
+ ```
44
+
45
+ <table>
46
+ <tr>
47
+ <td width="33%" align="center"><strong>πŸ”— Chain of Thought</strong><br/>Linear β€’ No backtrack</td>
48
+ <td width="33%" align="center"><strong>🌲 Tree of Thoughts</strong><br/>Branching β€’ No merge</td>
49
+ <td width="33%" align="center"><strong>🧠 Graph of Thoughts</strong><br/>Branch β€’ Merge β€’ Prune β€’ Converge</td>
50
+ </tr>
51
+ </table>
52
+
53
+ ---
54
+
55
+ ## ⚑ Quick Start
56
+
57
+ ### Option 1: Install from npm
58
+
59
+ ```bash
60
+ npm install -g @abderraouf-yt/got-mcp
61
+ ```
62
+
63
+ ### Option 2: Clone & Build
64
+
65
+ ```bash
66
+ git clone https://github.com/Abderraouf-yt/got-mcp.git
67
+ cd got-mcp
68
+ npm install && npm run build
69
+ ```
70
+
71
+ ### Configure your IDE
72
+
73
+ Add to your MCP config (`~/.gemini/settings.json`, VS Code `mcp.json`, etc.):
74
+
75
+ ```json
76
+ {
77
+ "got-mcp": {
78
+ "command": "npx",
79
+ "args": ["-y", "@abderraouf-yt/got-mcp"],
80
+ "env": { "THOUGHT_GRAPH_HTTP_PORT": "3001" }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 🎬 Live Demo
88
+
89
+ **Problem:** *"Should we use CRDTs or Operational Transformation for a collaborative editor?"*
90
+
91
+ The agent explored 3 branches, evaluated 13 nodes, rejected dead ends, and converged on a hybrid solution β€” all visible in the graph:
92
+
93
+ ```mermaid
94
+ graph TD
95
+ classDef validated fill:#00ff88,stroke:#00ff88,color:#000
96
+ classDef rejected fill:#ff4444,stroke:#ff4444,color:#fff
97
+ classDef active fill:#00e5ff,stroke:#00e5ff,color:#000
98
+ classDef winner fill:#ffd700,stroke:#ffd700,color:#000
99
+
100
+ N1["🎯 CRDTs vs OT?<br/>80%"]:::validated
101
+
102
+ N2["πŸ“– CRDT Research<br/>85%"]:::validated
103
+ N3["πŸ“– OT Research<br/>70%"]:::active
104
+
105
+ N4["🌿 Branch A: Yjs<br/>90%"]:::validated
106
+ N5["❌ Branch B: ShareDB<br/>40%"]:::rejected
107
+ N11["🌿 Branch C: Hybrid<br/>95%"]:::validated
108
+
109
+ N6["βœ… TypeScript + ProseMirror<br/>sub-100ms sync Β· 95%"]:::validated
110
+ N7["⚠️ Memory overhead<br/>10x state size · 65%"]:::active
111
+
112
+ N8["❌ MongoDB persistence<br/>50%"]:::rejected
113
+ N9["πŸ’€ Cannot work offline<br/>90%"]:::validated
114
+
115
+ N10["πŸ”§ Y.Doc compaction<br/>90% size reduction Β· 92%"]:::validated
116
+ N12["βœ… Liveblocks + Tiptap<br/>+ Hocuspocus Β· 88%"]:::validated
117
+ N13["πŸ† WINNER: Yjs +<br/>y-websocket + Hocuspocus<br/>100%"]:::winner
118
+
119
+ N1 -->|refinement| N2
120
+ N1 -->|refinement| N3
121
+ N1 -->|branch| N11
122
+
123
+ N2 -->|branch| N4
124
+ N3 -->|branch| N5
125
+
126
+ N4 -->|support| N6
127
+ N4 -->|contradiction| N7
128
+
129
+ N5 -->|support| N8
130
+ N5 -->|contradiction| N9
131
+
132
+ N7 -->|refinement| N10
133
+
134
+ N11 -->|support| N12
135
+ N11 -->|refinement| N13
136
+ ```
137
+
138
+ > **Result:** OT branch rejected (offline failure). CRDT memory concern contradicted then resolved via compaction. Hybrid path wins at 100%.
139
+
140
+ <details>
141
+ <summary>πŸ” <strong>Load this demo yourself</strong></summary>
142
+
143
+ ```bash
144
+ cp docs/assets/demo-state.json thought-graph-state.json
145
+ npm run start
146
+ # Open visualizer β†’ http://localhost:5173
147
+ ```
148
+
149
+ The demo state ships with the repo in `docs/assets/demo-state.json`.
150
+
151
+ </details>
152
+
153
+ ---
154
+
155
+ ## πŸ›  Tools (10)
156
+
157
+ <table>
158
+ <tr><th>Tool</th><th>What it does</th><th>Category</th></tr>
159
+ <tr><td><code>propose_thought</code></td><td>Add a reasoning node with optional parent + relation</td><td>🧠 Core</td></tr>
160
+ <tr><td><code>evaluate_thought</code></td><td>Score (0.0–1.0) + critique. Omit score β†’ autonomous LLM audit</td><td>🧠 Core</td></tr>
161
+ <tr><td><code>get_thought_graph</code></td><td>Retrieve the full DAG state</td><td>🧠 Core</td></tr>
162
+ <tr><td><code>reset_graph</code></td><td>Clear graph for new session</td><td>🧠 Core</td></tr>
163
+ <tr><td><code>aggregate_thoughts</code></td><td>Merge 2+ nodes β†’ weighted synthesis <code>Ξ£(scoreΓ—weight)/Ξ£(weights)</code></td><td>⚑ GoT</td></tr>
164
+ <tr><td><code>prune_branch</code></td><td>Hard (reject+zero) or Soft (score decay) pruning</td><td>⚑ GoT</td></tr>
165
+ <tr><td><code>find_winning_path</code></td><td>Greedy DFS or beam search (k-best paths) with threshold gating</td><td>⚑ GoT</td></tr>
166
+ <tr><td><code>get_graph_metrics</code></td><td>Node count, max depth, prune ratio, avg score, status breakdown</td><td>πŸ“Š Ops</td></tr>
167
+ <tr><td><code>export_snapshot</code></td><td>Full graph serialization for replay/recovery</td><td>πŸ” Replay</td></tr>
168
+ <tr><td><code>restore_snapshot</code></td><td>Restore from previously exported snapshot</td><td>πŸ” Replay</td></tr>
169
+ </table>
170
+
171
+ ### Edge Relations
172
+
173
+ `refinement` Β· `contradiction` Β· `support` Β· `branch` Β· `aggregation`
174
+
175
+ ### Node Statuses
176
+
177
+ `active` Β· `validated` Β· `rejected` Β· `branching`
178
+
179
+ ---
180
+
181
+ ## 🧬 How It Thinks
182
+
183
+ ```
184
+ Agent: I need to decide between PostgreSQL and MongoDB.
185
+
186
+ β†’ propose_thought("PostgreSQL vs MongoDB for user data store?")
187
+ β†’ propose_thought("PostgreSQL: ACID, strong schema", parent: "node_1", relation: "branch")
188
+ β†’ propose_thought("MongoDB: flexible schema, horizontal scaling", parent: "node_1", relation: "branch")
189
+ → propose_thought("Our data has relational patterns: user→orders→items", parent: "node_2", relation: "support")
190
+ β†’ propose_thought("MongoDB can't enforce referential integrity", parent: "node_3", relation: "contradiction")
191
+ β†’ evaluate_thought("node_3", score: 0.3, status: "rejected")
192
+ β†’ prune_branch("node_3", reason: "Relational data needs relational DB")
193
+ β†’ find_winning_path(beamWidth: 2, scoreThreshold: 0.5)
194
+ ↳ Winner: node_1 β†’ node_2 β†’ node_4 (PostgreSQL path, score: 2.75)
195
+ ```
196
+
197
+ ---
198
+
199
+ ## πŸ”’ Governance
200
+
201
+ Engine-level guards β€” enforced in the graph engine, not the tool layer:
202
+
203
+ | Guard | Default | Enforcement |
204
+ |-------|---------|-------------|
205
+ | **Node cap** | 200 | `addNode()` throws at limit |
206
+ | **Depth cap** | 15 | `addEdge()` validates depth |
207
+ | **Branch cap** | 5 children/node | `addEdge()` limits branching |
208
+ | **Cycle detection** | Always on | BFS reachability in `addEdge()` |
209
+ | **Thought length** | 5,000 chars | `addNode()` + Zod schema |
210
+ | **Aggregation limit** | 10 inputs | `aggregateNodes()` |
211
+ | **Prune cascade** | 50 nodes | `pruneFromNode()` |
212
+ | **Confidence clamp** | [0, 1] | `aggregateNodes()` |
213
+
214
+ <details>
215
+ <summary>βš™οΈ <strong>Custom Limits</strong></summary>
216
+
217
+ Override defaults via constructor:
218
+
219
+ ```typescript
220
+ const graph = new ThoughtGraph(persistPath, {
221
+ maxNodes: 500,
222
+ maxDepth: 25,
223
+ maxBranchFactor: 8,
224
+ maxThoughtLength: 10000,
225
+ maxAggregationInputs: 20,
226
+ maxPruneCascade: 100,
227
+ });
228
+ ```
229
+
230
+ </details>
231
+
232
+ ### Session Isolation
233
+
234
+ Each session gets its own isolated graph with separate persistence:
235
+
236
+ ```typescript
237
+ const alice = getGraphInstance("user-alice"); // β†’ thought-graph-state-user-alice.json
238
+ const bob = getGraphInstance("user-bob"); // β†’ thought-graph-state-user-bob.json
239
+ // Alice and Bob never share state
240
+ ```
241
+
242
+ ### Concurrency Safety
243
+
244
+ All mutations run under an async mutex:
245
+
246
+ ```typescript
247
+ await graph.withLock(async () => {
248
+ graph.addNode("Safe concurrent mutation");
249
+ });
250
+ ```
251
+
252
+ ### Snapshot Replay
253
+
254
+ ```typescript
255
+ const snapshot = graph.exportSnapshot();
256
+ // { nodes, edges, nodeCounter, timestamp, version: "3.0.0", stateVersion: 42 }
257
+
258
+ graph.restoreSnapshot(snapshot); // Deterministic replay
259
+ ```
260
+
261
+ ---
262
+
263
+ ## πŸ“Š Visualizer
264
+
265
+ **[🌐 Live Demo β†’](https://got-mcp-visualizer.netlify.app)**
266
+
267
+ A React 19 + Vite dashboard with a **cyber-industrial UI** β€” real-time graph rendering via React Flow + Dagre layout.
268
+
269
+ | Feature | Detail |
270
+ |---------|--------|
271
+ | **Layout** | Dagre hierarchical DAG |
272
+ | **Live sync** | SWR polling (2s interval) |
273
+ | **Node colors** | 🟒 Validated Β· πŸ”΅ Active Β· πŸ”΄ Rejected Β· 🟣 Branching |
274
+ | **Edge types** | Animated (branch) Β· Dashed (contradiction) Β· Solid (support) Β· Dotted (aggregation) |
275
+ | **Score bars** | Per-node confidence (0–100%) |
276
+ | **Minimap** | Bottom-right overview |
277
+
278
+ ```bash
279
+ cd visualizer && npm install && npm run dev
280
+ # β†’ http://localhost:5173
281
+ ```
282
+
283
+ ### Architecture
284
+
285
+ ```
286
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” Stdio β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
287
+ β”‚ AI Agent β”‚ ◄────────────► β”‚ MCP Server β”‚
288
+ β”‚ (Gemini/Cursor) β”‚ β”‚ (index.ts) β”‚
289
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
290
+ β”‚ Session Registry β”‚
291
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” HTTP:3001 β”‚ ThoughtGraph[] β”‚
292
+ β”‚ Visualizer β”‚ ◄────────────► β”‚ β”‚
293
+ β”‚ React + Vite β”‚ /api/graph β”‚ Express Bridge β”‚
294
+ β”‚ :5173 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
295
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
296
+ thought-graph-state-{session}.json
297
+ (per-session file persistence)
298
+ ```
299
+
300
+ ---
301
+
302
+ ## πŸ”¬ GoT Compliance
303
+
304
+ Based on [Besta et al., 2023 β€” "Graph of Thoughts"](https://arxiv.org/abs/2308.09687):
305
+
306
+ | Primitive | Implementation | Version |
307
+ |-----------|---------------|---------|
308
+ | **Generate** | `propose_thought` | v1.0 |
309
+ | **Evaluate** | `evaluate_thought` | v1.0 |
310
+ | **Backtrack** | `evaluate_thought(status: rejected)` | v1.0 |
311
+ | **Aggregate** | `aggregate_thoughts` β€” weighted synthesis | v3.0 |
312
+ | **Prune** | `prune_branch` β€” hard + soft modes | v3.0 |
313
+ | **Converge** | `find_winning_path` β€” beam search | v3.0 |
314
+ | **Governance** | Engine-level guards + session isolation | v3.0 |
315
+ | **Replay** | `export_snapshot` / `restore_snapshot` | v3.0 |
316
+ | Volume Control | Roadmap | β€” |
317
+ | Controller Loop | Roadmap | β€” |
318
+
319
+ ---
320
+
321
+ ## πŸ— Tech Stack
322
+
323
+ | Layer | Technology |
324
+ |-------|-----------|
325
+ | Runtime | TypeScript Β· Node.js v20+ |
326
+ | Protocol | `@modelcontextprotocol/sdk` ^1.26 |
327
+ | Validation | Zod schemas with `.max()` length guards |
328
+ | Governance | Engine-level: node/depth/branch caps, cycle detection |
329
+ | HTTP Bridge | Express |
330
+ | Visualizer | React 19 Β· Vite Β· `@xyflow/react` Β· Dagre Β· SWR |
331
+ | Persistence | Session-scoped JSON with `fs.watchFile` sync |
332
+ | Concurrency | Async mutex (`withLock`) per session |
333
+
334
+ ## πŸ“ Structure
335
+
336
+ ```
337
+ thought-graph/
338
+ β”œβ”€β”€ src/
339
+ β”‚ β”œβ”€β”€ index.ts # Bootstrap (Stdio + HTTP)
340
+ β”‚ β”œβ”€β”€ server/
341
+ β”‚ β”‚ β”œβ”€β”€ mcp.ts # 10 MCP tool registrations
342
+ β”‚ β”‚ └── http.ts # Express bridge + SSE
343
+ β”‚ β”œβ”€β”€ graph/
344
+ β”‚ β”‚ β”œβ”€β”€ ThoughtGraph.ts # Core DAG engine + governance
345
+ β”‚ β”‚ └── index.ts # Session registry exports
346
+ β”‚ └── types.ts # GraphLimits, SessionContext, GraphMetrics
347
+ β”œβ”€β”€ visualizer/ # React + Vite dashboard
348
+ β”œβ”€β”€ tests/ # Unit tests
349
+ β”œβ”€β”€ docs/assets/ # Demo screenshots & state
350
+ └── dist/ # Compiled output
351
+ ```
352
+
353
+ ## πŸ“œ License
354
+
355
+ MIT
356
+
357
+ ---
358
+
359
+ <p align="center">
360
+ <sub>Evolution of sequential thinking β€” because the best ideas don't come in a straight line.</sub>
361
+ </p>
package/dist/bridge.js ADDED
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Thought Graph SSE Bridge
3
+ * HTTP bridge for browser-based dashboard connectivity.
4
+ * Exposes the thought-graph MCP server over Server-Sent Events.
5
+ *
6
+ * @module bridge
7
+ * @description SSE/HTTP transport layer for web-based visualization
8
+ * @version 1.3.0
9
+ */
10
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
11
+ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
12
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
13
+ import express from "express";
14
+ import cors from "cors";
15
+ import { SERVER_CONFIG } from "./types.js";
16
+ import { ThoughtGraph } from "./graph/index.js";
17
+ import { TOOLS, handleToolCall } from "./tools/index.js";
18
+ import { RESOURCES, readResource } from "./resources/index.js";
19
+ /**
20
+ * Bridge Configuration
21
+ */
22
+ const BRIDGE_CONFIG = {
23
+ port: 3001,
24
+ name: "thought-graph-bridge",
25
+ version: SERVER_CONFIG.version,
26
+ };
27
+ /**
28
+ * Shared graph instance for all SSE connections.
29
+ * Unlike the main server (which uses singleton), the bridge maintains
30
+ * its own graph that persists across all web clients.
31
+ */
32
+ const sharedGraph = new ThoughtGraph();
33
+ /**
34
+ * Active SSE transport sessions.
35
+ */
36
+ const activeSessions = new Map();
37
+ /**
38
+ * Create and configure an MCP server instance for SSE transport.
39
+ * Each SSE connection gets its own server but shares the graph.
40
+ */
41
+ function createMCPServer() {
42
+ const server = new Server({
43
+ name: BRIDGE_CONFIG.name,
44
+ version: BRIDGE_CONFIG.version,
45
+ }, {
46
+ capabilities: {
47
+ tools: {},
48
+ resources: {},
49
+ },
50
+ });
51
+ // Register Resource Handlers
52
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
53
+ resources: RESOURCES,
54
+ }));
55
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
56
+ return readResource(request.params.uri, sharedGraph);
57
+ });
58
+ // Register Tool Handlers
59
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
60
+ tools: TOOLS,
61
+ }));
62
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
63
+ const { name, arguments: args } = request.params;
64
+ return handleToolCall(name, args, sharedGraph, server);
65
+ });
66
+ return server;
67
+ }
68
+ /**
69
+ * Express HTTP Server Setup
70
+ */
71
+ const app = express();
72
+ app.use(cors());
73
+ app.use(express.json());
74
+ /**
75
+ * SSE endpoint for MCP communication.
76
+ * Each connection creates a new MCP server instance.
77
+ */
78
+ app.get("/sse", async (req, res) => {
79
+ const sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(7)}`;
80
+ console.log(`πŸ“‘ New SSE connection: ${sessionId}`);
81
+ const transport = new SSEServerTransport("/messages", res);
82
+ const server = createMCPServer();
83
+ activeSessions.set(sessionId, transport);
84
+ res.on("close", () => {
85
+ console.log(`πŸ“΄ SSE connection closed: ${sessionId}`);
86
+ activeSessions.delete(sessionId);
87
+ });
88
+ await server.connect(transport);
89
+ });
90
+ /**
91
+ * Message endpoint for client -> server communication.
92
+ * SSEServerTransport handles message routing internally.
93
+ */
94
+ app.post("/messages", async (req, res) => {
95
+ res.status(200).json({ status: "received" });
96
+ });
97
+ /**
98
+ * REST API endpoint for direct graph access.
99
+ * Alternative to MCP for simple read operations.
100
+ */
101
+ app.get("/api/graph", (req, res) => {
102
+ res.json(sharedGraph.getGraph());
103
+ });
104
+ /**
105
+ * Health check endpoint.
106
+ */
107
+ app.get("/health", (req, res) => {
108
+ res.json({
109
+ status: "ok",
110
+ name: BRIDGE_CONFIG.name,
111
+ version: BRIDGE_CONFIG.version,
112
+ connections: activeSessions.size,
113
+ graph: {
114
+ nodes: sharedGraph.size,
115
+ edges: sharedGraph.edgeCount,
116
+ },
117
+ });
118
+ });
119
+ /**
120
+ * Start the HTTP server.
121
+ */
122
+ app.listen(BRIDGE_CONFIG.port, () => {
123
+ console.log(`πŸš€ ${BRIDGE_CONFIG.name} v${BRIDGE_CONFIG.version}`);
124
+ console.log(` Port: http://localhost:${BRIDGE_CONFIG.port}`);
125
+ console.log(` SSE: http://localhost:${BRIDGE_CONFIG.port}/sse`);
126
+ console.log(` REST API: http://localhost:${BRIDGE_CONFIG.port}/api/graph`);
127
+ console.log(` Health: http://localhost:${BRIDGE_CONFIG.port}/health`);
128
+ });