sudo-meow-mcp

sudo-meow-mcp

MCP server that exposes tools to read and control the state machine of a Tauri desktop app, enabling autonomous QA exploration and testing.

Category
Visit Server

README

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.

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.md
  • App → 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) — see docs/DEBUG_SERVER.md and docs/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.ts is 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's mcp_servers) — those only reach servers on a public URL, and this one is deliberately stdio-only/local (see docs/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.ts force-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 qa

Writes 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
get_current_state — GET /__debug/state
get_available_transitions — GET /__debug/state/transitions
trigger_event eventName: string, payload?: object POST /__debug/state/trigger
get_state_history limit?: number GET /__debug/state/history
read_console_logs limit?: number GET /__debug/logs

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 payload
  • pomodoro.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.js

Use 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-test

Spawns 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.js

Stopping 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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured