macbeth (wende/macbeth) is an MCP server listed on the M8ven Trust Index. It scores 60 out of 100, grade C. It declares 38 tools. No publisher has claimed this listing.

C
Caution
60/100

macbeth

Playwright for macOS native apps

Caution. Specific findings reduced this grade. They are listed on the page. Grades reflect the full trust pyramid: code, verification depth, and reputation. New projects cap at C until adoption is earned.

How we verified

⚡ Live Monitored: not connected

Verified is a snapshot. Live keeps it current, and builds your track record.

⚡ Connect GitHub → continuous verification on every pushwhy connect →

Who stands behind it

wende

Source: Glama · also listed on github_repo_search

Is this your MCP?

Claim it to get a verified publisher badge, a free copy of our full audit findings, and direct contact for any high-priority issues we find. Or connect your repo for our deepest verification, Live Monitored: read-only, revoke anytime. What we access →

Install from

The grade above is for the source repository. Registries can serve a different version, so we mark the ones we were not able to read.

// key findings
⚠️
Tool annotations don’t match behaviour
1 read-only tool performs write/delete/exec — list_shortcuts (line 581: spawnSync("shortcuts", ["list"], { encoding: "utf8", timeout: 10_000 }))
⚠️
Tool descriptions don’t match what handlers do
1 tool describes read intent but its handler mutates — list_shortcuts (line 581: spawnSync("shortcuts", ["list"], { encoding: "utf8", timeout: 10_000 }))
No credential exfiltration, no sensitive file access, no obfuscation
Static analysis found nothing flowing your secrets to unexpected places.
Open source with a license and README
Anyone can audit the code, the license is declared, and the publisher documents what it does.
🔐
You'll be asked for 2 credentials: GH_TOKEN, GITHUB_TOKEN
These are read from process.env at runtime. Make sure you trust where they’ll be sent.
// tools this server exposes27 tools

These names and descriptions are the publisher's own, read from the source code. We print them as written. Our assessment is the findings above, not this list.

list_apps

List running macOS apps, split into the ones that are currently reachable through the Accessibility API and the ones that are running but will fail to connect (launchers, helper processes, apps that never implement AX). Blocked entries carry the AX error code, what it means, and what to do instead.

list_daemon_methods

List every JSON-RPC method registered by the daemon. Used to verify that daemon capabilities are exposed through MCP.

begin_activity

Turn on the on-screen interaction indicator before you control the computer through some OTHER tool (a different MCP server, computer-use, a shell script) that Macbeth cannot see. Macbeth's own click/fill/press_key/run_applescript tools already show the indicator, so you do NOT need this for them. R

end_activity

End an interaction-indicator scope started by begin_activity. Pass the token that begin_activity returned. Safe to skip if the client disconnects; the daemon expires abandoned scopes on its own.

connect_app

OPTIONAL preflight. Every app-taking tool (query_tree, click, fill, screenshot, ...) connects on its own, so you do NOT need to call this first. Call it to (a) check an app is reachable through Accessibility before driving it, (b) see exactly how a fuzzy name resolved, or (c) warm up an Electron app

query_tree

Get an app's accessibility tree, including its menu hierarchy. Use this first; it connects automatically, so a separate connect_app or list_menu_bar call is unnecessary. If Chromium web content is empty, the result explains available screenshot/OCR/menu/keyboard fallbacks.

list_windows
click

Click a UI element. Auto-waits for the element to appear. On Electron/web content, the default 'auto' strategy tries AXPress (and adjacent nodes) then falls back to a synthetic mouse click; override with 'mouse' for canvas-heavy UIs or 'ax' to force a press. Mouse clicks briefly activate the target

fill

Set the text value of a field. Auto-waits for the element to appear. On Electron/web content, the default 'auto' strategy writes the AX value then synthesizes keystrokes (so frameworks like React see the input); override with 'keyboard' to force typing or 'ax' to force a direct value write.

wait_for

Wait for a UI condition. Conditions: 'exists' (default, wait for element to appear), 'value_equals' (wait for specific value), 'value_changes' (wait for any value change), 'enabled' (wait for element to become enabled).

press_key

WARNING: This tool steals focus — it activates the target app window before sending input. Use as a last resort when click/fill cannot achieve the goal (e.g. keyboard shortcuts, arrow-key navigation). Prefer "fill" for text entry and "click" for buttons. Key names: "return", "tab", "escape", "a"-"z"

press_keys

WARNING: This tool steals focus — it activates the target app window before sending input. Use as a last resort when click/fill cannot achieve the goal. Prefer "fill" for text entry and "click" for buttons. Sends a sequence of keyboard inputs in one call. Each step accepts either `key` plus optional

screenshot

Capture the default visible app window, or select a window returned by list_windows. Explicit selection does not activate the window or switch Spaces; some apps may provide blank content for off-Space windows.

extract_text

Extract text from an app window using OCR (Vision framework). Bridges accessibility gaps in apps with poor AX support. Pass either an app name to capture + OCR, or base64 PNG data to OCR directly.

get_element

Find a specific UI element and return its properties (role, title, value, enabled, focused).

dump_attributes

Dump all accessibility attributes for a previously resolved element handle.

pin_handle

Pin an element handle to prevent it from expiring (default TTL is 5 minutes). Useful for long-running workflows where you need a stable reference to a panel or control.

unpin_handle

Unpin a previously pinned handle, resuming normal TTL expiry.

read_form

Read all form-like controls (text fields, sliders, checkboxes, popups, etc.) from a subtree. Returns each control's label, current value, type, editability, and handle. Use this to inspect panel contents without parsing the full tree.

select_menu_item

Select a native menu bar item by path (e.g. ["Track", "New Audio Track"]). Uses the Accessibility API directly, accepts a fuzzy app name or PID, and does not steal focus.

list_menu_bar

Return a menu-only Accessibility view. query_tree already includes menus, so use this only when that menu section was omitted, truncated, or a compact menu-only result is needed.

run_applescript
list_shortcuts

List all Apple Shortcuts available on this Mac.

run_shortcut

Run an Apple Shortcut by name. Shortcuts are system-level automations, not tied to any specific app.

list_skills

List available macbeth skills. Each skill has instructions (SKILL.md) and optional runnable scripts.

load_skill

Load a skill by name. Returns the SKILL.md instructions and lists any runnable scripts.

run_skill_script

Run a script from a skill's scripts/ directory. Scripts are .mjs files that automate specific workflows using macbeth.

// environment variables
To run this server yourself, you supply these values. They go in your own MCP client configuration and stay on your machine. The secret label means the value is sensitive, not that the server mishandles it.
🔐 secretGH_TOKEN
🔐 secretGITHUB_TOKEN
configMACBETH_DAEMON_PATH
configMACBETH_UPDATE_REPO
configVITE_BASE_PATH
// quality suggestions

Tool annotations

10/38 tools have annotations

Add readOnlyHint or destructiveHint annotations to every tool so hosts can warn users before invoking.

All four hints declared on every tool

38/38 tools missing one or more hints — list_apps (missing: destructiveHint, idempotentHint, openWorldHint); list_daemon_methods (missing: destructiveHint, idempotentHint, openWorldHint); begin_activity (missing: readOnlyHint, destructiveHint, idempotentHint, openWorldHint), +35 more. OpenAI's directory rejects tools where any of the four hints are missing or non-boolean.

For every tool, set all four hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) to explicit true/false values that match the handler’s actual behaviour.

Tool annotations match behaviour

1 read-only tool performs write/delete/exec — list_shortcuts (line 581: spawnSync("shortcuts", ["list"], { encoding: "utf8", timeout: 10_000 }))

Either remove the readOnlyHint:true annotation, or remove the write/delete call from the tool handler.

Descriptions match behaviour

1 tool describes read intent but its handler mutates — list_shortcuts (line 581: spawnSync("shortcuts", ["list"], { encoding: "utf8", timeout: 10_000 }))

Rename the tool, rewrite the description, or move the side-effect into a separate clearly-named tool.

Tool inputs are validated

21/38 tool handlers declare input schemas (55%)

Declare an inputSchema with zod/joi/yup on every tool definition.

Tool handlers catch errors

Only 9/38 tool handlers wrap calls in try/catch (24%)

Wrap each tool handler body in try/catch and return a structured error response.

Tool test coverage

28/38 tools referenced in tests (74%)

Write tests that reference each tool by name so every tool has at least one test.

Tool description accuracy

list_shortcuts: description implies read-only but handler writes/deletes/executes

Update tool descriptions to accurately reflect all capabilities — especially write, delete, or execute operations.

Claim the listing to review these findings one by one and send us a correction where you disagree, straight to the team. Claiming also means we tell you when the grade moves, and reach you first if we find anything urgent.

// full audit trail
The findings above are the summary. The full trail, every check we ran, each deduction, the network hosts observed and the dependency advisories, goes to verified publishers, along with an alert whenever a new one lands. Verified publishers can also review each finding and dispute it in one click. Publisher corrections have sharpened several of our checks this month, because the maintainer knows the codebase better than any scanner.
// improvement guidance — verified publishers only
We have 8 concrete improvements we can share with the publisher of this MCP. Each comes with specific guidance to raise the trust score.
// embed badge in your README
[![M8ven Verified](https://m8ven.ai/badge/mcp/wende/macbeth?variant=verified)](https://m8ven.ai/mcp/wende/macbeth)
Shows verification status without the grade. Want the grade badge instead? Remove ?variant=verified from the URL.
commit: 03aaaa35e95a0f7680adc095b3a5882412fa7a79
code hash: 0bd4e4b7969b6ee4451d1e565c7faba8c444e002d5e6e5900d9c7898f2b394f1
view raw JSON →
Check MCPs from inside your assistant
Tool Check · MCP

Vetting this one by hand? Tool Check is an MCP that scores other MCPs. Add it once and ask Claude, ChatGPT, or any MCP client to grade a server, surface CVEs, check the publisher, and suggest safer alternatives — before you install.

https://m8ven.ai/api/mcp/tool-check
check_toolsearch_toolscompare_toolsrecommend_alternativescheck_publisherreport_concern
How to add it →Free · no account needed · works in any MCP client