Skip to content

Feat/mcp package#5

Merged
angelocavallo merged 3 commits into
mainfrom
feat/mcp-package
Jun 26, 2026
Merged

Feat/mcp package#5
angelocavallo merged 3 commits into
mainfrom
feat/mcp-package

Conversation

@angelocavallo

Copy link
Copy Markdown
Contributor

No description provided.

Angelo and others added 3 commits June 26, 2026 16:45
Add first-class MCP (Model Context Protocol) support as a new opt-in
workspace package, plus a vanilla-TS demo that exercises it end-to-end.
Core is untouched; the @modelcontextprotocol/sdk dependency is isolated
in the new package so users who don't need MCP never pull it in.

@forgewisp/mcp (packages/mcp, v0.4.1 — lockstep with core/bundled-tools):
- Adapts MCP server tools (Streamable HTTP transport) into
  FunctionDefinitions registered through the agent's existing
  registerFunction path, so core's registry, Ajv validation, two-phase
  executor, onConfirmRequired invariant, audit log, and runToolLoop all
  apply to MCP tools unchanged. Core is a types-only/peer dependency;
  the package never instantiates a core class.
- Public surface: registerMcpServer(agent, config) and the lower-level
  createMcpTools(config, options?), with McpServerConfig/McpServerHandle/
  McpAuthState/McpConnectOptions/McpToolsResult/AgentLike types and
  type-only re-exports from core + the SDK.
- Invariants enforced in src/mcp.ts: risk tiers come from config (MCP
  hints deliberately not auto-mapped), confirmation preflight before any
  registration on write/destructive without hasConfirmation, draft-07
  inputSchema passed through via documented cast, OpenAI-safe namespaced
  names with collision suffixing, result flattening, abort forwarding with
  per-server requestTimeoutMs.
- OAuth 2.1 + PKCE via McpServerConfig.authProvider with an
  'authorized'/'pending' state machine and fresh-transport resume
  (finishAuth / authorizationCode); client/auth.js is dynamically imported
  only on the OAuth path.
- ESM + CJS only (no IIFE/global build); SDK externalized. Tests use the
  SDK's InMemoryTransport via an @internal transport injection seam.
- release.yml: tag-check + publish order now include packages/mcp
  (published last; workspace:* dep on core rewrites on publish).

apps/mcp-demo: MCP-only agent (no inline/bundled tools) that connects to
one or more Streamable-HTTP MCP servers at runtime via createMcpTools, with
a tier-grouped connected-tools sidebar and an MCP Servers panel.
LocalStorageOAuthProvider + oauth-callback.html handle OAuth redirects
(popup postMessage + same-tab fallback) and page-reload resume. Server
chips built via the DOM API; renderMarkdown keeplist unchanged.

Code-review fixes folded into the initial implementation: withTimeout
timer/abort-listener leak + bounded listAllTools, prefix/name sanitization,
onlyTools:[] registers none, client close on listAndAdapt throw, finishAuth
race guard, CLIENT_INFO version sourced from package.json, core moved to
peerDependencies, PKCE codeVerifier randomization, abandonAllServersSync on
rebuild, bounded audit log, rAF-coalesced streaming render.

Verified locally: format:check, lint, typecheck (11), build (8), test
(mcp 41 + mcp-demo 22), pnpm install --frozen-lockfile all green.

Co-Authored-By: Claude <noreply@anthropic.com>
…taleness

Co-Authored-By: Claude <noreply@anthropic.com>
…/mcp to 0.5.0

Co-Authored-By: Claude <noreply@anthropic.com>
@angelocavallo angelocavallo merged commit 1cce464 into main Jun 26, 2026
1 check passed
@angelocavallo angelocavallo deleted the feat/mcp-package branch June 26, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant