Skip to content

[AI-stack E5] @netscript/ai: McpTransportPort (stdio + reconnectable Streamable-HTTP + auth modes) #244

Description

@rickylabs

Add an @netscript/ai/mcp subpath that wraps @tanstack/ai-mcp behind a McpTransportPort, covering stdio and reconnectable Streamable-HTTP transports with none/api-token/oauth auth, and surfaces remote MCP tools into the core tool registry.

Context

Part of epic #238 · cluster ENGINE · wave v1 · depends-on E1, E4

E5 sits in the engine wave alongside the provider adapters and tool registry: it needs the core @netscript/ai port/registry contracts (E1) and the tool-registry surface (E4) in place before remote MCP tools can be registered against it. It ships after those land so the registry has a real slot to receive MCP-sourced tools rather than a placeholder.

Problem / motivation

Today there is no NetScript-native way to consume an MCP server as a tool source. eis-chat hand-rolls MCP wiring per-app (transport selection, reconnect/backoff, auth header plumbing) with no shared port, no connection state machine, and no reuse across providers or apps. Per the standalone-core adapter-by-subpath doctrine (mirroring @netscript/kv / @netscript/kv/redis), MCP integration belongs in @netscript/ai as a self-contained subpath, not as app-level glue or a separate packages/ai-mcp package.

Scope

Ships

  • packages/ai/mcp.ts (or src/mcp/mod.ts re-exported at ./mcp) implementing McpTransportPort.
  • Transport implementations: stdio transport, reconnectable Streamable-HTTP transport (backoff + resume) wrapping @tanstack/ai-mcp.
  • Auth modes: none, api-token, oauth (token/credential supplied via injected config, no hardcoded secret handling).
  • A connection state machine (e.g. disconnected -> connecting -> connected -> reconnecting -> closed) with explicit transitions and a stop()/dispose path per F-13.
  • Registration path that surfaces remote MCP tools into the ToolRegistryPort/registry established in E4 (tool discovery on connect, de-registration on disconnect).
  • Unit tests for transport selection, reconnect/backoff behavior, and auth-mode wiring.

Out of scope

  • OTel spans/tracing for MCP connections and tool calls — owned by E9 (the sole ./otel + TelemetryPort slice).
  • Core port/registry contracts and provider adapters themselves — owned by E1.
  • Tool registry surface and invocation contract — owned by E4.
  • Any fresh/ai or fresh-ui wiring of MCP-sourced tools into chat UI — owned by the fresh/ai and fresh-ui clusters.
  • Named orchestration strategies over MCP tools — out of scope per the v1 primitives-only orchestration decision.

Public surface

  • New subpath export: @netscript/ai/mcp (added to packages/ai/deno.json exports).
  • McpTransportPort interface (connect, disconnect/stop, state, tool discovery callback).
  • StdioMcpTransport and StreamableHttpMcpTransport (or equivalently named) implementations of McpTransportPort.
  • McpAuthMode union type: "none" | "api-token" | "oauth".
  • McpConnectionState type/enum for the connection state machine.
  • Registration function(s) wiring an McpTransportPort instance into the E4 tool registry (e.g. registerMcpTools(registry, transport)).

Acceptance & fitness gates

  • F-3: layering respected — mcp.ts sits in the adapters layer, depends only on core ports/domain, no reverse imports from application into domain.
  • F-5: public surface has @module + JSDoc on all exported symbols; ./mcp subpath stays at or under 20 exports in its entry module.
  • F-6: publishes via deno task publish:dry-run WITHOUT --allow-slow-types.
  • F-13: connection state machine and transports implement explicit stop()/dispose and respect AbortSignal for in-flight connects/reconnects.
  • Reconnect regression test: Streamable-HTTP transport recovers from a mid-stream drop and resumes without duplicating already-surfaced tools.
  • Auth-mode test coverage: none, api-token, oauth each drive the correct handshake/header path against a fake MCP server.
  • Remote tools discovered over a live (or faked) MCP connection appear in the E4 tool registry and are removed on disconnect.

Dependencies

Depends on E1, E4 (GitHub numbers tracked in the #238 DAG checklist). Not blocked by #239.

Size

L

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions