Skip to main content
Glama
zhuhroscar-tech

safari-mcp-server

English 简体中文

safari-mcp

Control your real Safari.app session on macOS through an MCP server, CLI, or Python library. The project uses Apple's JavaScript for Automation (JXA) to navigate tabs, read pages, run JavaScript, click CSS-selected elements, and fill forms.

This is your existing signed-in browser, not an isolated automation profile. Actions can affect real accounts and pages. Connect only trusted agents and review consequential actions before execution.

Install and permissions

Requires macOS, Safari, and Python 3.10+. pip installs the MCP dependency.

git clone https://github.com/zhuhroscar-tech/safari-mcp.git
cd safari-mcp
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .

Enable both permissions:

  1. Allow the launching terminal/app to control Safari under System Settings → Privacy & Security → Automation when prompted.

  2. In Safari Settings → Advanced, enable Show features for web developers, then select Develop → Allow JavaScript from Apple Events. This is required for page JavaScript operations; tab listing, opening, and closing do not require it.

Related MCP server: Safari MCP Server

Connect an MCP host

For hosts using mcpServers configuration:

{
  "mcpServers": {
    "safari": {
      "command": "/absolute/path/to/safari-mcp/.venv/bin/safari-mcp-server"
    }
  }
}

Replace the path with your installation's executable. The server uses stdio and exposes safari_tabs, safari_open, safari_close, safari_read, safari_js, safari_click, safari_fill, safari_element_exists, and safari_wait_for.

CLI and Python

safari-mcp tabs
safari-mcp open "https://example.com" --new-tab
safari-mcp read --json
safari-mcp read --window 1 --tab 1

Targeted commands default to the frontmost window's current tab. Window and tab indices are one-based; use --help for supported targeting flags.

from safari_mcp.core import list_tabs, read_page

print(list_tabs())
page = read_page()
print(page.title, page.text[:100])

Boundaries

This is DOM automation, not screenshot or coordinate-based interaction. There is no sandbox or incognito isolation, and no Linux/Windows support. The wrapper has no telemetry or separate network client, but browser navigation and page actions can send network requests and change account state. Page content passed to an agent is subject to that host's data handling.

Preview and development

Example output · Demo video

python -m pip install -e ".[dev]"
python -m pytest -v
# Optional: real Safari; requires permissions and an open browser
python tests/e2e_mcp_roundtrip.py

CI tests mocked Safari interaction and packaging; it does not establish live Safari behavior. API implementation · MIT license

Available Tools

9 tools
safari_clickA

Click the first element matching a CSS selector in a Safari tab. Returns found=False (not an error) if nothing matched the selector.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
windowNo
selectorYes

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It explicitly mentions that a missing match returns found=False (not an error), which is a useful behavioral trait. However, it does not disclose the success return value, behavior when multiple elements match (only first is stated), or any side effects. This is partial disclosure but adds some value.

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 concise and well-structured: two sentences that lead with the purpose and add a key behavioral note. There is no fluff or redundancy, and the most important information is front-loaded.

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?

The lack of an output schema and annotations means the description should cover return values and parameter semantics. It does explain the not-found case, but omits the success return value and any detail about tab/window parameters. For a simple tool, this is adequate but leaves clear gaps that an agent might need, such as what to expect on success.

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

Parameters2/5

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

Schema coverage is 0%, so the description must compensate. It implicitly explains 'selector' as a CSS selector, but does not clarify the 'tab' and 'window' parameters—what they mean, whether they are indices, or their default behavior. Two of three parameters remain effectively undocumented, leaving significant ambiguity.

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 action ('Click'), the resource ('element in a Safari tab'), and the selection method ('CSS selector'). It also differentiates from siblings by specifying the 'first element' behavior and the not-found case. This is a specific, unambiguous purpose that any agent can understand without ambiguity.

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 provides clear context for when to use the tool: when you need to click an element in a Safari tab using a CSS selector. It does not explicitly mention alternatives or when not to use it, but the context is clear enough to distinguish it from sibling tools like safari_fill or safari_js. This aligns with the 'clear context, no exclusions' rating.

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

safari_closeA

Close a Safari tab. Omit both arguments to close the frontmost window's current tab.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
windowNo

TDQS

A3.8/5.0
Behavior3/5

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

No annotations are present, so the description carries the behavioral burden. It discloses that the tool closes a tab and defines the default target, which is useful. It does not mention irreversibility, unsaved-state loss, or what happens when only one argument is supplied, but the destructive nature is evident from the verb 'close.'

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?

One sentence with no filler. The primary action is stated first, and the special case follows naturally. Every part of the description earns its place.

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?

The tool is simple: two optional parameters and no output schema. The description covers the core operation and the no-argument default, but leaves partial-argument semantics and index conventions implicit. It is adequate yet incomplete for an agent trying to call it with one argument.

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

Parameters2/5

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

Schema description coverage is 0%, and the description only explains the case where both arguments are omitted. It does not define what the integer values for 'tab' and 'window' represent, nor does it explain behavior when only one of the two arguments is provided. The parameter names and the default instruction provide some orientation, but not enough.

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 states a specific verb and resource: 'Close a Safari tab.' It clearly distinguishes this tool from the sibling tools, which perform read, JavaScript execution, click, fill, element checks, waiting, listing, and opening operations. The added default-target detail further clarifies what the tool is for.

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 instruction to 'Omit both arguments to close the frontmost window's current tab' gives a concrete invocation condition. It does not explicitly name alternatives or exclusion criteria, but the intended use is clear from the action and the sibling set.

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

safari_element_existsC

Check whether a CSS selector matches any element in a Safari tab.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
windowNo
selectorYes

TDQS

C2.7/5.0
Behavior2/5

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

With no annotations, the description carries the full burden of disclosing behavior. It implies a read-only check, but it does not explicitly state the return value, whether the tool waits for the element, what happens when no element matches, or how invalid selectors are handled. This is a significant gap, especially alongside safari_wait_for.

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 one concise sentence with the verb and subject front-loaded and no filler. It earns its place as a clear purpose statement, though its brevity does contribute to missing behavioral and parameter detail.

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

Completeness2/5

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

Given no annotations, no output schema, and no parameter descriptions, the description alone should be complete enough for an agent to call the tool correctly. It is not: return type, tab/window semantics, waiting behavior, and relation to safari_wait_for are all absent. It is a clear but under-specified definition.

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

Parameters2/5

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. It does clarify that 'selector' is a CSS selector, but it leaves 'tab' and 'window' semantically undefined: there is no explanation of what the integers refer to, what null/default means, or how the two interact. That is a meaningful gap for a 3-parameter tool.

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

Purpose4/5

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

The description clearly states the action ('Check whether') and the resource ('a CSS selector matches any element in a Safari tab'), making the boolean-existence purpose obvious. It does not explicitly call out how it differs from siblings like safari_wait_for, but the core function is recognizable enough to avoid confusion at a high level.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus alternatives. It never mentions that safari_wait_for is the appropriate choice when an element may need time to appear, nor that safari_element_exists is a non-waiting preflight check. The agent is left to infer usage context from the tool name alone.

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

safari_fillA

Set an /'s value via a CSS selector, dispatching real 'input'/'change' events so JS-framework-backed forms (React, Vue, ...) observe the change. Returns found=False (not an error) if nothing matched the selector.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
valueYes
windowNo
selectorYes

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations provided, the description carries the full behavioral burden. It discloses the important event-dispatch behavior and the non-error no-match result ('Returns found=False (not an error) if nothing matched'). It does not mention multi-match behavior or whether the previous value is overwritten, but the core safety-relevant behavior is covered.

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 sentences, front-loaded with the core action, no filler or redundancy. Every clause adds useful information: target element type, selector mechanism, event behavior, and no-match return semantics.

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?

The description is strong for a simple action but is not fully complete given there is no output schema and no annotations. It explains the failure case ('found=False') but not the success return shape, and it does not state behavior when multiple elements match the selector or how tab/window targeting works.

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?

Schema description coverage is 0%, so the description must compensate for parameter meaning. It adds the critical clarification that selector is a CSS selector and that value is set on an input/textarea, but it does not explain the optional tab and window parameters at all. This partial compensation merits a 3, not higher.

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 uses a specific verb ('Set') and names the resource ('<input>/<textarea>'s value') plus the mechanism ('via a CSS selector'). It clearly distinguishes itself from siblings like safari_click, safari_read, and safari_js by explaining exactly what action it performs.

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 gives clear context for when this tool is appropriate: 'dispatching real input/change events so JS-framework-backed forms (React, Vue, ...) observe the change' implies it should be used over raw JS injection for framework-managed inputs. It does not explicitly name alternatives or exclusions, so it stops short of a 5.

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

safari_jsB

Evaluate arbitrary JavaScript in a Safari tab's page context and return the string-coerced result. Requires Safari's Develop menu > 'Allow JavaScript from Apple Events' to be enabled.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
codeYes
windowNo

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description carries the full burden for behavioral disclosure. It does disclose that execution happens in the page context and that results are string-coerced, and it mentions the required Develop menu setting. However, it does not describe side effects, error behavior, tab/window targeting semantics, or that arbitrary JS can modify the page.

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 sentences with no filler. The core behavior is front-loaded, and the prerequisite is stated separately and clearly. Every sentence earns its place.

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

Completeness2/5

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

The description covers what and prerequisite but omits important operational context for a code-execution tool: target tab/window selection, return-value edge cases, and side-effect expectations. With no output schema and no annotations, this leaves meaningful gaps for an agent deciding how to invoke the tool safely.

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

Parameters2/5

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

Schema description coverage is 0%, yet the description provides no parameter-level meaning beyond the word 'JavaScript' hinting at 'code'. The optional 'tab' and 'window' parameters are not explained, so the agent cannot determine how target selection works or what null defaults mean.

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 uses a specific verb ('Evaluate') and resource ('arbitrary JavaScript in a Safari tab's page context'), and clearly distinguishes this from siblings like safari_click, safari_fill, and safari_read. It also states the output behavior ('return the string-coerced result'), leaving no ambiguity about the tool's core function.

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

Usage Guidelines2/5

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

No guidance is given about when to prefer safari_js over sibling tools, nor are alternatives mentioned. The 'arbitrary JavaScript' wording implies broad use, but there is no explicit when-to-use or when-not-to-use context, leaving the agent to infer the decision.

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

safari_openA

Navigate Safari to a URL. Reuses the real, already-logged-in Safari session (cookies, extensions, everything) rather than a separate automation profile. With new_tab=True opens a new tab; otherwise navigates the frontmost window's current tab in place. Waits for the page to finish loading by default so the returned title is accurate.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYes
new_tabNo
wait_for_loadNo

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral disclosure burden. It openly discloses session reuse with cookies and extensions, tab navigation semantics, and default wait-for-load behavior so the returned title is accurate. It does not mention failure modes or permission caveats, but the major behavioral traits are covered.

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?

Three sentences with no filler. The core action is front-loaded, followed by the session context, then the parameter-dependent behaviors. Every sentence earns its place.

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?

For a 3-parameter navigation tool with no annotations and no output schema, the description covers purpose, session context, tab behavior, load behavior, and returned title accuracy. It lacks explicit error or edge-case handling, but an agent has enough information to call the tool correctly.

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 description coverage is 0%, so the description must compensate. It adds meaningful semantics for new_tab and wait_for_load, and even links wait_for_load to the returned title. The url parameter is minimally described as 'a URL,' but that is largely self-explanatory for a navigation tool.

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?

States a specific verb and resource: 'Navigate Safari to a URL.' It also distinguishes itself from a separate automation profile and, implicitly, from sibling interaction tools like safari_click or safari_read by focusing on navigation.

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?

Provides clear context by explaining that it reuses the real logged-in Safari session rather than a separate automation profile, which establishes a strong reason to use it. It also explains the new_tab and wait_for_load behaviors, though it does not explicitly name alternatives or say when not to use it.

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

safari_readA

Read a Safari tab's URL, title, and visible text (document.body's innerText). Set include_html=True to also get the full outerHTML. Omit window/tab to read the frontmost window's current tab.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
windowNo
include_htmlNo

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations, the description carries the full burden. It discloses the read-only nature ('Read'), the specific data returned (URL, title, innerText, optional outerHTML), and the default tab selection. It does not mention error conditions or potential side effects, but 'Read' implies non-mutating, and the detail about what is returned is sufficient for an agent to understand the operation.

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?

Three sentences, each carrying distinct information: what is read, how to opt into HTML, and the default targeting. Front-loaded with the core purpose, no wasted words. Perfectly structured for quick consumption.

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 the main purpose and the return content (URL, title, text, optional HTML). Since there is no output schema, it is the sole source of return info and does provide it. However, it omits the exact return format (e.g., JSON structure) and does not address error scenarios. It also does not distinguish from safari_js, which could also read content. Overall, it is fairly complete for a simple read operation, but not exhaustive.

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

Parameters2/5

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

Schema coverage is 0%, so the description must explain all parameters. It explains include_html clearly ('Set include_html=True to also get the full outerHTML'), and it explains the default behavior for window/tab ('Omit window/tab to read the frontmost window's current tab'). However, it never clarifies what integer values for tab or window represent (e.g., indices, IDs) or whether both are needed together. This is a significant gap given zero schema documentation.

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 reads a Safari tab's URL, title, and visible text, and optionally the full outerHTML. This is a specific verb-resource pair that distinguishes it from siblings like safari_js (which executes scripts) and safari_click (which mutates). It unambiguously defines what data is returned.

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

Usage Guidelines2/5

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

The only usage guidance is the default behavior when window/tab are omitted ('frontmost window's current tab'). It does not mention when to prefer this tool over alternatives like safari_js, nor any exclusions or prerequisites. No context about when NOT to use it is given.

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

safari_tabsA

List every open tab across every Safari window. Each entry has window_index, tab_index, url, title, and is_current (whether it's that window's frontmost tab).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description must carry the behavioral transparency burden, and it does so by specifying the exact shape of returned entries (window_index, tab_index, url, title, is_current) and clarifying the meaning of is_current as the frontmost tab of the window. It does not explicitly assert that listing has no side effects, but the verb 'List' strongly implies a read-only operation. This is a reasonable level of disclosure for a simple enumeration tool.

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 filler. The opening sentence states the action and scope immediately, and the second sentence adds the essential return fields, so every word earns its place.

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

Completeness5/5

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

This is a zero-parameter tool with no output schema, so the description must specify what the agent will receive; it does, listing all fields and defining the one ambiguous value. It does not mention edge cases like an empty Safari session, but for a tool this simple the information provided is sufficient for correct invocation.

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 input schema has zero parameters, so the baseline is 4; there is nothing for the description to add about parameters. The description focuses entirely on the output fields, which is appropriate for a parameterless tool.

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 names a specific verb ('List') and resource ('every open tab across every Safari window'), making the tool's action unambiguous. It also enumerates the fields each entry contains, which clearly separates it from sibling tools like safari_read or safari_close.

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

Usage Guidelines2/5

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

The description provides no guidance on when to choose this tool over siblings such as safari_read or safari_js, and does not mention any exclusions or alternatives. Usage must be inferred entirely from the action itself, which is not sufficient for routing an agent in ambiguous situations.

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

safari_wait_forA

Poll a Safari tab until a CSS selector matches an element, or time out. Useful after a click/navigation that loads content asynchronously. Returns found=False (not an error) on timeout.

ParametersJSON Schema
NameRequiredDescriptionDefault
tabNo
windowNo
selectorYes
timeout_secondsNo

TDQS

A4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It discloses the timeout behavior explicitly: 'Returns found=False (not an error) on timeout.' This clarifies that a timeout is not an error and the return value is a boolean. It also implies polling behavior but does not mention other potential failures (e.g., invalid selector) or whether the operation is read-only. Still, the main behavioral trait is well-covered.

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, front-loaded with the core action and the timeout behavior. There is no wasted wording; each sentence earns its place.

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?

The description covers the essential purpose, a use case, and the timeout return value. However, it does not describe the success return (implied true), explain the tab/window parameters, or mention error scenarios like invalid selectors. Given the absence of an output schema and annotations, these gaps leave the tool only adequately specified.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must explain parameters. It implicitly identifies 'selector' as a CSS selector ('a CSS selector matches') and hints at a timeout, but it does not explicitly name or explain 'tab', 'window', or 'timeout_seconds'. The optional tab/window parameters are left completely unexplained, which is a significant gap for a tool with 0% schema coverage.

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 action: 'Poll a Safari tab until a CSS selector matches an element, or time out.' It specifies the resource (Safari tab) and the condition (CSS selector match). It also distinguishes itself from siblings by focusing on waiting/polling, and explicitly mentions the typical use case after click/navigation.

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 provides a clear context: 'Useful after a click/navigation that loads content asynchronously.' This tells the agent when to use it, but it does not mention alternatives like safari_element_exists or state when not to use it. It gives a clear scenario but lacks explicit exclusions or comparisons.

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.

  1. 9 tool updatesv0.1.0
    • First observedsafari_click
    • First observedsafari_close
    • First observedsafari_element_exists
    • First observedsafari_fill
    • First observedsafari_js
    • First observedsafari_open
    • First observedsafari_read
    • First observedsafari_tabs
    • First observedsafari_wait_for

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct action: tab-level operations (open, close, tabs) vs. page-level interactions (read, click, fill, js) vs. condition checks (element_exists, wait_for). The only conceivable overlap is between element_exists and wait_for, but one is a one-shot check and the other is a polling operation, so the descriptions make them unambiguous.

Naming Consistency4/5

All tools share the consistent 'safari_' prefix and lowercase snake_case style, and most use a verb-like action word (close, read, click, fill, open). Minor deviations exist: 'safari_tabs' is a noun rather than a verb phrase like 'list_tabs', and 'safari_element_exists' is a noun+verb predicate, but the overall pattern remains predictable.

Tool Count5/5

Nine tools is a well-scoped size for a Safari automation server, covering navigation, tab management, page reading, and DOM interaction without unnecessary bloat. Each tool earns its place for a focused browser-automation purpose.

Completeness4/5

The core workflows are covered: open URLs, read page content, interact via click/fill/JS, wait for elements, and manage tabs. Minor gaps exist, such as no explicit back/forward navigation, no screenshot capability, and no direct 'activate tab' tool, but these are workaroundable and the essential lifecycle of browsing automation is present.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • -
    license
    A
    quality
    Not graded
    maintenance
    A server that provides AI assistants programmatic control of Safari browser on macOS for web automation, testing, and debugging.
    16
    1
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables visual web access and browser automation through Safari, with tools for navigation, screenshots, element interaction, and tab management.
    17
    14 npm
    BSD 3-Clause
  • A
    license
    A
    quality
    D
    maintenance
    Safari Web Extension + Node.js MCP bridge giving Claude Desktop full control over Safari — navigate, read pages, click elements, fill forms, and manage tabs. No Playwright or WebDriver dependency.
    13
    1
    MIT