@abderraouf-yt/got-mcp 3.2.1 → 4.0.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/README.md +20 -11
- package/dist/graph/ThoughtGraph.js +188 -0
- package/dist/server/http.js +7 -10
- package/dist/server/mcp.js +39 -0
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -13,16 +13,14 @@
|
|
|
13
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
14
|
<a href="#"><img src="https://img.shields.io/badge/node-%3E%3D20-00e5ff?style=flat-square" alt="Node.js" /></a>
|
|
15
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-
|
|
16
|
+
<a href="#"><img src="https://img.shields.io/badge/tools-15-00ff88?style=flat-square" alt="Tools" /></a>
|
|
17
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
18
|
<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
19
|
</p>
|
|
21
20
|
|
|
22
21
|
<p align="center">
|
|
23
22
|
<a href="#-quick-start">⚡ Quick Start</a> •
|
|
24
|
-
<a href="
|
|
25
|
-
<a href="#-tools-10">🛠 Tools</a> •
|
|
23
|
+
<a href="#-tools-15">🛠 Tools</a> •
|
|
26
24
|
<a href="#-how-it-thinks">🧬 How It Thinks</a> •
|
|
27
25
|
<a href="#-governance">🔒 Governance</a> •
|
|
28
26
|
<a href="#-visualizer">📊 Visualizer</a>
|
|
@@ -152,7 +150,7 @@ The demo state ships with the repo in `docs/assets/demo-state.json`.
|
|
|
152
150
|
|
|
153
151
|
---
|
|
154
152
|
|
|
155
|
-
## 🛠 Tools (
|
|
153
|
+
## 🛠 Tools (15)
|
|
156
154
|
|
|
157
155
|
<table>
|
|
158
156
|
<tr><th>Tool</th><th>What it does</th><th>Category</th></tr>
|
|
@@ -166,11 +164,16 @@ The demo state ships with the repo in `docs/assets/demo-state.json`.
|
|
|
166
164
|
<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
165
|
<tr><td><code>export_snapshot</code></td><td>Full graph serialization for replay/recovery</td><td>🔁 Replay</td></tr>
|
|
168
166
|
<tr><td><code>restore_snapshot</code></td><td>Restore from previously exported snapshot</td><td>🔁 Replay</td></tr>
|
|
167
|
+
<tr><td><code>reflect_and_refine</code></td><td>Self-reflection: 4-axis confidence + auto-critique + branch</td><td>🔬 v4.0</td></tr>
|
|
168
|
+
<tr><td><code>context_set</code></td><td>Write key-value to shared context store with provenance</td><td>📦 v4.0</td></tr>
|
|
169
|
+
<tr><td><code>context_get</code></td><td>Read value + source from shared context store</td><td>📦 v4.0</td></tr>
|
|
170
|
+
<tr><td><code>context_list</code></td><td>List all context store entries and their sources</td><td>📦 v4.0</td></tr>
|
|
171
|
+
<tr><td><code>export_reasoning_trace</code></td><td>Export winning path as Long CoT trace (DeepSeek-R1/o3 format)</td><td>📤 v4.0</td></tr>
|
|
169
172
|
</table>
|
|
170
173
|
|
|
171
174
|
### Edge Relations
|
|
172
175
|
|
|
173
|
-
`refinement` · `contradiction` · `support` · `branch` · `aggregation`
|
|
176
|
+
`refinement` · `contradiction` · `support` · `branch` · `aggregation` · `reflection`
|
|
174
177
|
|
|
175
178
|
### Node Statuses
|
|
176
179
|
|
|
@@ -313,7 +316,9 @@ Based on [Besta et al., 2023 — "Graph of Thoughts"](https://arxiv.org/abs/2308
|
|
|
313
316
|
| **Converge** | `find_winning_path` — beam search | v3.0 |
|
|
314
317
|
| **Governance** | Engine-level guards + session isolation | v3.0 |
|
|
315
318
|
| **Replay** | `export_snapshot` / `restore_snapshot` | v3.0 |
|
|
316
|
-
|
|
|
319
|
+
| **Self-Reflect** | `reflect_and_refine` — 4-axis confidence | v4.0 |
|
|
320
|
+
| **Context Store** | `context_set` / `context_get` / `context_list` | v4.0 |
|
|
321
|
+
| **Reasoning Trace** | `export_reasoning_trace` — Long CoT export | v4.0 |
|
|
317
322
|
| Controller Loop | Roadmap | — |
|
|
318
323
|
|
|
319
324
|
---
|
|
@@ -338,13 +343,17 @@ thought-graph/
|
|
|
338
343
|
├── src/
|
|
339
344
|
│ ├── index.ts # Bootstrap (Stdio + HTTP)
|
|
340
345
|
│ ├── server/
|
|
341
|
-
│ │ ├── mcp.ts #
|
|
342
|
-
│ │ └── http.ts # Express bridge
|
|
346
|
+
│ │ ├── mcp.ts # 15 MCP tool registrations
|
|
347
|
+
│ │ └── http.ts # Express bridge (minimal inline CORS)
|
|
343
348
|
│ ├── graph/
|
|
344
349
|
│ │ ├── ThoughtGraph.ts # Core DAG engine + governance
|
|
345
350
|
│ │ └── index.ts # Session registry exports
|
|
346
|
-
│
|
|
347
|
-
├──
|
|
351
|
+
│ ├── context/
|
|
352
|
+
│ │ ├── ContextStore.ts # Shared context store (CA-MCP)
|
|
353
|
+
│ │ └── index.ts # Context singleton export
|
|
354
|
+
│ └── types.ts # GraphLimits, ConfidenceVector, ReasoningTrace
|
|
355
|
+
├── visualizer/ # React + Vite dashboard (local only)
|
|
356
|
+
├── evaluations/ # XML evaluation framework
|
|
348
357
|
├── tests/ # Unit tests
|
|
349
358
|
├── docs/assets/ # Demo screenshots & state
|
|
350
359
|
└── dist/ # Compiled output
|
|
@@ -796,6 +796,194 @@ export class ThoughtGraph {
|
|
|
796
796
|
exportedAt: new Date().toISOString(),
|
|
797
797
|
};
|
|
798
798
|
}
|
|
799
|
+
// ==========================================
|
|
800
|
+
// v4.0: CONTROLLER LOOP — Autonomous GoT Cycle
|
|
801
|
+
// ==========================================
|
|
802
|
+
/**
|
|
803
|
+
* Controller Loop: Autonomous Graph of Thoughts reasoning cycle.
|
|
804
|
+
*
|
|
805
|
+
* Orchestrates the full GoT pipeline on a given prompt:
|
|
806
|
+
* 1. GENERATE — propose initial thoughts from the prompt
|
|
807
|
+
* 2. EVALUATE — score each active leaf using confidence vectors
|
|
808
|
+
* 3. BRANCH — create alternatives for mid-scoring thoughts
|
|
809
|
+
* 4. REFLECT — auto-critique top candidates via reflectAndRefine
|
|
810
|
+
* 5. PRUNE — remove branches below autoPruneBelow threshold
|
|
811
|
+
* 6. CONVERGE — find the winning path via beam search
|
|
812
|
+
*
|
|
813
|
+
* Governance:
|
|
814
|
+
* - maxIterations caps the number of generate→evaluate→prune cycles
|
|
815
|
+
* - convergenceThreshold stops early when the best path score exceeds it
|
|
816
|
+
* - autoPruneBelow automatically soft-prunes low-scoring branches
|
|
817
|
+
* - All existing graph limits (node cap, depth cap, etc.) still apply
|
|
818
|
+
*
|
|
819
|
+
* @param prompt - The reasoning question or problem statement
|
|
820
|
+
* @param thoughts - Array of initial thought branches to explore
|
|
821
|
+
* @param options - Controller loop configuration
|
|
822
|
+
* @returns The final winning path, reasoning trace, and iteration metrics
|
|
823
|
+
*/
|
|
824
|
+
runControllerLoop(prompt, thoughts, options) {
|
|
825
|
+
const maxIterations = options?.maxIterations ?? 5;
|
|
826
|
+
const convergenceThreshold = options?.convergenceThreshold ?? 0.85;
|
|
827
|
+
const autoPruneBelow = options?.autoPruneBelow ?? 0.3;
|
|
828
|
+
const beamWidth = options?.beamWidth ?? 2;
|
|
829
|
+
const iterationLog = [];
|
|
830
|
+
// Step 1: GENERATE — seed the graph with the prompt + initial thoughts
|
|
831
|
+
const rootId = this.addNode(prompt);
|
|
832
|
+
this.updateNode(rootId, { score: 0.5, status: "active" });
|
|
833
|
+
for (const thought of thoughts) {
|
|
834
|
+
const childId = this.addNode(thought);
|
|
835
|
+
this.addEdge(rootId, childId, "branch");
|
|
836
|
+
this.updateNode(childId, { score: 0.5, status: "active" });
|
|
837
|
+
}
|
|
838
|
+
let converged = false;
|
|
839
|
+
let iteration = 0;
|
|
840
|
+
// Step 2-6: Iterate until convergence or budget exhausted
|
|
841
|
+
while (iteration < maxIterations && !converged) {
|
|
842
|
+
iteration++;
|
|
843
|
+
// --- EVALUATE: score all active leaf nodes ---
|
|
844
|
+
const activeLeaves = this.getActiveLeaves();
|
|
845
|
+
let scored = 0;
|
|
846
|
+
let pruned = 0;
|
|
847
|
+
let branched = 0;
|
|
848
|
+
let reflected = 0;
|
|
849
|
+
for (const leaf of activeLeaves) {
|
|
850
|
+
// Auto-score based on thought quality heuristics:
|
|
851
|
+
// - Length factor: longer = more detailed (diminishing returns)
|
|
852
|
+
// - Depth factor: deeper = more refined thinking
|
|
853
|
+
// - Specificity: presence of numbers, comparisons, evidence markers
|
|
854
|
+
const depth = this.getNodeDepth(leaf.id);
|
|
855
|
+
const lengthScore = Math.min(leaf.thought.length / 500, 1.0);
|
|
856
|
+
const depthBonus = Math.min(depth * 0.05, 0.2);
|
|
857
|
+
const specificity = this.estimateSpecificity(leaf.thought);
|
|
858
|
+
const autoScore = Math.min(Math.round((lengthScore * 0.3 + depthBonus + specificity * 0.5) * 100) / 100, 1.0);
|
|
859
|
+
this.updateNode(leaf.id, {
|
|
860
|
+
score: autoScore,
|
|
861
|
+
status: autoScore >= convergenceThreshold ? "validated" : "active",
|
|
862
|
+
});
|
|
863
|
+
scored++;
|
|
864
|
+
}
|
|
865
|
+
// --- PRUNE: remove low-scoring branches ---
|
|
866
|
+
const lowScorers = Array.from(this.nodes.values())
|
|
867
|
+
.filter(n => n.status === "active" && n.score < autoPruneBelow && n.score > 0);
|
|
868
|
+
for (const weak of lowScorers) {
|
|
869
|
+
try {
|
|
870
|
+
const result = this.pruneFromNode(weak.id, `Auto-pruned: score ${weak.score} < ${autoPruneBelow}`, {
|
|
871
|
+
mode: "soft",
|
|
872
|
+
decayFactor: 0.3,
|
|
873
|
+
trigger: "auto",
|
|
874
|
+
});
|
|
875
|
+
pruned += result.pruned.length;
|
|
876
|
+
}
|
|
877
|
+
catch {
|
|
878
|
+
// Skip if prune fails (e.g. cascade limit)
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
// --- BRANCH: create alternatives for mid-tier thoughts ---
|
|
882
|
+
const midTier = Array.from(this.nodes.values())
|
|
883
|
+
.filter(n => n.status === "active" && n.score >= autoPruneBelow && n.score < convergenceThreshold);
|
|
884
|
+
for (const mid of midTier.slice(0, 3)) { // Limit branching to top 3
|
|
885
|
+
const existingChildren = this.edges.filter(e => e.from === mid.id).length;
|
|
886
|
+
if (existingChildren < this.limits.maxBranchFactor && this.nodes.size < this.limits.maxNodes - 5) {
|
|
887
|
+
try {
|
|
888
|
+
const altId = this.addNode(`[Alternative] What if we reconsider: ${mid.thought.substring(0, 200)}...`);
|
|
889
|
+
this.addEdge(mid.id, altId, "branch");
|
|
890
|
+
this.updateNode(altId, { score: 0.5, status: "active" });
|
|
891
|
+
branched++;
|
|
892
|
+
}
|
|
893
|
+
catch {
|
|
894
|
+
// Skip if limits hit
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
// --- REFLECT: critique the best candidates ---
|
|
899
|
+
const topCandidates = Array.from(this.nodes.values())
|
|
900
|
+
.filter(n => n.status !== "rejected" && n.score >= 0.5)
|
|
901
|
+
.sort((a, b) => b.score - a.score)
|
|
902
|
+
.slice(0, 2);
|
|
903
|
+
for (const top of topCandidates) {
|
|
904
|
+
try {
|
|
905
|
+
const confidence = {
|
|
906
|
+
factual: Math.min(top.score + 0.1, 1),
|
|
907
|
+
logical: Math.min(top.score + 0.05, 1),
|
|
908
|
+
relevance: Math.min(top.score + 0.15, 1),
|
|
909
|
+
novelty: Math.max(top.score - 0.1, 0),
|
|
910
|
+
};
|
|
911
|
+
this.reflectAndRefine(top.id, `Iteration ${iteration} auto-reflection: evaluating strength of reasoning.`, confidence);
|
|
912
|
+
reflected++;
|
|
913
|
+
}
|
|
914
|
+
catch {
|
|
915
|
+
// Skip if reflection fails
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
// --- CONVERGE CHECK ---
|
|
919
|
+
const winningPath = this.findWinningPath({ beamWidth, scoreThreshold: autoPruneBelow });
|
|
920
|
+
const avgPathScore = winningPath.path.length > 0
|
|
921
|
+
? winningPath.totalScore / winningPath.path.length
|
|
922
|
+
: 0;
|
|
923
|
+
iterationLog.push({
|
|
924
|
+
iteration,
|
|
925
|
+
nodesScored: scored,
|
|
926
|
+
nodesPruned: pruned,
|
|
927
|
+
nodesBranched: branched,
|
|
928
|
+
nodesReflected: reflected,
|
|
929
|
+
totalNodes: this.nodes.size,
|
|
930
|
+
bestPathScore: Math.round(avgPathScore * 100) / 100,
|
|
931
|
+
converged: avgPathScore >= convergenceThreshold,
|
|
932
|
+
});
|
|
933
|
+
if (avgPathScore >= convergenceThreshold) {
|
|
934
|
+
converged = true;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
// Final convergence
|
|
938
|
+
const finalPath = this.findWinningPath({ beamWidth, scoreThreshold: 0 });
|
|
939
|
+
const trace = this.exportReasoningTrace();
|
|
940
|
+
const metrics = this.getMetrics();
|
|
941
|
+
this.stateVersion++;
|
|
942
|
+
this.save();
|
|
943
|
+
return {
|
|
944
|
+
converged,
|
|
945
|
+
iterations: iteration,
|
|
946
|
+
winningPath: {
|
|
947
|
+
pathIds: finalPath.pathIds,
|
|
948
|
+
totalScore: finalPath.totalScore,
|
|
949
|
+
conclusion: finalPath.path.length > 0
|
|
950
|
+
? finalPath.path[finalPath.path.length - 1].thought
|
|
951
|
+
: "No conclusion reached",
|
|
952
|
+
},
|
|
953
|
+
trace,
|
|
954
|
+
metrics,
|
|
955
|
+
iterationLog,
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Get active leaf nodes (nodes with no outgoing edges that aren't rejected).
|
|
960
|
+
*/
|
|
961
|
+
getActiveLeaves() {
|
|
962
|
+
const nodesWithOutgoing = new Set(this.edges.map(e => e.from));
|
|
963
|
+
return Array.from(this.nodes.values())
|
|
964
|
+
.filter(n => !nodesWithOutgoing.has(n.id) && n.status !== "rejected");
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Estimate the specificity of a thought based on content heuristics.
|
|
968
|
+
* Higher specificity = more concrete, evidence-based reasoning.
|
|
969
|
+
*/
|
|
970
|
+
estimateSpecificity(thought) {
|
|
971
|
+
let score = 0.3; // Base score
|
|
972
|
+
// Indicators of specific, evidence-based thinking
|
|
973
|
+
if (/\d+/.test(thought))
|
|
974
|
+
score += 0.1; // Contains numbers
|
|
975
|
+
if (/vs\.?|versus|compared|better|worse/i.test(thought))
|
|
976
|
+
score += 0.1; // Comparisons
|
|
977
|
+
if (/because|since|therefore|thus|hence/i.test(thought))
|
|
978
|
+
score += 0.1; // Causal reasoning
|
|
979
|
+
if (/however|but|although|despite/i.test(thought))
|
|
980
|
+
score += 0.1; // Nuance
|
|
981
|
+
if (/example|specifically|for instance/i.test(thought))
|
|
982
|
+
score += 0.1; // Concreteness
|
|
983
|
+
if (/\b(data|evidence|research|study|benchmark)\b/i.test(thought))
|
|
984
|
+
score += 0.1; // Evidence
|
|
985
|
+
return Math.min(score, 1.0);
|
|
986
|
+
}
|
|
799
987
|
}
|
|
800
988
|
// ==========================================
|
|
801
989
|
// SESSION REGISTRY (replaces singleton)
|
package/dist/server/http.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import express from "express";
|
|
2
|
-
import cors from "cors";
|
|
3
2
|
import net from "net";
|
|
4
3
|
import crypto from "crypto";
|
|
5
4
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
@@ -43,15 +42,13 @@ async function findAvailablePort(startPort) {
|
|
|
43
42
|
export async function startHttpServer() {
|
|
44
43
|
const port = await findAvailablePort(PREFERRED_PORT);
|
|
45
44
|
const app = express();
|
|
46
|
-
//
|
|
47
|
-
app.use(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
]
|
|
54
|
-
}));
|
|
45
|
+
// Minimal localhost-only CORS (no external dependency needed)
|
|
46
|
+
app.use((_req, res, next) => {
|
|
47
|
+
res.header("Access-Control-Allow-Origin", "http://localhost:5173");
|
|
48
|
+
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
49
|
+
res.header("Access-Control-Allow-Headers", "Content-Type");
|
|
50
|
+
next();
|
|
51
|
+
});
|
|
55
52
|
app.use(express.json());
|
|
56
53
|
const activeSessions = new Map();
|
|
57
54
|
app.get("/sse", async (req, res) => {
|
package/dist/server/mcp.js
CHANGED
|
@@ -473,5 +473,44 @@ export function createServerInstance() {
|
|
|
473
473
|
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
474
474
|
}
|
|
475
475
|
});
|
|
476
|
+
// ==========================================
|
|
477
|
+
// v4.0: Controller Loop — Autonomous GoT Orchestrator
|
|
478
|
+
// ==========================================
|
|
479
|
+
server.registerTool("run_controller_loop", {
|
|
480
|
+
description: "Autonomous GoT Controller Loop: Seeds a graph with a prompt + initial thoughts, then iteratively evaluates, branches, reflects, prunes, and converges until a winning path emerges or the iteration budget is exhausted. Returns the winning conclusion, full reasoning trace, and per-iteration metrics.",
|
|
481
|
+
inputSchema: {
|
|
482
|
+
prompt: z.string().min(1).max(5000).describe("The reasoning question or problem statement"),
|
|
483
|
+
thoughts: z.array(z.string().min(1).max(5000)).min(1).max(10).describe("Initial thought branches to explore (1-10)"),
|
|
484
|
+
maxIterations: z.number().int().min(1).max(20).default(5).describe("Maximum reasoning cycles (default: 5)"),
|
|
485
|
+
convergenceThreshold: z.number().min(0).max(1).default(0.85).describe("Stop when best path average score exceeds this (default: 0.85)"),
|
|
486
|
+
autoPruneBelow: z.number().min(0).max(1).default(0.3).describe("Auto soft-prune branches scoring below this (default: 0.3)"),
|
|
487
|
+
beamWidth: z.number().int().min(1).max(10).default(2).describe("Number of top paths to track during convergence (default: 2)"),
|
|
488
|
+
},
|
|
489
|
+
annotations: { destructiveHint: true }
|
|
490
|
+
}, async ({ prompt, thoughts, maxIterations, convergenceThreshold, autoPruneBelow, beamWidth }) => {
|
|
491
|
+
try {
|
|
492
|
+
const result = graph.runControllerLoop(prompt, thoughts, {
|
|
493
|
+
maxIterations,
|
|
494
|
+
convergenceThreshold,
|
|
495
|
+
autoPruneBelow,
|
|
496
|
+
beamWidth,
|
|
497
|
+
});
|
|
498
|
+
notifyUpdate();
|
|
499
|
+
const summary = [
|
|
500
|
+
`Controller Loop ${result.converged ? "CONVERGED" : "EXHAUSTED"} after ${result.iterations} iterations.`,
|
|
501
|
+
`Winning path: ${result.winningPath.pathIds.join(" → ")} (score: ${result.winningPath.totalScore})`,
|
|
502
|
+
`Conclusion: "${result.winningPath.conclusion.substring(0, 200)}"`,
|
|
503
|
+
`Graph: ${result.metrics.nodeCount} nodes, ${result.metrics.edgeCount} edges`,
|
|
504
|
+
`Prune ratio: ${Math.round(result.metrics.pruneRatio * 100)}%`,
|
|
505
|
+
].join("\n");
|
|
506
|
+
return {
|
|
507
|
+
content: [{ type: "text", text: summary }],
|
|
508
|
+
structuredContent: result,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
catch (err) {
|
|
512
|
+
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
513
|
+
}
|
|
514
|
+
});
|
|
476
515
|
return server;
|
|
477
516
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abderraouf-yt/got-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Graph of Thoughts (GoT) MCP Server — bounded, auditable reasoning for AI agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -48,12 +48,10 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
51
|
-
"cors": "^2.8.5",
|
|
52
51
|
"express": "^4.21.0",
|
|
53
52
|
"zod": "^4.3.6"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
|
-
"@types/cors": "^2.8.17",
|
|
57
55
|
"@types/express": "^4.17.21",
|
|
58
56
|
"@types/node": "^20.19.30",
|
|
59
57
|
"typescript": "^5.9.3"
|