MCP from Claude
@nwire/mcp exposes the wire-side /_nwire/* inspection surface as MCP tools so Claude Code (or any other MCP client) can introspect a running Nwire app and dispatch actions against it.
Wire it into Claude Code
Add the server to ~/.claude/mcp.json:
{
"mcpServers": {
"nwire": {
"command": "pnpm",
"args": ["exec", "nwire", "mcp"],
"env": { "NWIRE_PORT_HINT": "3000" }
}
}
}The server port-probes the local machine to find your running wire and connects to its /_nwire root. Requires @nwire/cli ≥ 0.9 with the mcp subcommand (experimental — see stability contract).
Available tools
| Tool | Reads | Notes |
|---|---|---|
manifest | /_nwire/manifest | Full app graph: modules, actions, events |
list_actions | manifest slice | Names, inputs, owning module |
list_events | manifest slice | Names, payload schemas |
list_hooks | manifest slice | Named hooks + step counts |
list_plugins | manifest slice | Plugin contributions |
recent_events | /_nwire/events/recent | Ring-buffer of fired domain events |
recent_telemetry | /_nwire/telemetry/recent | Ring-buffer of telemetry kinds |
dispatch_action | POST /_nwire/dispatch | Drives the same code path as HTTP |
Dispatching actions
dispatch_action takes { action, input, user?, tenant? }. action is the registered handler name (list_actions shows them); user.id threads into the handler's envelope as envelope.userId, and tenant as envelope.tenant, so an action that authorizes on envelope.userId sees who is calling. (The tool schema also accepts user.roles, but the dispatch payload forwards only the id — roles don't reach the envelope.) handler and name are accepted as deprecated aliases for action for one release — the result carries a deprecation note when one is used.
Failures come back as coded tool errors, the same error contract the HTTP surface speaks: a zod-invalid input is validation_failed (400) naming the failing field, an unknown action is action_not_found (404), and a generic throw inside the handler is an opaque internal_error (500) unless the wire runs with exposeErrors — never a raw stack trace or driver message.
Example prompt
Claude, the wire is running. Use
list_actionsto find the posts publish action, then calldispatch_actionwith{ title: "draft from claude", body: "test" }and report the events that fired.
Claude will pick the action, dispatch it, and read back the resulting events — useful for smoke-testing a new module without writing a fixture.