mcpgraph 0.1.5 → 0.1.7

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 (47) hide show
  1. package/README.md +1 -0
  2. package/dist/api.d.ts +17 -1
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +33 -4
  5. package/dist/api.js.map +1 -1
  6. package/dist/execution/context.d.ts +3 -6
  7. package/dist/execution/context.d.ts.map +1 -1
  8. package/dist/execution/context.js +11 -2
  9. package/dist/execution/context.js.map +1 -1
  10. package/dist/execution/controller.d.ts +29 -0
  11. package/dist/execution/controller.d.ts.map +1 -0
  12. package/dist/execution/controller.js +95 -0
  13. package/dist/execution/controller.js.map +1 -0
  14. package/dist/execution/executor.d.ts +8 -1
  15. package/dist/execution/executor.d.ts.map +1 -1
  16. package/dist/execution/executor.js +184 -37
  17. package/dist/execution/executor.js.map +1 -1
  18. package/dist/execution/nodes/entry-executor.d.ts +1 -1
  19. package/dist/execution/nodes/entry-executor.d.ts.map +1 -1
  20. package/dist/execution/nodes/entry-executor.js +3 -2
  21. package/dist/execution/nodes/entry-executor.js.map +1 -1
  22. package/dist/execution/nodes/exit-executor.d.ts +1 -1
  23. package/dist/execution/nodes/exit-executor.d.ts.map +1 -1
  24. package/dist/execution/nodes/exit-executor.js +3 -2
  25. package/dist/execution/nodes/exit-executor.js.map +1 -1
  26. package/dist/execution/nodes/mcp-tool-executor.d.ts +1 -1
  27. package/dist/execution/nodes/mcp-tool-executor.d.ts.map +1 -1
  28. package/dist/execution/nodes/mcp-tool-executor.js +3 -2
  29. package/dist/execution/nodes/mcp-tool-executor.js.map +1 -1
  30. package/dist/execution/nodes/switch-executor.d.ts +1 -1
  31. package/dist/execution/nodes/switch-executor.d.ts.map +1 -1
  32. package/dist/execution/nodes/switch-executor.js +7 -2
  33. package/dist/execution/nodes/switch-executor.js.map +1 -1
  34. package/dist/execution/nodes/transform-executor.d.ts +1 -1
  35. package/dist/execution/nodes/transform-executor.d.ts.map +1 -1
  36. package/dist/execution/nodes/transform-executor.js +3 -2
  37. package/dist/execution/nodes/transform-executor.js.map +1 -1
  38. package/dist/types/execution.d.ts +92 -0
  39. package/dist/types/execution.d.ts.map +1 -0
  40. package/dist/types/execution.js +5 -0
  41. package/dist/types/execution.js.map +1 -0
  42. package/docs/design.md +220 -0
  43. package/docs/implementation.md +377 -0
  44. package/docs/introspection-debugging.md +651 -0
  45. package/examples/api-usage.ts +49 -1
  46. package/examples/switch_example.yaml +80 -0
  47. package/package.json +2 -1
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { EntryNode } from "../../types/config.js";
5
5
  import type { ExecutionContext } from "../context.js";
6
- export declare function executeEntryNode(node: EntryNode, toolInput: Record<string, unknown>, context: ExecutionContext): {
6
+ export declare function executeEntryNode(node: EntryNode, toolInput: Record<string, unknown>, context: ExecutionContext, startTime: number): {
7
7
  output: unknown;
8
8
  nextNode: string;
9
9
  };
@@ -1 +1 @@
1
- {"version":3,"file":"entry-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/entry-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,OAAO,EAAE,gBAAgB,GACxB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcvC"}
1
+ {"version":3,"file":"entry-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/entry-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAevC"}
@@ -2,13 +2,14 @@
2
2
  * Entry node executor
3
3
  */
4
4
  import { logger } from "../../logger.js";
5
- export function executeEntryNode(node, toolInput, context) {
5
+ export function executeEntryNode(node, toolInput, context, startTime) {
6
6
  logger.debug(`Executing entry node: ${node.id}`);
7
7
  // Entry node receives tool input and initializes context
8
8
  // The input is already in the context, so we just pass it through
9
9
  const output = toolInput;
10
+ const endTime = Date.now();
10
11
  context.setNodeOutput(node.id, output);
11
- context.addHistory(node.id, toolInput, output);
12
+ context.addHistory(node.id, "entry", toolInput, output, startTime, endTime);
12
13
  return {
13
14
  output,
14
15
  nextNode: node.next,
@@ -1 +1 @@
1
- {"version":3,"file":"entry-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/entry-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAC9B,IAAe,EACf,SAAkC,EAClC,OAAyB;IAEzB,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEjD,yDAAyD;IACzD,kEAAkE;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC;IAEzB,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAE/C,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,IAAI,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"entry-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/entry-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAC9B,IAAe,EACf,SAAkC,EAClC,OAAyB,EACzB,SAAiB;IAEjB,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEjD,yDAAyD;IACzD,kEAAkE;IAClE,MAAM,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAE5E,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,IAAI,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC"}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { ExitNode } from "../../types/config.js";
5
5
  import type { ExecutionContext } from "../context.js";
6
- export declare function executeExitNode(node: ExitNode, context: ExecutionContext): {
6
+ export declare function executeExitNode(node: ExitNode, context: ExecutionContext, startTime: number): {
7
7
  output: unknown;
8
8
  };
9
9
  //# sourceMappingURL=exit-executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exit-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/exit-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,gBAAgB,GACxB;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAarB"}
1
+ {"version":3,"file":"exit-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/exit-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAcrB"}
@@ -2,13 +2,14 @@
2
2
  * Exit node executor
3
3
  */
4
4
  import { logger } from "../../logger.js";
5
- export function executeExitNode(node, context) {
5
+ export function executeExitNode(node, context, startTime) {
6
6
  logger.debug(`Executing exit node: ${node.id}`);
7
7
  // Exit node extracts the final result from context
8
8
  // Use the last output or the context's output
9
9
  const data = context.getData();
10
10
  const output = data.output || data.last || {};
11
- context.addHistory(node.id, data, output);
11
+ const endTime = Date.now();
12
+ context.addHistory(node.id, "exit", data, output, startTime, endTime);
12
13
  return {
13
14
  output,
14
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"exit-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/exit-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,UAAU,eAAe,CAC7B,IAAc,EACd,OAAyB;IAEzB,MAAM,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhD,mDAAmD;IACnD,8CAA8C;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAE9C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO;QACL,MAAM;KACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"exit-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/exit-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,UAAU,eAAe,CAC7B,IAAc,EACd,OAAyB,EACzB,SAAiB;IAEjB,MAAM,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhD,mDAAmD;IACnD,8CAA8C;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEtE,OAAO;QACL,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -4,7 +4,7 @@
4
4
  import type { McpNode, ServerConfig } from "../../types/config.js";
5
5
  import type { ExecutionContext } from "../context.js";
6
6
  import type { McpClientManager } from "../../mcp/client-manager.js";
7
- export declare function executeMcpToolNode(node: McpNode, context: ExecutionContext, clientManager: McpClientManager, serverConfig: ServerConfig): Promise<{
7
+ export declare function executeMcpToolNode(node: McpNode, context: ExecutionContext, clientManager: McpClientManager, serverConfig: ServerConfig, startTime: number): Promise<{
8
8
  output: unknown;
9
9
  nextNode: string;
10
10
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tool-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/mcp-tool-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,gBAAgB,EAC/B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAiEhD"}
1
+ {"version":3,"file":"mcp-tool-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/mcp-tool-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,gBAAgB,EAC/B,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAkEhD"}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { evaluateJsonata } from "../../expressions/jsonata.js";
5
5
  import { logger } from "../../logger.js";
6
- export async function executeMcpToolNode(node, context, clientManager, serverConfig) {
6
+ export async function executeMcpToolNode(node, context, clientManager, serverConfig, startTime) {
7
7
  logger.debug(`Executing MCP tool node: ${node.id} (${node.server}.${node.tool})`);
8
8
  const exprContext = context.getData();
9
9
  // Pre-transform: Apply JSONata to format tool arguments
@@ -54,8 +54,9 @@ export async function executeMcpToolNode(node, context, clientManager, serverCon
54
54
  }
55
55
  logger.debug(`MCP tool output: ${JSON.stringify(toolOutput, null, 2)}`);
56
56
  const output = toolOutput;
57
+ const endTime = Date.now();
57
58
  context.setNodeOutput(node.id, output);
58
- context.addHistory(node.id, transformedArgs, output);
59
+ context.addHistory(node.id, "mcp", transformedArgs, output, startTime, endTime);
59
60
  return {
60
61
  output,
61
62
  nextNode: node.next,
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-tool-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/mcp-tool-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-tool-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/mcp-tool-executor.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { SwitchNode } from "../../types/config.js";
5
5
  import type { ExecutionContext } from "../context.js";
6
- export declare function executeSwitchNode(node: SwitchNode, context: ExecutionContext): Promise<{
6
+ export declare function executeSwitchNode(node: SwitchNode, context: ExecutionContext, startTime: number): Promise<{
7
7
  output: unknown;
8
8
  nextNode: string;
9
9
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"switch-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/switch-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgChD"}
1
+ {"version":3,"file":"switch-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/switch-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAqChD"}
@@ -3,14 +3,16 @@
3
3
  */
4
4
  import { evaluateJsonLogic } from "../../expressions/json-logic.js";
5
5
  import { logger } from "../../logger.js";
6
- export async function executeSwitchNode(node, context) {
6
+ export async function executeSwitchNode(node, context, startTime) {
7
7
  logger.debug(`Executing switch node: ${node.id}`);
8
8
  const exprContext = context.getData();
9
+ const endTime = Date.now();
9
10
  // Evaluate conditions in order
10
11
  for (const condition of node.conditions) {
11
12
  // If no rule is specified, this is a default/fallback case
12
13
  if (condition.rule === undefined || condition.rule === null) {
13
14
  logger.debug(`Switch node ${node.id}: Using default/fallback target: ${condition.target}`);
15
+ context.addHistory(node.id, "switch", exprContext, exprContext, startTime, endTime);
14
16
  return {
15
17
  output: exprContext,
16
18
  nextNode: condition.target,
@@ -20,6 +22,7 @@ export async function executeSwitchNode(node, context) {
20
22
  const ruleResult = evaluateJsonLogic(condition.rule, exprContext);
21
23
  if (ruleResult) {
22
24
  logger.debug(`Switch node ${node.id}: Condition matched, routing to: ${condition.target}`);
25
+ context.addHistory(node.id, "switch", exprContext, exprContext, startTime, endTime);
23
26
  return {
24
27
  output: exprContext,
25
28
  nextNode: condition.target,
@@ -27,6 +30,8 @@ export async function executeSwitchNode(node, context) {
27
30
  }
28
31
  }
29
32
  // No conditions matched and no default case
30
- throw new Error(`Switch node ${node.id}: No conditions matched and no default case provided`);
33
+ const error = new Error(`Switch node ${node.id}: No conditions matched and no default case provided`);
34
+ context.addHistory(node.id, "switch", exprContext, null, startTime, endTime, error);
35
+ throw error;
31
36
  }
32
37
  //# sourceMappingURL=switch-executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"switch-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/switch-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAgB,EAChB,OAAyB;IAEzB,MAAM,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAElD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAEtC,+BAA+B;IAC/B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,2DAA2D;QAC3D,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3F,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,SAAS,CAAC,MAAM;aAC3B,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAElE,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3F,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,SAAS,CAAC,MAAM;aAC3B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,MAAM,IAAI,KAAK,CACb,eAAe,IAAI,CAAC,EAAE,sDAAsD,CAC7E,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"switch-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/switch-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAgB,EAChB,OAAyB,EACzB,SAAiB;IAEjB,MAAM,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAElD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,+BAA+B;IAC/B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,2DAA2D;QAC3D,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3F,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACpF,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,SAAS,CAAC,MAAM;aAC3B,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAElE,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,EAAE,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3F,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACpF,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,SAAS,CAAC,MAAM;aAC3B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,eAAe,IAAI,CAAC,EAAE,sDAAsD,CAC7E,CAAC;IACF,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACpF,MAAM,KAAK,CAAC;AACd,CAAC"}
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import type { TransformNode } from "../../types/config.js";
5
5
  import type { ExecutionContext } from "../context.js";
6
- export declare function executeTransformNode(node: TransformNode, context: ExecutionContext): Promise<{
6
+ export declare function executeTransformNode(node: TransformNode, context: ExecutionContext, startTime: number): Promise<{
7
7
  output: unknown;
8
8
  nextNode: string;
9
9
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"transform-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/transform-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBhD"}
1
+ {"version":3,"file":"transform-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/nodes/transform-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBhD"}
@@ -3,15 +3,16 @@
3
3
  */
4
4
  import { evaluateJsonata } from "../../expressions/jsonata.js";
5
5
  import { logger } from "../../logger.js";
6
- export async function executeTransformNode(node, context) {
6
+ export async function executeTransformNode(node, context, startTime) {
7
7
  logger.debug(`Executing transform node: ${node.id}`);
8
8
  logger.debug(`Transform expression: ${node.transform.expr}`);
9
9
  const exprContext = context.getData();
10
10
  logger.debug(`Transform context: ${JSON.stringify(exprContext, null, 2)}`);
11
11
  const output = await evaluateJsonata(node.transform.expr, exprContext);
12
+ const endTime = Date.now();
12
13
  logger.debug(`Transform output: ${JSON.stringify(output, null, 2)}`);
13
14
  context.setNodeOutput(node.id, output);
14
- context.addHistory(node.id, exprContext, output);
15
+ context.addHistory(node.id, "transform", exprContext, output, startTime, endTime);
15
16
  return {
16
17
  output,
17
18
  nextNode: node.next,
@@ -1 +1 @@
1
- {"version":3,"file":"transform-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/transform-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAmB,EACnB,OAAyB;IAEzB,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAEvE,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAEjD,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,IAAI,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"transform-executor.js","sourceRoot":"","sources":["../../../src/execution/nodes/transform-executor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAmB,EACnB,OAAyB,EACzB,SAAiB;IAEjB,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAE7D,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE3B,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAElF,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,IAAI,CAAC,IAAI;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Types for execution introspection and debugging
3
+ */
4
+ import type { NodeDefinition } from "./config.js";
5
+ import type { ExecutionContext } from "../execution/context.js";
6
+ export type ExecutionStatus = "not_started" | "running" | "paused" | "finished" | "error";
7
+ export interface NodeExecutionRecord {
8
+ nodeId: string;
9
+ nodeType: string;
10
+ startTime: number;
11
+ endTime: number;
12
+ duration: number;
13
+ input: unknown;
14
+ output: unknown;
15
+ error?: Error;
16
+ }
17
+ export interface ExecutionState {
18
+ status: ExecutionStatus;
19
+ currentNodeId: string | null;
20
+ executionHistory: NodeExecutionRecord[];
21
+ context: ExecutionContext;
22
+ error?: Error;
23
+ }
24
+ export interface ExecutionHooks {
25
+ /**
26
+ * Called before a node executes
27
+ * Return false to pause execution (breakpoint)
28
+ */
29
+ onNodeStart?: (nodeId: string, node: NodeDefinition, context: ExecutionContext) => Promise<boolean>;
30
+ /**
31
+ * Called after a node completes successfully
32
+ */
33
+ onNodeComplete?: (nodeId: string, node: NodeDefinition, input: unknown, output: unknown, duration: number) => Promise<void>;
34
+ /**
35
+ * Called when a node encounters an error
36
+ */
37
+ onNodeError?: (nodeId: string, node: NodeDefinition, error: Error, context: ExecutionContext) => Promise<void>;
38
+ /**
39
+ * Called when execution pauses (breakpoint hit or manual pause)
40
+ */
41
+ onPause?: (nodeId: string, context: ExecutionContext) => Promise<void>;
42
+ /**
43
+ * Called when execution resumes
44
+ */
45
+ onResume?: () => Promise<void>;
46
+ }
47
+ export interface ExecutionController {
48
+ /**
49
+ * Pause execution at the next node boundary
50
+ * Only valid when status is "running"
51
+ */
52
+ pause(): void;
53
+ /**
54
+ * Resume execution
55
+ * Only valid when status is "paused"
56
+ */
57
+ resume(): void;
58
+ /**
59
+ * Step to the next node (step over)
60
+ * Only valid when status is "paused"
61
+ */
62
+ step(): Promise<void>;
63
+ /**
64
+ * Get current execution state
65
+ */
66
+ getState(): ExecutionState;
67
+ /**
68
+ * Set breakpoints
69
+ */
70
+ setBreakpoints(nodeIds: string[]): void;
71
+ /**
72
+ * Clear breakpoints
73
+ */
74
+ clearBreakpoints(): void;
75
+ }
76
+ export interface ExecutionOptions {
77
+ hooks?: ExecutionHooks;
78
+ breakpoints?: string[];
79
+ enableTelemetry?: boolean;
80
+ }
81
+ export interface ExecutionTelemetry {
82
+ totalDuration: number;
83
+ nodeDurations: Map<string, number>;
84
+ nodeCounts: Map<string, number>;
85
+ errorCount: number;
86
+ }
87
+ export interface ExecutionResult {
88
+ result: unknown;
89
+ executionHistory: NodeExecutionRecord[];
90
+ telemetry?: ExecutionTelemetry;
91
+ }
92
+ //# sourceMappingURL=execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/types/execution.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;;OAGG;IACH,MAAM,IAAI,IAAI,CAAC;IAEf;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,QAAQ,IAAI,cAAc,CAAC;IAE3B;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAExC;;OAEG;IACH,gBAAgB,IAAI,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for execution introspection and debugging
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/types/execution.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/docs/design.md ADDED
@@ -0,0 +1,220 @@
1
+ # mcpGraph Design Document
2
+
3
+ ## Overview
4
+
5
+ This document memorializes the high-level design and tooling recommendations for mcpGraph, a product similar to n8n that surfaces an MCP interface and internally implements a directed graph of MCP server calls. The system enables filtering and reformatting data between nodes, makes routing decisions based on node output, and maintains a declarative, observable configuration without embedding a full programming language.
6
+
7
+ ## Core Architecture: The Orchestrator
8
+
9
+ ### Recommended Platform: TypeScript (Node.js)
10
+
11
+ **Rationale:**
12
+ - The MCP SDK is most mature in TypeScript
13
+ - Frontend tools for visual graph editing (like React Flow) are industry standard
14
+ - Strong ecosystem for both backend orchestration and frontend visualization
15
+
16
+ ### Graph Execution Engine
17
+
18
+ The system implements a custom graph execution engine that orchestrates the directed graph of MCP server calls.
19
+
20
+ **Design Approach:**
21
+ - **Custom Execution Loop**: A lightweight, sequential execution loop that provides full control over execution flow
22
+ - **Simple Architecture**: Direct mapping from YAML node definitions to execution, avoiding abstraction layers
23
+ - **Data Flow**: Execution context maintains state and data flow between nodes
24
+ - **Control Flow**: Supports conditional routing via switch nodes; cycles are supported for future loop constructs
25
+ - **Observability**: Built-in execution history tracking for debugging and introspection
26
+
27
+ **Implementation:**
28
+ The YAML configuration is parsed into a graph structure (`Graph` class) and executed by a custom `GraphExecutor` that:
29
+ - Starts at the tool's entry node
30
+ - Executes nodes sequentially based on the graph structure
31
+ - Tracks execution state and history
32
+ - Routes conditionally via switch nodes
33
+ - Continues until the exit node is reached
34
+
35
+ ### MCP Integration
36
+
37
+ - Use `@modelcontextprotocol/sdk`
38
+ - The system exposes an MCP server interface
39
+ - The YAML configuration defines the MCP server metadata and the tools it exposes
40
+ - Each tool definition includes standard MCP tool metadata (name, description, input/output parameters)
41
+ - Each tool's graph has an explicit entry node that receives tool arguments and initializes execution
42
+ - Each tool's graph has an explicit exit node that returns the final result to the MCP tool caller
43
+ - Execution flows through the graph from entry node to exit node
44
+
45
+ ## Declarative Logic & Data Transformation
46
+
47
+ To avoid embedding a full programming language while maintaining declarative, observable configurations, the system uses standardized expression engines.
48
+
49
+ ### Data Reformatting: JSONata
50
+
51
+ **Why JSONata:**
52
+ - Declarative query and transformation language for JSON
53
+ - Single string expression enables clear observability
54
+ - Can log input, expression, and output to debug transformations
55
+
56
+ **Resources:** [JSONata Documentation](https://jsonata.org/)
57
+
58
+ **YAML Example:**
59
+ ```yaml
60
+ transform:
61
+ expr: "$merge([payload, {'timestamp': $now()}])"
62
+ ```
63
+
64
+ ### Routing Decisions: JSON Logic
65
+
66
+ **Why JSON Logic:**
67
+ - Allows complex rules (e.g., "if price > 100 and status == 'active'") as pure JSON objects
68
+ - Declarative and observable
69
+ - No embedded code execution
70
+
71
+ **Resources:** [JSON Logic Documentation](https://jsonlogic.com/)
72
+
73
+ **YAML Example:**
74
+ ```yaml
75
+ condition:
76
+ and:
77
+ - ">": [{ var: "price" }, 100]
78
+ - "==": [{ var: "status" }, "active"]
79
+ ```
80
+
81
+ ## High-Level Design: The Graph Runner
82
+
83
+ The system exposes an MCP server that reads a YAML configuration file. When a tool is called on this MCP server, it executes the corresponding graph starting at the tool's entry node and continuing until the exit node is reached.
84
+
85
+ ### The Workflow Lifecycle
86
+
87
+ 1. **Parse**: Read the YAML configuration into a structure containing MCP server metadata, tool definitions, and the directed graph of nodes
88
+ 2. **Initialize MCP Server**: Expose the MCP server with the tools defined in the configuration
89
+ 3. **Tool Invocation**: When a tool is called:
90
+ - Receive tool arguments from the MCP client
91
+ - Start graph execution at the tool's entry node
92
+ - Entry node receives tool arguments and initializes the execution context
93
+ 4. **Execute Node**:
94
+ - **Entry Node**: Receives tool arguments, initializes execution context, passes to next node
95
+ - **Pre-transform**: Apply JSONata to the incoming data to format the tool arguments (if node is an MCP tool call)
96
+ - **Call Tool**: Use the MCP SDK to `callTool` on the target server (if node is an MCP tool call)
97
+ - **Transform**: Apply JSONata expressions to transform data (if node is a transform node)
98
+ - **Route**: Evaluate JSON Logic against the current data state to decide which edge to follow next (if node is a switch/conditional)
99
+ - **Track History**: Record node execution with inputs and outputs for observability
100
+ 5. **Exit Node**: When execution reaches the exit node, extract the final result and return it to the MCP tool caller
101
+
102
+ ## Visual Tooling & Observability
103
+
104
+ ### Component Recommendations
105
+
106
+ | Component | Tooling Recommendation |
107
+ |-----------|----------------------|
108
+ | **Visual Editor** | **React Flow** - Industry standard for node-based UIs, used by companies like Stripe and Typeform. Provides customizable nodes, edges, zooming, panning, and built-in components like MiniMap and Controls. [React Flow Documentation](https://reactflow.dev/) |
109
+ | **Observability** | OpenTelemetry - wrap each node execution in a "Span" to see the "Trace" of data through the graph in tools like Jaeger |
110
+
111
+ ## Implementation Strategy: The YAML Standard
112
+
113
+ Graph definitions should feel like Kubernetes manifests or GitHub Actions - declarative and version-controlled.
114
+
115
+ ### Configuration Structure
116
+
117
+ The YAML configuration centers around MCP server and tool definitions:
118
+
119
+ 1. **MCP Server Metadata**: Defines the MCP server information (name, version, description)
120
+ 2. **Tools**: Array of tool definitions, each containing:
121
+ - Standard MCP tool metadata (name, description)
122
+ - Input parameters schema (MCP tool parameter definitions)
123
+ - Output schema (what the tool returns)
124
+ - Note: Entry and exit nodes are defined in the nodes section with a `tool` field indicating which tool they belong to
125
+ 3. **Nodes**: The directed graph of nodes that execute when tools are called. Node types include:
126
+ - **`entry`**: Entry point for a tool's graph execution. Receives tool arguments and initializes execution context.
127
+ - **`mcp`**: Calls an MCP tool on an internal or external MCP server using `callTool`
128
+ - **`transform`**: Applies JSONata expressions to transform data between nodes
129
+ - **`switch`**: Uses JSON Logic to conditionally route to different nodes based on data
130
+ - **`exit`**: Exit point for a tool's graph execution. Extracts and returns the final result to the MCP tool caller
131
+
132
+ ### Example YAML Structure: count_files Tool
133
+
134
+ This example defines a `count_files` tool that takes a directory, lists its contents using the filesystem MCP server, counts the files, and returns the count:
135
+
136
+ ```yaml
137
+ version: "1.0"
138
+
139
+ # MCP Server Metadata
140
+ server:
141
+ name: "fileUtils"
142
+ version: "1.0.0"
143
+ description: "File utilities"
144
+
145
+ # Tool Definitions
146
+ tools:
147
+ - name: "count_files"
148
+ description: "Counts the number of files in a directory"
149
+ inputSchema:
150
+ type: "object"
151
+ properties:
152
+ directory:
153
+ type: "string"
154
+ description: "The directory path to count files in"
155
+ required:
156
+ - directory
157
+ outputSchema:
158
+ type: "object"
159
+ properties:
160
+ count:
161
+ type: "number"
162
+ description: "The number of files in the directory"
163
+
164
+ # MCP Servers used by the graph
165
+ servers:
166
+ filesystem:
167
+ command: "npx"
168
+ args:
169
+ - "-y"
170
+ - "@modelcontextprotocol/server-filesystem"
171
+ - "./tests/files"
172
+
173
+ # Graph Nodes
174
+ nodes:
175
+ # Entry node: Receives tool arguments
176
+ - id: "entry_count_files"
177
+ type: "entry"
178
+ tool: "count_files"
179
+ next: "list_directory_node"
180
+
181
+ # List directory contents
182
+ - id: "list_directory_node"
183
+ type: "mcp"
184
+ server: "filesystem"
185
+ tool: "list_directory"
186
+ args:
187
+ path: "$.input.directory"
188
+ next: "count_files_node"
189
+
190
+ # Transform and count files
191
+ - id: "count_files_node"
192
+ type: "transform"
193
+ transform:
194
+ expr: |
195
+ { "count": $count($split(list_directory_node, "\n")) }
196
+ next: "exit_count_files"
197
+
198
+ # Exit node: Returns the count
199
+ - id: "exit_count_files"
200
+ type: "exit"
201
+ tool: "count_files"
202
+ ```
203
+
204
+ ## Key Design Principles
205
+
206
+ 1. **Declarative Configuration**: All logic expressed in YAML using standard expression languages (JSONata, JSON Logic)
207
+ 2. **Observability**: Every transformation and decision is traceable and loggable
208
+ 3. **No Embedded Code**: Avoid full programming languages to maintain clarity and safety
209
+ 4. **Standard-Based**: Favor existing standards (JSONata, JSON Logic) over custom solutions
210
+ 5. **Visual First**: Graph should be viewable and editable through a visual interface
211
+ 6. **Execution Transparency**: Ability to observe graph execution in real-time
212
+
213
+ ## System Components
214
+
215
+ 1. **Executable**: Exposes an MCP server to run the graph (`mcpgraph` CLI)
216
+ 2. **Programmatic API**: Exports `McpGraphApi` class for programmatic use (e.g., by visualizer applications)
217
+ 3. **Graph Executor**: Core orchestration engine that executes the directed graph sequentially
218
+ 4. **Execution Context**: Tracks execution state, data flow, and history
219
+ 5. **Visual Editor**: Tools to visually view and edit the graph (future)
220
+ 6. **Execution Observer**: Ability to observe and debug graph execution (future - see `docs/future-introspection-debugging.md`)