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.
- 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.
- 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:
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:
const prepared = await prepareMcpHostExtension({
id: 'document-operations',
workspaceRoot,
stateRoot,
serverId: 'documents',
server,
includeTools: ['create_document', 'validate_document'],
excludeTools: ['delete_document'],
})- Use
includeToolsandexcludeToolsfor a stable curated surface. - Use
hideDefaultMcpTools: truewhen the same server would otherwise appear through both raw MCP tools and curated host-tool names. - Use
toolNamePrefixonly when multiple servers expose colliding names. - Use
toolOverridesfor 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.