Debug and test the Kitsoki studio MCP server and its tools from the repo checkout. Use when working on `kitsoki mcp`, `cmd/kitsoki/mcp_test_client.go`, `internal/mcp/studio`, MCP tool registration, stdio MCP handshake failures, visual MCP tools (`visual.open`, `visual.observe`, `visual.act`), `mcp-test` output, or when the user wants to verify studio MCP changes without reloading an LLM client.
Use kitsoki mcp-test as the first validation surface for studio MCP work. It
spawns the studio MCP server over stdio with the official Go MCP SDK client, so
it exercises the same transport boundary an attached coding agent uses without
requiring Claude/Codex to reload its MCP tool list.
Run from the repo root:
GOCACHE=$PWD/.cache/go-build go run ./cmd/kitsoki mcp-test --stories-dir ./stories --timeout 20sExpected behavior:
kitsoki: studio MCP server on stdio ... on stderr"ok": truetools includes studio.ping, studio.handles, story.validate,
session.new, and render toolstool_runs contains successful studio.ping and studio.handles callsUse a repo-local GOCACHE in sandboxed environments. Remove .cache/ before
committing unless it is already ignored.
Use --tool and a JSON object in --tool-args:
GOCACHE=$PWD/.cache/go-build go run ./cmd/kitsoki mcp-test \
--stories-dir ./stories \
--tool story.validate \
--tool-args '{"dir":"stories/bugfix"}'Other useful calls:
# read-only server shape, useful for meta-mode/Q&A surface checks
GOCACHE=$PWD/.cache/go-build go run ./cmd/kitsoki mcp-test --read-only
# workspace-bound authoring tools
GOCACHE=$PWD/.cache/go-build go run ./cmd/kitsoki mcp-test \
--workspace stories/bugfix \
--tool story.graph \
--tool-args '{}'
# point at a built binary instead of go run's current executable
go build -o /tmp/kitsoki-mcp-test ./cmd/kitsoki
/tmp/kitsoki-mcp-test mcp-test --server-command /tmp/kitsoki-mcp-test --stories-dir ./storiesmcp-test defaults to spawning its current executable with generated mcp
args. Use repeated --server-arg flags only when the default generated server
args are not appropriate; they replace the generated mcp argument list.
The default smoke is no-LLM:
mcp-test only initializes, lists tools, and calls deterministic toolskitsoki mcp defaults driving sessions to harness:replaysession.new with harness:"live" unless the user explicitly asks
for a live integration testFor changes in the CLI wrapper:
GOCACHE=$PWD/.cache/go-build go test ./cmd/kitsoki -run 'TestMCP|TestRunStudioMCPTest|TestCLI_TopLevelHelp'For studio server/tool behavior:
GOCACHE=$PWD/.cache/go-build go test ./internal/mcp/studioIf go test ./cmd/kitsoki fails on sandboxed runs with ~/.kitsoki writes or
Unix socket bind errors, treat that as unrelated unless the touched code is in
those areas. Keep verification focused and report the sandbox blocker.
mcp-test: connect: the child process did not initialize as an MCP server.
Run with a longer --timeout, check the child stderr, and verify the server
args start with mcp.tools: inspect registration in internal/mcp/studio/server.go
and the relevant register*Tools method."is_error": true: read the text/structured content in the
JSON report; studio tools return typed error payloads such as NO_WORKSPACE,
BAD_REQUEST, or UNKNOWN_HANDLE.story.* path surprises: pass --stories-dir ./stories for @kitsoki/<name>
resolution and pass explicit dir or --workspace when testing workspace
tools.render.tui before render.tui_png or
render.web; render.web may degrade when no browser-capable host is wired.Use visual MCP when the claim is about what a real operator can see or point at in the web surface. For Slidey deck QA, the high-signal path is:
Open a no-LLM/replay session with the story cassette or flow seed.
Drive to the rendered deck or review state.
Call visual.open with kind:"web" and a query that deep-links the
single-page app route:
{
"kind": "web",
"session_id": "<session>",
"query": {
"route": "/s/<session>/chat",
"visual_annotate": "1"
}
}Call visual.observe and verify regions include the relevant surface:
media, deck, and annotation for Slidey deck annotation work.
If visual.act is involved, verify the action is executable through the
returned semantic handles. Treat non-actionable semantic text as an MCP/UI
bug, not as a user workaround.
Use a local DB for repeatable command-line MCP visual smoke when the shared DB is read-only:
GOCACHE=/private/tmp/kitsoki-go-cache go run ./cmd/kitsoki mcp-test \
--stories-dir ./stories \
--timeout 20s \
--server-arg mcp \
--server-arg --stories-dir --server-arg ./stories \
--server-arg --db --server-arg .artifacts/visual-mcp-smoke/sessions.dbSlidey-specific traps:
visual.open must capture the session route, not just the runstatus observer
landing page.visual_annotate=1 or the specific media handle.stories/slidey-edit/baked/. If an isolated worktree shows a missing
deck.html, check whether the main checkout has the ignored artifact before
changing tracked story logic.map[...], add a string world key such as scene_json and
test the Starlark output.You cannot check on a job another connection/process is driving via a second
session.status/studio.handles call:
session.drive), andkitsoki mcp process can't
see another's handles.The studio SERVER is NOT the bottleneck — it's provably concurrent (guard test
internal/mcp/studio/session_concurrent_readonly_test.go; ticket
2026-06-25T121622Z-… is wontfix). So don't go hunting for a server-side lock.
Instead read the trace from disk: kitsoki trace status <trace|id> [--json] —
one-shot, cross-process, prints {state, turn, status, last_error, cost, idle}
and flags ⚠ STALLED. This is the supported way to watch a live MCP-driven run.
Model selection is a session.new {profile} parameter, not a story edit: a
profile that pins a model (e.g. codex-native → gpt-5.5, synthetic-claude →
GLM) SUPERSEDES the story agent-def model: (internal/host/agents.go). The bare
codex profile pins nothing and falls back to the agent-def — that's the trap.
Before committing, run git diff --check and confirm only intended files are
staged. Leave unrelated untracked files alone.
1f4abf0
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.