sudo-meow-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sudo-meow-mcpCheck current state and available transitions"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
sudo-meow-mcp
MCP server + autonomous QA agent for sudo meow's state machine (a Tauri desktop app) — the agent explores the app's actual running state machine over MCP and decides for itself what to test.
Why this exists
Most test suites encode test cases someone already thought of. This instead gives an LLM agent a small set of tools (read current state, list what transitions are valid from here, fire an event, read history/logs) and a systematic-exploration instruction, and lets it drive the app's real state machine — through a live debug bridge, not mocks — deciding what to probe next based on what it just observed. Coverage of "every state got visited" is enforced by the harness independently of the agent, so the result is trustworthy even when the agent (especially a small local model) doesn't behave perfectly.
Related MCP server: tauri-plugin-mcp
Architecture
sudo meow (Tauri app, dev mode)
Vite dev server ── vite-debug-plugin.ts ── HTTP /__debug/* (localhost:1420)
│
▼
sudo-meow-mcp (this repo)
src/httpClient.ts + src/index.ts
MCP server, stdio transport
│
▼
agent/run-qa.ts (MCP client)
tool-calling loop ◄──► Ollama (local LLM)
│
▼
test-report.mdApp → debug bridge: sudo-meow's Vite dev server exposes the cat's state machine and Pomodoro timer over a dev-only HTTP API (
/__debug/state,/state/transitions,/state/trigger,/state/history,/logs) — seedocs/DEBUG_SERVER.mdanddocs/STATE_MACHINE.md, copied here from that repo since this one directly depends on that contract.Debug bridge → MCP server:
src/wraps those 5 endpoints as 5 MCP tools (get_current_state,get_available_transitions,trigger_event,get_state_history,read_console_logs), served over stdio — the standard transport for a locally-spawned MCP server.MCP server → agent:
agent/run-qa.tsis itself an MCP client (spawns the server over stdio, same as Claude Desktop would) and a tool-calling loop against Ollama. Not using any cloud API's remote-MCP connector (e.g. Anthropic'smcp_servers) — those only reach servers on a public URL, and this one is deliberately stdio-only/local (seedocs/DEBUG_SERVER.md).Coverage guarantee, independent of the agent: the system prompt instructs BFS exploration, but after the agent's own loop ends, a deterministic pass in
agent/bookkeeping.ts+run-qa.tsforce-visits any state the agent didn't reach, using the same tool calls. Two mechanical anomaly checks (does a forced transition land where requested; did a new warning/error log line appear) are computed from the raw tool-call transcript, not from asking the agent to self-report.
Run it
# 1. In the sudo-meow app repo (separate clone):
npm install && npm run tauri dev # leave running
# 2. Ollama, once:
brew install ollama # or see https://ollama.com
ollama pull llama3.1 # ~4.7 GB; any tool-calling-capable model works
# 3. This repo:
npm install
npm run build
npm run qaWrites test-report.md to this repo's root. Configurable via .env (copy .env.example) or env vars: QA_MAX_STEPS (default 200), QA_OLLAMA_MODEL (default llama3.1), OLLAMA_BASE_URL, SUDO_MEOW_DEBUG_URL.
On CPU-only local inference, each tool-call round trip can take from a few
seconds to close to a minute depending on the model and prompt length — the
default budget of 200 can take a while. QA_MAX_STEPS=40 or so is enough to
see the agent actually explore before the harness's completion pass takes
over; the checked-in test-report.md was generated that way.
Example finding
From a real run (test-report.md, qwen2.5, 40 tool calls): the coverage table's idle row lists idle itself among its own declared organic edges — impossible per the app's own state graph, which has no self-transitions. Root cause: GET /state/transitions reports transitions for whatever the live state is at that instant but never says which state that was, so the harness infers it from the last snapshot it saw. Real latency between a forced transition and the next tool call is enough for the cat's own clock to have already moved on — the response then gets attributed to the wrong state. Not an app bug; a gap in the debug API's response shape, caught only because the agent was slow enough for the race to matter.
Stack
TypeScript · Tauri 2.x (the app under test) · @modelcontextprotocol/sdk · Ollama (local LLM runtime, native tool-calling)
Reference
MCP tools
Tool | Parameters | Wraps |
| — |
|
| — |
|
|
|
|
|
|
|
|
|
|
limit on the last two is applied client-side — the underlying endpoints
always return everything they have, capped at 50 (history) / 200 (logs)
server-side.
Valid eventNames for trigger_event (call get_available_transitions
first to see what's actually valid from the current state):
cat.forceTransition— payload{ "state": CatState }pomodoro.start— payload{ "minutes"?: number }pomodoro.tick— payload{ "dtSeconds"?: number }pomodoro.resume— no payloadpomodoro.cancel— no payload
Using the MCP server outside this agent
It's a normal stdio MCP server — connect it to Claude Desktop or Claude Code
directly, independent of agent/run-qa.ts.
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json
on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"sudo-meow-debug": {
"command": "node",
"args": ["/absolute/path/to/sudo-meow-mcp/dist/index.js"]
}
}
}Claude Code:
claude mcp add sudo-meow-debug -- node /absolute/path/to/sudo-meow-mcp/dist/index.jsUse an absolute path in both cases — these tools don't run from this
package's directory. Requires npm run build first.
Manual testing without any LLM
npm run smoke-testSpawns the built server over stdio, does the MCP initialize handshake,
lists tools, and calls each of the 5 tools once (including an intentionally
invalid trigger_event, to confirm error handling) — see
scripts/smoke-test.mjs. Or, interactively:
npx @modelcontextprotocol/inspector node dist/index.jsStopping npm run tauri dev and re-running either should make every call
return isError: true with a message pointing at the missing dev server,
not a crash or a hang.
Limitations
Everything here depends on the sudo-meow app running in dev mode — the debug HTTP surface doesn't exist in a built app, by design (see
docs/DEBUG_SERVER.md).Day/night variants of the cat's transition graph aren't exercised — no tool exposes control over the system clock or the app's time-of-day config.
The QA agent's mechanical anomaly detection is intentionally narrow (2 checks) to avoid false positives from the state machine's inherent randomness; see
test-report.md's own "Limitations" section for the specifics of any given run.
Available Tools
5 toolsget_available_transitionsGet available transitionsA
What's reachable from the cat's current state: the organic weighted-graph options, every state forceTransition would accept (unconditionally — CatStateMachine has no transition validation of its own, see docs/STATE_MACHINE.md), and which Pomodoro events are valid from the current phase.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_current_stateGet current stateA
Snapshot of the sudo meow cat's state machine and Pomodoro timer from a running dev instance (requires npm run tauri dev running in the sudo-meow repo).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_state_historyGet state transition historyA
Last transitions of both machines, interleaved, oldest first. The debug server itself caps this at 50 entries; limit (if given) further trims to the most recent N of whatever's returned.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max entries to return (most recent); omit for all available |
read_console_logsRead console logsA
Last console.log/warn/error calls from the app window since it loaded. The debug server itself caps this at 200 entries; limit (if given) further trims to the most recent N of whatever's returned.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | max entries to return (most recent); omit for all available |
trigger_eventTrigger a state machine eventA
Sends an event to the live state machine. Valid eventNames: "cat.forceTransition" (payload: { state: CatState }), "pomodoro.start" (payload?: { minutes }), "pomodoro.tick" (payload?: { dtSeconds }), "pomodoro.resume", "pomodoro.cancel". Call get_available_transitions first to see what's valid from the current state — invalid states/events are rejected with a clear error.
| Name | Required | Description | Default |
|---|---|---|---|
| payload | No | event-specific payload, if the event needs one | |
| eventName | Yes | e.g. "cat.forceTransition", "pomodoro.start" |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
get_available_transitions - First observed
get_current_state - First observed
get_state_history - First observed
read_console_logs - First observed
trigger_event
TDQS
Scored across 5 tools
Each tool has a distinct purpose: state snapshot, transitions, event triggering, history, and console logs. No overlap or ambiguity.
All tool names follow a consistent verb_noun pattern in snake_case (get_current_state, get_available_transitions, trigger_event, get_state_history, read_console_logs).
Five tools is ideal for debugging a state machine and Pomodoro timer, covering reading state, available transitions, event triggering, history, and console logs without unnecessary duplication.
The tool surface covers the main debugging needs (state, transitions, events, history, logs). Minor gaps exist (e.g., no reset or clear functionality), but these are acceptable for a debug server.
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server exposing the Backtest360 engine API as tools for AI agents.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI assistants to automate and test Tauri desktop applications through the Model Context Protocol. It provides tools for app management, UI interaction, and state inspection across multiple platforms without requiring CDP dependencies.143,794 npm1MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that allows AI agents to interact with and debug Tauri applications through screenshots, DOM access, input simulation, and more.3,794 npm113MIT
- AlicenseNot gradedqualityBmaintenanceGives AI agents and MCP clients direct control over native desktop apps, Chrome/Electron browsers, and Android devices with screenshots, OCR, accessibility-based element lookup, input simulation, window management, CDP, and ADB in one local server.141MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that enables AI assistants to build, test, and debug Tauri v2 applications through UI automation (screenshots, clicks, typing, element finding), IPC monitoring, log streaming, and mobile device management.MIT