Dataflow devtool
Kovo's repo-internal devtool turns a Kovo graph into two surfaces: a visual dataflow app and an MCP
tool named kovo_explain. Both render the same graph cards, so the page a developer reads and the
artifact an agent consumes stay aligned.
The @kovojs/devtool package is private in the current technical preview. Treat the imports below
as repository tooling examples, not public app dependencies.
Build or capture a graph first#
The devtool consumes graph JSON but does not require generated files to live under src/generated.
Example apps keep graph assertions in tests:
pnpm --filter @kovojs/example-commerce run build:demo
pnpm --filter @kovojs/example-crm test -- src/interactive-app.test.ts
pnpm --filter @kovojs/example-stackoverflow test -- src/interactive-app.test.tsFor a visual devtool host, pass the graph object or a build-produced graph file into
buildBundle(). The CLI writes that file at dist/.kovo/graph.json; the discovery rules are in
Check current source and inspect artifacts explicitly.
Mount it under a repo dev server#
Inside this repository, the Vite plugin can mount the devtool under an existing dev server path such
as /__kovo:
import { devtoolMountPlugin } from '@kovojs/devtool/vite';
export default {
plugins: [devtoolMountPlugin('/__kovo', { handlerModuleId: '/src/app-shell.ts' })],
};Set KOVO_DEVTOOL_BASE=/__kovo so emitted links match the mount path, then run the dev server for
the host example you are testing. The exact package script is repo-local; it is not part of
create-kovo.
KOVO_DEVTOOL_BASE=/__kovo pnpm --filter @kovojs/example-devtool run devBuild a bundle directly in repo tooling#
For repo tooling that owns the host, provide the graph JSON and source root:
import { readFileSync } from 'node:fs';
import { buildBundle } from '@kovojs/devtool';
import { createDevtoolApp } from '@kovojs/devtool/app';
const bundle = buildBundle({
app: 'my-app',
label: 'My App',
graph: JSON.parse(readFileSync('./dist/.kovo/graph.json', 'utf8')),
srcRoot: './src',
});
export const { app, nodeHandler } = createDevtoolApp({ bundles: [bundle] });
export default app;The package is data-free: the host provides app graph and source root; the devtool derives node cards, lanes, source previews, and edges from that input.
Query the same graph through MCP#
Run the MCP server over the same graph:
kovo-devtool mcp --graph ./dist/.kovo/graph.json --src ./src --label "My App"kovo_explain({ query, app?, limit? }) resolves exact node names when possible, then falls back to
deterministic BM25-ranked cards. Results include stable kovo-explain/v1 text and structured
content for agents.
Check that both surfaces match#
Use the repo check that exercises the devtool against real graphs rather than rerunning the MCP command above:
pnpm run checkWhen a graph assertion fails, fix the app facts first: route, query, mutation, domain, or generated graph emission. The devtool should explain the graph you built, not patch around it.
Next#
- Reading kovo check & kovo explain - the graph and audit output behind the cards.
- Testing - where to keep graph assertions in app CI.
Spec & diagnostics
The graph/explain artifact contract and stable kovo-explain/v1 text shape: SPEC §11.4. Machine-
auditable generation and authorable outputs: SPEC §1.3, Constitution #3.
API reference: @kovojs/server.