.compile() returns a RegisteredFlow that maps onto the standard server.registerTool(name, config, handler) contract.
Compile
.compile() validates the graph (see Edges) and throws immediately if the graph is malformed. Accepts one optional argument for a custom state store:
WaniwaniFlowStore, which uses the WaniWani API as a key-value store keyed by session id. It reads WANIWANI_API_KEY and WANIWANI_API_URL from env.
The RegisteredFlow shape
Registering
Use theregister shortcut for the common case:
server.registerTool directly if you prefer:
Batch registration
registerTools from @waniwani/sdk/mcp registers a mix of flows and regular tools in one call. Handy when a flow needs a display tool registered alongside it.
Minimal end-to-end wiring
A completeserver/src/index.ts using @modelcontextprotocol/sdk looks like this:
server/src/index.ts
withWaniwani is idempotent, so calling it twice on the same server is a no-op. Because it wraps registerTool at the point of call, it must run before you register your flows.
Debugging a compiled flow
Inspect the graph
flow.graph() returns a Mermaid diagram of the compiled flow. Log it at startup in development:
Unit-test with createFlowTestHarness
The SDK ships a test harness that drives a compiled flow without spinning up a real transport or store. Import it from @waniwani/sdk/mcp:
start(intent, stateUpdates?): begins a run.intentis positional.continueWith(stateUpdates?): resumes the paused run.lastState(): returns the persistedFlowTokenContentwhen a store is passed viacreateFlowTestHarness(flow, { stateStore }).
FlowTestResult that is the parsed FlowContent (interrupt, widget, complete, or error) plus a decodedState field populated when a store is supplied. Use it to write deterministic tests for branching, validation, and state transitions.