mcpgraph 0.1.15 → 0.1.17

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 (64) hide show
  1. package/README.md +61 -1
  2. package/dist/api.d.ts +13 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +40 -0
  5. package/dist/api.js.map +1 -1
  6. package/dist/config/expression-validator.d.ts +12 -0
  7. package/dist/config/expression-validator.d.ts.map +1 -0
  8. package/dist/config/expression-validator.js +77 -0
  9. package/dist/config/expression-validator.js.map +1 -0
  10. package/dist/config/parser.d.ts.map +1 -1
  11. package/dist/config/parser.js +9 -0
  12. package/dist/config/parser.js.map +1 -1
  13. package/dist/config/schema.d.ts +18 -0
  14. package/dist/config/schema.d.ts.map +1 -1
  15. package/dist/config/schema.js +5 -0
  16. package/dist/config/schema.js.map +1 -1
  17. package/dist/execution/context.d.ts +27 -3
  18. package/dist/execution/context.d.ts.map +1 -1
  19. package/dist/execution/context.js +52 -9
  20. package/dist/execution/context.js.map +1 -1
  21. package/dist/execution/executor.d.ts.map +1 -1
  22. package/dist/execution/executor.js +34 -12
  23. package/dist/execution/executor.js.map +1 -1
  24. package/dist/execution/nodes/entry-executor.d.ts.map +1 -1
  25. package/dist/execution/nodes/entry-executor.js +1 -2
  26. package/dist/execution/nodes/entry-executor.js.map +1 -1
  27. package/dist/execution/nodes/exit-executor.d.ts +1 -1
  28. package/dist/execution/nodes/exit-executor.d.ts.map +1 -1
  29. package/dist/execution/nodes/exit-executor.js +9 -7
  30. package/dist/execution/nodes/exit-executor.js.map +1 -1
  31. package/dist/execution/nodes/mcp-tool-executor.d.ts +1 -1
  32. package/dist/execution/nodes/mcp-tool-executor.d.ts.map +1 -1
  33. package/dist/execution/nodes/mcp-tool-executor.js +5 -4
  34. package/dist/execution/nodes/mcp-tool-executor.js.map +1 -1
  35. package/dist/execution/nodes/switch-executor.d.ts +1 -1
  36. package/dist/execution/nodes/switch-executor.d.ts.map +1 -1
  37. package/dist/execution/nodes/switch-executor.js +13 -8
  38. package/dist/execution/nodes/switch-executor.js.map +1 -1
  39. package/dist/execution/nodes/transform-executor.d.ts +1 -1
  40. package/dist/execution/nodes/transform-executor.d.ts.map +1 -1
  41. package/dist/execution/nodes/transform-executor.js +5 -4
  42. package/dist/execution/nodes/transform-executor.js.map +1 -1
  43. package/dist/expressions/json-logic.d.ts +11 -2
  44. package/dist/expressions/json-logic.d.ts.map +1 -1
  45. package/dist/expressions/json-logic.js +98 -16
  46. package/dist/expressions/json-logic.js.map +1 -1
  47. package/dist/expressions/jsonata-extensions.d.ts +10 -0
  48. package/dist/expressions/jsonata-extensions.d.ts.map +1 -0
  49. package/dist/expressions/jsonata-extensions.js +69 -0
  50. package/dist/expressions/jsonata-extensions.js.map +1 -0
  51. package/dist/expressions/jsonata.d.ts +8 -1
  52. package/dist/expressions/jsonata.d.ts.map +1 -1
  53. package/dist/expressions/jsonata.js +72 -12
  54. package/dist/expressions/jsonata.js.map +1 -1
  55. package/dist/types/config.d.ts +5 -0
  56. package/dist/types/config.d.ts.map +1 -1
  57. package/dist/types/execution.d.ts +1 -1
  58. package/dist/types/execution.d.ts.map +1 -1
  59. package/docs/design.md +21 -2
  60. package/docs/implementation.md +15 -6
  61. package/docs/introspection-debugging.md +28 -1
  62. package/examples/api-usage.ts +54 -1
  63. package/examples/loop_example.yaml +84 -0
  64. package/package.json +1 -1
@@ -70,7 +70,7 @@ async function introspectionExample() {
70
70
  if (result.executionHistory) {
71
71
  console.log('\nExecution History:');
72
72
  for (const record of result.executionHistory) {
73
- console.log(` ${record.nodeId} (${record.nodeType}): ${record.duration}ms`);
73
+ console.log(` [${record.executionIndex}] ${record.nodeId} (${record.nodeType}): ${record.duration}ms`);
74
74
  }
75
75
  }
76
76
 
@@ -88,6 +88,57 @@ async function introspectionExample() {
88
88
  await api.close();
89
89
  }
90
90
 
91
+ // Example: Time-travel debugging with getContextForExecution
92
+ async function timeTravelDebuggingExample() {
93
+ const api = new McpGraphApi('examples/count_files.yaml');
94
+
95
+ let executionIndexToInspect: number | null = null;
96
+
97
+ const { promise, controller } = api.executeTool('count_files', {
98
+ directory: './tests/files',
99
+ }, {
100
+ hooks: {
101
+ onNodeComplete: async (nodeId, node, input, output, duration) => {
102
+ // When count_files_node completes, inspect the context that was available to list_directory_node
103
+ if (nodeId === 'count_files_node') {
104
+ // Find the execution index of list_directory_node
105
+ const state = api.getExecutionState();
106
+ if (state) {
107
+ const listDirRecord = state.executionHistory.find(r => r.nodeId === 'list_directory_node');
108
+ if (listDirRecord) {
109
+ executionIndexToInspect = listDirRecord.executionIndex;
110
+ }
111
+ }
112
+ }
113
+ },
114
+ },
115
+ });
116
+
117
+ await promise;
118
+
119
+ if (executionIndexToInspect !== null && controller) {
120
+ // Get the context that was available to list_directory_node when it executed
121
+ const context = api.getContextForExecution(executionIndexToInspect);
122
+ if (context) {
123
+ console.log('\nTime-Travel Debugging:');
124
+ console.log(`Context available to execution #${executionIndexToInspect} (list_directory_node):`);
125
+ console.log(JSON.stringify(context, null, 2));
126
+ }
127
+
128
+ // Get the execution record itself
129
+ const record = api.getExecutionByIndex(executionIndexToInspect);
130
+ if (record) {
131
+ console.log(`\nExecution Record #${executionIndexToInspect}:`);
132
+ console.log(` Node: ${record.nodeId}`);
133
+ console.log(` Type: ${record.nodeType}`);
134
+ console.log(` Duration: ${record.duration}ms`);
135
+ console.log(` Output: ${JSON.stringify(record.output).substring(0, 100)}...`);
136
+ }
137
+ }
138
+
139
+ await api.close();
140
+ }
141
+
91
142
  // Example: Validate config without creating an API instance
92
143
  function validateConfigExample() {
93
144
  const errors = McpGraphApi.validateConfig('examples/count_files.yaml');
@@ -118,6 +169,8 @@ if (import.meta.url === `file://${process.argv[1]}`) {
118
169
 
119
170
  if (exampleToRun === 'introspection') {
120
171
  introspectionExample().catch(console.error);
172
+ } else if (exampleToRun === 'debugging') {
173
+ timeTravelDebuggingExample().catch(console.error);
121
174
  } else {
122
175
  example().catch(console.error);
123
176
  }
@@ -0,0 +1,84 @@
1
+ version: "1.0"
2
+
3
+ # MCP Server Metadata
4
+ server:
5
+ name: "loopExample"
6
+ version: "1.0.0"
7
+ description: "Example with a loop using history functions"
8
+
9
+ # Tool Definitions
10
+ tools:
11
+ - name: "sum_to_n"
12
+ description: "Sums numbers from 1 to n using a loop"
13
+ inputSchema:
14
+ type: "object"
15
+ properties:
16
+ n:
17
+ type: "number"
18
+ description: "The number to sum to"
19
+ required:
20
+ - n
21
+ outputSchema:
22
+ type: "object"
23
+ properties:
24
+ sum:
25
+ type: "number"
26
+ description: "The sum from 1 to n"
27
+
28
+ # Graph Nodes
29
+ nodes:
30
+ # Entry node: Receives tool arguments
31
+ - id: "entry_sum"
32
+ type: "entry"
33
+ tool: "sum_to_n"
34
+ next: "increment_node"
35
+
36
+ # Increment counter and add to sum
37
+ # Uses $nodeExecution() to get the previous iteration of this node
38
+ # First iteration: $executionCount("increment_node") = 0, so we initialize
39
+ # Subsequent iterations: $nodeExecution("increment_node", -1) gets the last execution
40
+ - id: "increment_node"
41
+ type: "transform"
42
+ transform:
43
+ expr: |
44
+ $executionCount("increment_node") = 0
45
+ ? {
46
+ "counter": 1,
47
+ "sum": 1,
48
+ "target": $.entry_sum.n
49
+ }
50
+ : {
51
+ "counter": $nodeExecution("increment_node", -1).counter + 1,
52
+ "sum": $nodeExecution("increment_node", -1).sum + $nodeExecution("increment_node", -1).counter + 1,
53
+ "target": $.entry_sum.n
54
+ }
55
+ next: "check_condition"
56
+
57
+ # Check if we should continue looping
58
+ - id: "check_condition"
59
+ type: "switch"
60
+ conditions:
61
+ - rule:
62
+ "<": [{"var": "$.increment_node.counter"}, {"var": "$.increment_node.target"}]
63
+ target: "increment_node"
64
+ - target: "exit_sum"
65
+
66
+ # Exit node: Extracts the sum from increment_node
67
+ # Uses $previousNode() to verify it returns the switch node's output (target node ID)
68
+ # The output matches the tool's outputSchema (just the sum)
69
+ - id: "exit_sum"
70
+ type: "transform"
71
+ transform:
72
+ expr: |
73
+ $previousNode() = "exit_sum" ? {
74
+ "sum": $.increment_node.sum
75
+ } : {
76
+ "sum": 0,
77
+ "error": "previousNode check failed"
78
+ }
79
+ next: "exit_sum_final"
80
+
81
+ # Final exit node
82
+ - id: "exit_sum_final"
83
+ type: "exit"
84
+ tool: "sum_to_n"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcpgraph",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "MCP server that executes directed graphs of MCP server calls",
5
5
  "main": "dist/main.js",
6
6
  "type": "module",