SDK tutorial · 4 of 10

Connect an MCP server

Use MCP when a capability already exists behind a server. The product chooses and trusts the server; Heddle discovers its catalog and exposes the selected tools through the normal runtime, approval, trace, and artifact paths.

Customization depth

Level 2 · External capabilities

Hosting depth

Prepared during Node.js host startup

Documentation status

Runnable reference

Assumptions

  • A trusted MCP server can be started or reached by the Node.js host.
  • The host has a durable workspaceRoot and stateRoot before preparing the extension.
  • The product has decided which MCP tools should be visible to the model.
Heddle owns
  • Refresh the MCP catalog, adapt discovered schemas into Heddle tools, and connect calls to approval and trace behavior.
  • Apply include/exclude filters, name overrides, and optional result-artifact capture.
  • Return an explicit preparation result with a failing step and safe error when startup cannot complete.
Your product owns
  • Select, install, configure, and trust the MCP server and its operating-system permissions.
  • Supply environment variables, executable paths, authentication, and lifecycle policy for the server.
  • Curate the model-visible tool surface and define product authorization around each real action.

Prepare the extension before creating the engine

Use the resolved host roots and replace the sample command with the trusted MCP server your product actually operates:

TypeScript
import { join } from 'node:path'
import {
  prepareMcpHostExtension,
  runQuickstartConversationCli,
} from '@roackb2/heddle'

const workspaceRoot = process.cwd()
const stateRoot = join(workspaceRoot, '.heddle')

const prepared = await prepareMcpHostExtension({
  id: 'document-operations',
  workspaceRoot,
  stateRoot,
  serverId: 'documents',
  server: {
    type: 'stdio',
    command: 'node',
    args: ['./dist/document-mcp-server.js'],
    cwd: workspaceRoot,
  },
  hideDefaultMcpTools: true,
  resultArtifacts: true,
  systemContext: 'Use document tools for drafting, validation, and export.',
})

if (!prepared.ok) {
  throw new Error(
    'MCP setup failed at ' + prepared.step + ': ' + prepared.error,
  )
}

await runQuickstartConversationCli({
  workspaceRoot,
  stateRoot,
  hostExtensions: [prepared.extension],
})

For an embedded product, pass the same prepared.extension to createConversationEngine({ hostExtensions: [...] }) instead.

Curate the model-visible surface

By default, preparation exposes all enabled tools in the refreshed server catalog. Narrow that set deliberately:

TypeScript
const prepared = await prepareMcpHostExtension({
  id: 'document-operations',
  workspaceRoot,
  stateRoot,
  serverId: 'documents',
  server,
  includeTools: ['create_document', 'validate_document'],
  excludeTools: ['delete_document'],
})
  • Use includeTools and excludeTools for a stable curated surface.
  • Use hideDefaultMcpTools: true when the same server would otherwise appear through both raw MCP tools and curated host-tool names.
  • Use toolNamePrefix only when multiple servers expose colliding names.
  • Use toolOverrides for sharper descriptions, public names, capability tags, or approval behavior.

Capture large MCP results

resultArtifacts: true scans generated text, HTML, JSON, and other large strings, saves them as artifacts, and replaces duplicated text/structured mirrors with a compact reference. Start with the boolean setting. Add thresholds, path hints, or manual rules only after observing a real server result shape.

Security boundary

An MCP declaration is an integration, not a trust grant. A local stdio server runs with the host process user's operating-system permissions. Authenticate and authorize product requests before a tool call reaches the server, and keep approval policy aligned with the real side effects.

Failure behavior

Preparation is explicit startup work. Log prepared.step with operational context, fail deployment readiness when a required server cannot prepare, and avoid silently removing required capabilities. Do not leak server credentials or raw secret-bearing diagnostics to a browser client.

Canonical sources