cowork-qa-mcp
Click on "Install 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., "@cowork-qa-mcpstart a session to find the cheapest MacBook Pro on apple.com"
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.
cowork-qa-mcp

A Model Context Protocol server that gives an LLM a real Chromium browser, records every action it takes toward a stated goal, and hands back a structured trace so the LLM (or a second LLM) can decide whether the goal was actually achieved.
Built on Playwright. Five tools, one binary, no cloud dependency.
Why
Most browser-tool MCP servers are stateless — the LLM clicks, gets HTML back, repeats. There's no record of what happened, no way to grade the run after the fact, and no goal context.
cowork-qa-mcp flips that:
Every session starts with a goal in plain English.
Every action (
goto,click,fill,press,eval) is recorded with timestamps, the URL after, and the page's aria-snapshot.When the session ends, a JSON trace is persisted to disk and exposed via a single
qa_get_tracecall.
The orchestrating LLM can then reason over the trace ("did this run actually fulfill the goal, or did it click the wrong button?") instead of trusting the run-time chatter.
Related MCP server: MCP Playwright Server
Tools
Tool | What it does |
| Open a fresh tab, optional starting URL, return a session id |
| Run one of: |
| Return current URL + full aria-snapshot of the page |
| Close the tab, persist the trace to disk, return the file path |
| Return the goal, every step, final URL, and final aria-snapshot — formatted for an LLM to read |
Install
Requires Node 20+. The package is on npm — no clone needed.
# Try it once, no install
npx cowork-qa-mcp
# Or install globally
npm install -g cowork-qa-mcpThe first install pulls Chromium via Playwright's postinstall (~150 MB).
Wire into your MCP-compatible client
Claude Code
claude mcp add cowork-qa --scope user -- npx -y cowork-qa-mcpTo watch the browser instead of running headless:
claude mcp add cowork-qa --scope user \
-e COWORK_QA_HEADED=1 \
-- npx -y cowork-qa-mcpVerify with /mcp inside a fresh claude session — you should see cowork-qa ✓ connected and 5 tools.
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"cowork-qa": {
"command": "npx",
"args": ["-y", "cowork-qa-mcp"]
}
}
}Cursor / Windsurf / other MCP clients
Any client that speaks the MCP stdio transport works. Point its server config at npx -y cowork-qa-mcp.
From source (for development)
git clone https://github.com/inSideos-designs/cowork-qa-mcp.git
cd cowork-qa-mcp
npm install
npm run build
node dist/server.js # stdio server, expects an MCP clientMCP Registry
This server is also published on the official MCP Server Registry as io.github.inSideos-designs/cowork-qa — clients that auto-discover from the registry will find it without any manual config.
Environment variables
Variable | Default | Purpose |
| unset (headless) | Set to |
|
| Directory where |
Usage example
A typical end-to-end loop the orchestrating LLM runs:
session_start({ goal: "find the cheapest 14\" MacBook Pro on apple.com",
url: "https://www.apple.com/shop/buy-mac/macbook-pro" })
→ { session_id: "abc-123" }
session_observe({ session_id: "abc-123" })
→ URL + aria-snapshot
session_act({ session_id: "abc-123", action: "click",
target: "button:has-text('Continue')" })
# ... more acts / observes ...
session_end({ session_id: "abc-123" })
→ { steps: 7, trace_path: "~/.cowork-qa/abc-123.json" }
qa_get_trace({ session_id: "abc-123" })
→ Goal: ...
Steps (7 total): ...
Final URL: ...
Final aria-snapshot: ...Trace format
Each trace is a JSON file:
{
"session_id": "abc-123",
"goal": "...",
"steps": [
{
"t": 142,
"action": "click",
"args": { "target": "...", "value": null },
"url_after": "...",
"aria_after": "..."
}
],
"final": { "url": "...", "aria": "..." },
"path": "/.../abc-123.json"
}Limitations / known quirks
session_observecalls don't show up in the trace's step count — onlysession_actcalls do. The final aria-snapshot is captured atsession_end.evalruns the JS expression but doesn't return the value to the caller — only side effects on the page are observable.One Chromium process is shared across all sessions in a server instance; each session gets its own context (cookies, etc. are isolated).
Selectors are passed straight to Playwright. CSS, text-selectors (
button:has-text("Send")), androle=selectors all work.
License
MIT — see LICENSE.
Contributing
PRs welcome. Keep it small: this is meant to stay a thin, auditable server.
Available Tools
5 toolsqa_get_traceA
Return the full recorded trace (goal, every step, final URL, final aria-snapshot) so the calling LLM can judge whether the goal was achieved. Call session_end first.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavior disclosure. It discloses that the tool returns the full trace and its constituent parts, which is useful. However, it doesn't state whether the trace persists after being read, whether it can be called multiple times, whether the session must be ended already, or error behavior (e.g., calling before a session exists). It's a read operation, which is fairly clear, but lacks depth beyond what's stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero wasted words. It front-loads the primary action, enumerates the return contents, states the purpose, and adds the key precondition. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with one parameter and no output schema. The description adequately covers return contents (goal, steps, final URL, aria-snapshot) and the prerequisite (session_end first). It could mention the interaction with session_end's own behavior and replayability, but for a single-param read tool the description is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the session_id parameter. The description mentions 'session_end first' and the tool name references 'trace,' but the description never explicitly states that session_id identifies which session's trace to retrieve. The parameter's role is only implied by context, not clearly explained in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb+resource ('Return the full recorded trace') with a precise scope enumerated: goal, every step, final URL, final aria-snapshot. It also names the purpose ('so the calling LLM can judge whether the goal was achieved'), which clearly distinguishes it from the sibling session_start/act/observe/end tools that operate during the session rather than reading back its record.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: it's a read-back/reporting tool used after a session, and it explicitly instructs 'Call session_end first.' While it doesn't enumerate exclusions or alternatives, the precondition (session_end first) and the clear purpose effectively guide when to use it. It could name alternatives explicitly but the sibling set makes the distinction obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_actA
Perform a browser action in a session: goto | click | fill | press | eval.
| Name | Required | Description | Default |
|---|---|---|---|
| value | No | Value for fill. | |
| action | Yes | ||
| target | No | Selector for click/fill, URL for goto, key for press, JS expression for eval. | |
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations provided, so the description carries the disclosure burden. The description states it performs a browser action, which implies side effects (navigation, DOM changes), but it does not disclose potential security implications of 'eval' (arbitrary JS execution), rate limits, or what happens on invalid actions or missing sessions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, zero waste, and the action enum is embedded directly in the description, making it instantly scannable. Front-loaded with the verb+resource and immediately enumerating the valid actions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a polymorphic tool with 4 parameters and no annotations or output schema, so it demands more documentation. The description resolves the target polymorphism well but leaves ambiguity about which actions require 'value' versus 'target', error behaviors, and return format. Reasonable for a simple action dispatcher but notable gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%, but the description compensates by clarifying the polymorphic 'target' parameter meaning across action types (selector for click/fill, URL for goto, key for press, JS expression for eval). This adds meaningful semantics for the most ambiguous polymorphic parameter. However, 'value' and 'session_id' semantics are left to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Perform a browser action in a session') and enumerates the supported action types (goto/click/fill/press/eval). It clearly communicates the tool's scope as a browser action executor within a session context, distinguishing it from siblings that start/observe/end sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by listing the action verbs, and the sibling tools (session_start/observe/end) establish the session lifecycle context. However, it does not explicitly state when to use this tool versus alternatives, nor does it mention prerequisites like requiring an active session before executing actions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_endC
Close the session, persist the trace to disk, and return the path.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It does disclose three side effects: closing the session, persisting a trace to disk (a side effect with external consequences), and returning the path. However, it doesn't note that this is likely destructive/terminal (session cannot be resumed after), disk persistence implications, or whether closing is irreversible. Moderate disclosure but incomplete for a state-changing operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One efficient sentence that front-loads the primary action and lists secondary effects compactly. No wasted words. Slightly better than a bare minimum given it packs three behavioral aspects into a single concise clause, though additional parameter guidance could have been added without excessive bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a state-changing terminal tool with no output schema and no annotations, the description is thin. It explains the return value conceptually (the path) but not the format, doesn't address reversibility or whether the session becomes unusable, and gives no parameter semantics. Given it's a terminal lifecycle operation among several session tools, more guidance on ordering and implications is warranted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and there's a single required parameter session_id with no type/format detail beyond 'string' in the schema. The description provides zero parameter information—it doesn't explain what session_id identifies, where to obtain it, or any constraints. Since coverage is 0% (below the 50% threshold), the description must compensate, and it fails to do so.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Close the session, persist the trace to disk, and return the path.' It describes a specific end-of-session action that distinguishes it functionally from siblings (session_start, session_act) though it doesn't explicitly name them. The three-part behavior (close, persist, return path) is specific and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool vs alternatives. With sibling tools like session_act and session_observe present, there's no 'when not to use' or comparison. The description implies it's used at the end of a session lifecycle, but this is implicit rather than stated. No exclusions or ordering requirements (e.g., must session_act first) are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_observeC
Return the current URL and aria-snapshot of the session's page.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states what is returned (URL and aria-snapshot) but doesn't clarify whether this is a passive read operation or whether it might alter session state. For an observation tool, the read-only nature is implied by the name but never explicitly stated given annotations are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero wasted words. It front-loads the action ('Return') and specifies both outputs clearly. The terseness is appropriate for a simple observation tool, though a touch more context about the aria-snapshot format could justify extending it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, no output schema, and zero schema description coverage, the description is thin. It names two outputs (URL and aria-snapshot) but doesn't describe the format of the aria-snapshot, whether both always come together, or what happens if the session is inactive/invalid. Given siblings include session_act (which presumably mutates), this read tool would benefit from clarifying its non-mutating role.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter `session_id` is a plain string with no schema description coverage (0%). The tool description doesn't mention this parameter at all, so the agent must infer that session_id refers to a session previously created by session_start. Since all sibling tools likely use the same session_id pattern, some inference is possible, but the description provides zero compensation for the documented schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the current URL and aria-snapshot of the session's page. It uses a specific verb ('Return') with a clear resource ('current URL and aria-snapshot'). While it doesn't explicitly differentiate from siblings, the 'observe' name and description of returning page state clearly distinguish it from session_start (initialize), session_act (perform action), session_end (terminate), and qa_get_trace.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool vs alternatives. It doesn't state this is the read/inspection tool for a session's current state, nor does it mention any prerequisites (e.g., session must be active, started via session_start). There's no context about typical usage patterns such as observing before deciding an action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_startB
Open a fresh browser tab and start recording a goal-driven session.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Optional starting URL. | |
| goal | Yes | Plain-English goal the agent will try to accomplish. |
TDQS
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 tool 'opens a fresh browser tab' and 'starts recording' — some behavioral disclosure — but doesn't say what happens to an existing session, whether the URL is navigated immediately, what start/recording side effects occur, or whether this is destructive to prior state. For a stateful action with no annotation coverage, this is a notable gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single concise sentence, front-loaded with the verb and purpose. Zero wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a stateful session-initiation tool with no annotations and no output schema, the description is somewhat thin. It doesn't explain what the agent gains from the 'recording' (observations? trace?), what the expected return indicates, or how session state carries to siblings. But it's a relatively simple 2-param tool that establishes an entry point; adequate overall, with room to improve on session lifecycle expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the schema already documents both parameters. The description's 'goal-driven' and 'fresh browser tab' wording adds minimal context (e.g., implying URL is the initial page, goal is the objective), but doesn't meaningfully exceed what the schema describes. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description has a clear verb+resource (open a fresh browser tab, start recording) with a specific purpose: goal-driven session. However, it doesn't distinguish itself from session_act/session_observe siblings, though those are clearly different actions (acting and observing within a session, not starting one). The 'goal-driven' qualifier adds useful scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is the entry point for a session ('start recording'), and the required 'goal' parameter signals that the agent should first define a goal. However, it provides no explicit when-to-use guidance or alternatives, and doesn't mention session_end as the counterpart or any prerequisites.
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.
5 tool updates
v0.1.1- First observed
qa_get_trace - First observed
session_act - First observed
session_end - First observed
session_observe - First observed
session_start
TDQS
Scored across 5 tools
Each tool targets a distinct phase of the session lifecycle: start, act, observe, end, and trace retrieval. There is no overlap in purpose, and the descriptions clearly delineate which tool to use at each point in a workflow.
The session_* tools follow a consistent verb_noun pattern (session_start, session_act, session_observe, session_end). qa_get_trace is a minor deviation from the prefix convention, though it's clearly thematic and still readable.
Five tools is well-scoped for a QA session recorder. Each tool earns its place: lifecycle management (start/end), actions (act), observation (observe), and trace retrieval (qa_get_trace). No redundancy or unnecessary tools.
The surface covers the full session lifecycle: start a session, perform actions, observe state, end the session, and retrieve the trace for evaluation. There are no dead ends—qa_get_trace even instructs the caller to call session_end first, closing the loop.
Maintenance
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
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server for Mint — AI-powered QA that runs your app in a real browser on every PR.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Control plane for autonomous software labor. Agents claim objectives over MCP with audit trail.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA Playwright-based MCP server that exposes a live browser as a traceable, inspectable, debuggable and controllable execution environment for AI agents.3,71357-
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI-powered browser automation, web scraping, and testing using Playwright across Chromium, Firefox, and WebKit. It allows users to perform actions like navigation, clicking, typing, and taking screenshots through natural language interfaces.8MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that provides browser automation using Playwright, enabling LLMs to interact with web pages through structured accessibility snapshots.-
- AlicenseNot gradedqualityCmaintenanceAn MCP server that provides structured control of a Playwright browser for QA, scraping, diagnostics, and reproducible browser workflows.6,282MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Cultistsid/cowork-qa-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server