Skip to main content
Glama
alicefarron
by alicefarron

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

Available Tools

5 tools
get_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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description provides behavioral insights by explaining that the output includes organic weighted-graph options, forceTransition-acceptable states, and valid Pomodoro events, and notes that CatStateMachine has no transition validation. However, it does not disclose side effects, auth requirements, or whether the tool is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence but is somewhat long and uses punctuation that may reduce clarity. It contains useful information but could be restructured for better readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters or output schema, the description covers the main return types but lacks details on edge cases, prerequisites, or references to external documentation for deeper context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With no parameters, the description adds value by explaining what the output contains (three categories of transitions). However, it does not describe the return format or structure, which would help the agent interpret results.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns transitions reachable from the current state, listing three specific categories. This distinguishes it from sibling tools like get_current_state (which returns state) and trigger_event (which triggers an action).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied: the tool is for exploring transitions before triggering events or force transitions. However, no explicit guidance on when to use versus alternatives, and no mention of prerequisites or when not to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description alone must convey safety and behavior. It correctly implies a read-only snapshot (non-destructive) and notes the requirement for a running dev instance. However, it does not disclose what happens if the instance is not running or any other side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single informative sentence, front-loaded with 'Snapshot'. The parenthetical adds necessary context. It is concise without missing key points, though it could be slightly more structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and low complexity, the description covers the tool's purpose and a crucial prerequisite. However, it does not outline what the snapshot contains beyond naming 'state machine and Pomodoro timer', leaving the output format unclear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description adds no parameter information, but none is needed since schema coverage is 100%.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it provides a snapshot of the state machine and Pomodoro timer from a running dev instance. This specific verb+resource combination distinguishes it from siblings like get_state_history (history) and get_available_transitions (transitions).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions the prerequisite of having 'npm run tauri dev' running, implying the tool only works when a dev instance is active. However, it does not explicitly state when not to use this tool or provide alternatives like 'use get_state_history for past states'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNomax entries to return (most recent); omit for all available

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It reveals the server cap of 50 entries and how the limit parameter interacts, which is good disclosure. However, it does not mention auth needs or other potential side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. Key information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers ordering, server cap, and limit behavior. However, it lacks explanation of the return format, which would be helpful given no output schema. Still, for a simple tool with one optional parameter, it is mostly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds value by explaining that limit trims to the most recent N of whatever the server returns and that omitting it returns all available. This goes beyond the schema's description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns 'last transitions of both machines, interleaved, oldest first', which is specific and distinguishes it from siblings like get_current_state and get_available_transitions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving history and explains the limit behavior, but does not explicitly state when to use this tool versus alternatives or provide exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNomax entries to return (most recent); omit for all available

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description bears full responsibility for behavioral disclosure. It mentions the server cap of 200 entries and that limit further trims, which is helpful. However, it omits details like expected response format, error handling for missing logs, or whether the tool is read-only. This leaves gaps for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two short sentences. The first sentence states the core purpose, the second details the parameter behavior and server constraint. No unnecessary words. Information is front-loaded and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple nature (one optional param, no output schema), the description covers the essential behavior. However, it lacks information about return format (e.g., array of strings) and edge cases (e.g., no logs yet, server unavailable). This leaves some ambiguity for an agent invoking the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a single parameter. The description adds meaningful context beyond the schema by noting the debug server caps results at 200 and that limit works on top of that cap. This clarifies the boundary condition, adding value over the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it reads the last console.log/warn/error calls from the app window since it loaded. The verb 'read' and the resource 'console logs' are explicit. It naturally distinguishes from sibling tools (state machine operations) by domain.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving console output, which is distinct from sibling tools focused on state transitions. It provides clear context but lacks explicit when-not-to-use or alternative tool names. However, the domain difference is sufficient for an agent to differentiate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
payloadNoevent-specific payload, if the event needs one
eventNameYese.g. "cat.forceTransition", "pomodoro.start"

TDQS

A4.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description does not fully cover behavioral aspects like side effects or idempotency. It mentions error handling but lacks detail on mutation or safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with purpose, no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema, but the description clearly explains usage and error behavior. Missing return value details, but acceptable for a command-like tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% but the description adds specific valid event names and payload structures, greatly enriching parameter understanding beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as sending events to a state machine, lists valid event names, and distinguishes itself from siblings by explicitly referencing get_available_transitions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance to call get_available_transitions first to check valid transitions, and notes that invalid inputs will be rejected with clear errors.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.0
    • First observedget_available_transitions
    • First observedget_current_state
    • First observedget_state_history
    • First observedread_console_logs
    • First observedtrigger_event

TDQS

A4.2/5.0
Disambiguation5/5

Each tool has a distinct purpose: state snapshot, transitions, event triggering, history, and console logs. No overlap or ambiguity.

Naming Consistency5/5

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

Tool Count5/5

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.

Completeness4/5

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

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    B
    maintenance
    Enables 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.
    14
    1,310
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Gives 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.
    128
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    An 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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alicefarron/sudo-meow-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server