@zauso-ai/capstan-agent 0.2.0 → 0.3.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/dist/registry.js CHANGED
@@ -1,7 +1,10 @@
1
1
  import { generateAgentManifest } from "./manifest.js";
2
2
  import { generateOpenApiSpec } from "./openapi.js";
3
- import { createMcpServer } from "./mcp.js";
3
+ import { createMcpServer, createMcpHttpHandler } from "./mcp.js";
4
4
  import { createA2AHandler } from "./a2a.js";
5
+ import { withSpan } from "./telemetry.js";
6
+ import { createMcpClient } from "./mcp-client.js";
7
+ import { toLangChainTools } from "./langchain.js";
5
8
  /**
6
9
  * Unified capability registry — the central abstraction for Capstan's
7
10
  * multi-protocol adapter layer.
@@ -27,6 +30,10 @@ export class CapabilityRegistry {
27
30
  /** Register a single route entry. */
28
31
  register(route) {
29
32
  this.routes.push(route);
33
+ void withSpan("capstan.capability.register", {
34
+ "capstan.route.path": route.path,
35
+ "capstan.route.method": route.method,
36
+ }, async () => { });
30
37
  }
31
38
  /** Register multiple route entries at once. */
32
39
  registerAll(routes) {
@@ -51,6 +58,10 @@ export class CapabilityRegistry {
51
58
  }
52
59
  /** Project to OpenAPI 3.1 specification. */
53
60
  toOpenApi() {
61
+ // Fire-and-forget span — synchronous return is not blocked.
62
+ void withSpan("capstan.openapi.generate", {
63
+ "capstan.route.count": this.routes.length,
64
+ }, async () => { });
54
65
  return generateOpenApiSpec(this.config, this.routes);
55
66
  }
56
67
  /**
@@ -63,6 +74,20 @@ export class CapabilityRegistry {
63
74
  toMcp(executeRoute) {
64
75
  return createMcpServer(this.config, this.routes, executeRoute);
65
76
  }
77
+ /**
78
+ * Project to MCP Streamable HTTP handler.
79
+ *
80
+ * Returns a web-standard `(req: Request) => Promise<Response>` handler
81
+ * implementing the MCP Streamable HTTP transport (2025-03-26 spec).
82
+ * Mount it on any route (e.g. `/mcp`) to serve MCP over HTTP.
83
+ *
84
+ * @param executeRoute - Callback that invokes the actual route handler
85
+ * given an HTTP method, path, and input payload.
86
+ * @returns A web-standard request handler.
87
+ */
88
+ toMcpHttp(executeRoute) {
89
+ return createMcpHttpHandler(this.config, this.routes, executeRoute);
90
+ }
66
91
  /**
67
92
  * Project to A2A agent card and JSON-RPC handler.
68
93
  *
@@ -73,5 +98,27 @@ export class CapabilityRegistry {
73
98
  toA2A(executeRoute) {
74
99
  return createA2AHandler(this.config, this.routes, executeRoute);
75
100
  }
101
+ // -------------------------------------------------------------------------
102
+ // MCP Client — consume external MCP servers
103
+ // -------------------------------------------------------------------------
104
+ mcpClients = [];
105
+ /** Connect to an external MCP server and import its tools. */
106
+ async connectMcp(options) {
107
+ const client = await createMcpClient(options);
108
+ this.mcpClients.push(client);
109
+ return client;
110
+ }
111
+ /** Close all MCP client connections. */
112
+ async closeMcpClients() {
113
+ await Promise.allSettled(this.mcpClients.map((c) => c.close()));
114
+ this.mcpClients = [];
115
+ }
116
+ // -------------------------------------------------------------------------
117
+ // LangChain — project to LangChain-compatible tools
118
+ // -------------------------------------------------------------------------
119
+ /** Project to LangChain-compatible tool definitions. */
120
+ toLangChain(options) {
121
+ return toLangChainTools(this, options);
122
+ }
76
123
  }
77
124
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,GAAyB,EAAE,CAAC;IAClC,MAAM,CAAc;IAE5B,YAAY,MAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,4EAA4E;IAC5E,eAAe;IACf,4EAA4E;IAE5E,qCAAqC;IACrC,QAAQ,CAAC,KAAyB;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,WAAW,CAAC,MAA4B;QACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,mCAAmC;IACnC,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,4EAA4E;IAC5E,cAAc;IACd,4EAA4E;IAE5E,gDAAgD;IAChD,UAAU;QACR,OAAO,qBAAqB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,4CAA4C;IAC5C,SAAS;QACP,OAAO,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CACH,YAIqB;QASrB,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CACH,YAIqB;QAKrB,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClE,CAAC;CACF"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Execute an async function inside an OpenTelemetry span.
3
+ *
4
+ * When `@opentelemetry/api` is not installed the function is called directly
5
+ * without any tracing overhead — graceful degradation by design.
6
+ */
7
+ export declare function withSpan<T>(name: string, attributes: Record<string, string | number | boolean>, fn: (span?: any) => Promise<T>): Promise<T>;
8
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACrD,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,CAAC,CAAC,CAkBZ"}
@@ -0,0 +1,48 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * Thin OpenTelemetry wrapper that gracefully degrades when
4
+ * `@opentelemetry/api` is not installed — zero overhead, no hard dep.
5
+ */
6
+ let _tracer = null;
7
+ async function getTracer() {
8
+ if (_tracer)
9
+ return _tracer;
10
+ try {
11
+ const moduleName = "@opentelemetry/api";
12
+ const { trace } = await import(/* webpackIgnore: true */ moduleName);
13
+ _tracer = trace.getTracer("@zauso-ai/capstan-agent", "1.0.0");
14
+ return _tracer;
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ /**
21
+ * Execute an async function inside an OpenTelemetry span.
22
+ *
23
+ * When `@opentelemetry/api` is not installed the function is called directly
24
+ * without any tracing overhead — graceful degradation by design.
25
+ */
26
+ export async function withSpan(name, attributes, fn) {
27
+ const tracer = await getTracer();
28
+ if (!tracer)
29
+ return fn();
30
+ return tracer.startActiveSpan(name, { attributes }, async (span) => {
31
+ try {
32
+ const result = await fn(span);
33
+ span.setStatus({ code: 1 }); // SpanStatusCode.OK
34
+ return result;
35
+ }
36
+ catch (err) {
37
+ span.setStatus({
38
+ code: 2, // SpanStatusCode.ERROR
39
+ message: err instanceof Error ? err.message : "unknown",
40
+ });
41
+ throw err;
42
+ }
43
+ finally {
44
+ span.end();
45
+ }
46
+ });
47
+ }
48
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD;;;GAGG;AAEH,IAAI,OAAO,GAAQ,IAAI,CAAC;AAExB,KAAK,UAAU,SAAS;IACtB,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,oBAAoB,CAAC;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC;QACrE,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAY,EACZ,UAAqD,EACrD,EAA8B;IAE9B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,CAAC;IACzB,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;QACtE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB;YACjD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,CAAC,EAAE,uBAAuB;gBAChC,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;aACxD,CAAC,CAAC;YACH,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,84 @@
1
+ import type { CapabilityRegistry } from "./registry.js";
2
+ /**
3
+ * Result of a single MCP test check.
4
+ */
5
+ export interface McpTestResult {
6
+ pass: boolean;
7
+ tool: string;
8
+ check: string;
9
+ message?: string;
10
+ }
11
+ /**
12
+ * Test harness for validating MCP tool discovery and invocation.
13
+ * Uses the Capstan MCP server in-process (no network needed).
14
+ */
15
+ export declare class McpTestHarness {
16
+ private registry;
17
+ constructor(registry: CapabilityRegistry);
18
+ /**
19
+ * Validate that all registered routes with a `capability` field appear as
20
+ * MCP tools, and that every MCP tool maps back to a registered route.
21
+ */
22
+ validateToolDiscovery(): Promise<McpTestResult[]>;
23
+ /**
24
+ * Validate that MCP tool input schemas match the Zod shapes derived from
25
+ * each route's `inputSchema`.
26
+ */
27
+ validateToolSchemas(): Promise<McpTestResult[]>;
28
+ /**
29
+ * Call a tool with test input and validate the response format.
30
+ *
31
+ * The `executeRoute` callback simulates the actual route handler. The
32
+ * harness verifies that the MCP server wraps the response correctly
33
+ * (content array with text entries).
34
+ */
35
+ validateToolInvocation(toolName: string, input: Record<string, unknown>, executeRoute: (method: string, path: string, input: unknown) => Promise<unknown>): Promise<McpTestResult[]>;
36
+ /**
37
+ * Run all validations: discovery, schemas, and invocation for every tool.
38
+ */
39
+ runAll(executeRoute: (method: string, path: string, input: unknown) => Promise<unknown>): Promise<{
40
+ results: McpTestResult[];
41
+ passed: number;
42
+ failed: number;
43
+ }>;
44
+ }
45
+ /**
46
+ * HTTP-based test client for testing the Streamable HTTP MCP endpoint.
47
+ *
48
+ * Sends JSON-RPC 2.0 POST requests to a running MCP HTTP endpoint and
49
+ * manages session lifecycle via the `Mcp-Session-Id` header.
50
+ */
51
+ export declare class McpHttpTestClient {
52
+ private baseUrl;
53
+ private sessionId;
54
+ private nextId;
55
+ constructor(baseUrl: string);
56
+ /**
57
+ * Send a JSON-RPC 2.0 request to the MCP endpoint.
58
+ */
59
+ private sendRequest;
60
+ /**
61
+ * Send an initialize request to establish a session.
62
+ */
63
+ initialize(): Promise<{
64
+ serverInfo: unknown;
65
+ capabilities: unknown;
66
+ }>;
67
+ /**
68
+ * List all available MCP tools.
69
+ */
70
+ listTools(): Promise<Array<{
71
+ name: string;
72
+ description?: string;
73
+ inputSchema?: unknown;
74
+ }>>;
75
+ /**
76
+ * Call a specific MCP tool by name.
77
+ */
78
+ callTool(name: string, args?: Record<string, unknown>): Promise<unknown>;
79
+ /**
80
+ * Close the current session by sending an HTTP DELETE.
81
+ */
82
+ close(): Promise<void>;
83
+ }
84
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIxD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAqB;gBAEzB,QAAQ,EAAE,kBAAkB;IAIxC;;;OAGG;IACG,qBAAqB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IA2DvD;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAiGrD;;;;;;OAMG;IACG,sBAAsB,CAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,YAAY,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC;IAiI3B;;OAEG;IACG,MAAM,CACV,YAAY,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,GACpB,OAAO,CAAC;QAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CA0BzE;AAcD;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAK;gBAEP,OAAO,EAAE,MAAM;IAI3B;;OAEG;YACW,WAAW;IAqEzB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC;QAC1B,UAAU,EAAE,OAAO,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC;KACvB,CAAC;IA8CF;;OAEG;IACG,SAAS,IAAI,OAAO,CACxB,KAAK,CAAC;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC,CACH;IAqCD;;OAEG;IACG,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC;IAiBnB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB7B"}