Core vs IMessage MCP

A side-by-side look at the Core and IMessage MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.

Core logoCoreOS Automation · Local subprocess (stdio)Agent-native MCP server for driving, inspecting, and asserting on real Electron desktop apps.59GoodAuth: not declaredIMessage MCP logoIMessage MCPOS Automation · Local subprocess (stdio)25 tools for searching, analyzing, and exploring your iMessage history on macOS.59GoodAuth: not declared

Verdict: choose Core for os automation work as a local process; choose IMessage MCP for os automation as a local process. You can also run both side by side in one mcpServers block.

Which MCP server should you choose?

Core logoChoose Core when

  • You need dedicated capabilities in the OS Automation domain.
  • You prefer a local stdio subprocess transport.
  • You want tools like electron_assert_pattern, electron_attach, electron_check.
Explore Core

IMessage MCP logoChoose IMessage MCP when

  • You need dedicated capabilities in the OS Automation domain.
  • You prefer a local stdio subprocess transport.
  • You want tools like search_messages, get_conversation, list_conversations.
Explore IMessage MCP

Feature & specification comparison

Rows where the two servers differ are marked.

SpecCore logoCoreIMessage MCP logoIMessage MCP
CategoryOS AutomationOS Automation
Quality signal59/100 · Good59/100 · Good
Install commandConfirmedConfirmed
TransportLocal subprocess (stdio)Local subprocess (stdio)
AuthNot declaredNot declared
PricingNot declaredNot declared
Required env varsNone listedNone listed
Verified ownerCommunity listingCommunity listing
GitHub stars1228
Directory activity 6 views 0 installs 0 upvotes 3 views 0 installs 0 upvotes
Tools558

Tools & capabilities

Core tools 55

  • electron_assert_patternValidate, in a single check (no polling), that an element's text or a named attribute matches a pattern. Target by ref or selector. With `attribute` set, reads that attribute; otherwise reads the element's trimmed text. Provide exactly one of: equals, contains, matches_regex. Optional flags (any of i, m, s, u) apply to matches_regex; g and y are rejected as stateful. Returns: { ok, session_id, matched, actual }. Errors: EXPECTATION_FAILED (element found but its value did not match the pattern — details carry expected + actual; a missing attribute reads as actual: null), SELECTOR_NO_MATCH (no element matched — this is one-shot, so a missing element is a precondition failure, not a retry; carries similar_refs), REF_NOT_FOUND (stale ref), TRANSPORT_UNSUPPORTED, NOT_RUNNING, BAD_ARGUMENT (no/multiple predicates, invalid regex or flags, or ref+selector both/neither).
  • electron_attachAttach to an already-running Electron app exposing a CDP debug endpoint (use electron_discover_running to find one, or start the app with --remote-debugging-port). Provide port (+ optional loopback host) or a loopback cdpUrl; pid alone is not attachable over CDP but, when supplied alongside, lets stop escalate to SIGKILL. The CDP transport supports eval/read/observe and core interaction surfaces against the attached app. The selected CDP page is also the default snapshot/find surface; explicit iframe/webview surface targeting remains unavailable. Returns: { ok, session_id, transport, windows, capabilities }. Errors: TRANSPORT_UNSUPPORTED (no attach-capable transport), CDP_DISCONNECTED (endpoint unreachable or dropped; retryable), CDP_TIMEOUT (handshake/method timeout; retryable), BAD_ARGUMENT (missing target selector or non-loopback endpoint).
  • electron_checkCheck the checkbox/radio identified by ref or selector (no-op if already checked). Options: force, timeoutMs. Returns: { ok, session_id, target, checked: true }. Errors: REF_NOT_FOUND / SELECTOR_NO_MATCH (carries similar_refs), ELEMENT_NOT_VISIBLE (retryable), ELEMENT_DISABLED, NOT_RUNNING, BAD_ARGUMENT.
  • electron_clear_inputClear the value of the input/textarea identified by ref or selector (sets it to empty). Options: force, timeoutMs. Returns: { ok, session_id, target, cleared }. Errors: REF_NOT_FOUND / SELECTOR_NO_MATCH (carries similar_refs), ELEMENT_NOT_VISIBLE (retryable), ELEMENT_DISABLED, NOT_RUNNING, BAD_ARGUMENT.
  • electron_clickClick the element identified by ref (from a snapshot) or selector. Options: button (left|right|middle, default left), clickCount (2 = double-click), force (bypass actionability), timeoutMs. Returns: { ok, session_id, target }. Errors: REF_NOT_FOUND / SELECTOR_NO_MATCH (no such element — re-snapshot; not retryable, carries similar_refs), ELEMENT_NOT_VISIBLE (retryable), ELEMENT_DISABLED (not retryable), NOT_RUNNING, BAD_ARGUMENT (ref+selector both/neither).
  • electron_console_logsRead the captured renderer console output for the session, newest-relevant entries last. Filters (all optional, ANDed): type (one or more of log/info/warning/error/debug/...), match (a regular expression the text must match), since (epoch ms — only entries at/after it), limit (max entries, default 200, max 1000 — the most recent are kept). Returns: { ok, session_id, entries: [{ type, text, timestamp, windowId?, location? }], count, overflowed }. overflowed is the number of older entries the buffer dropped. Errors: NOT_RUNNING, BAD_ARGUMENT (invalid regex, or multiple sessions).
  • electron_detachDisconnect from an attached or injected app without stopping it. A launch-owned session cannot detach because its transport owns the process; this includes Playwright development launches and packaged CDP launches. Use electron_stop for that case. Returns: { ok, session_id, detached: true }. Errors: TRANSPORT_UNSUPPORTED (launch-owned session; not retryable), NOT_RUNNING (no such session), BAD_ARGUMENT (multiple sessions).
  • electron_dialog_handlerArm the auto-responder for native JS dialogs (alert/confirm/prompt/beforeunload) and read which dialogs fired. Dialogs block the renderer, so the policy is applied automatically the instant one appears. Arming args (all optional): action (accept|dismiss — the default for every dialog), perType (per-kind overrides, e.g. {"confirm":"accept","beforeunload":"dismiss"}, falls back to action), promptText (text submitted to prompt() when it is accepted), oneShot (apply to exactly the next dialog, then revert to dismiss). With NO arming args the call is inspect-only and leaves the policy unchanged. Read args (all optional): type (one or more kinds to include), since (epoch ms), limit (max events, default 50, max 200 — most recent kept), clear (flush the whole buffer after reading). Until armed, the default policy is dismiss, so dialogs never hang the app. Returns: { ok, session_id, policy, entries: [{ type, message, action, defaultValue?, promptText?, timestamp, windowId? }], count, overflowed }. overflowed counts dropped events across the whole buffer, not just the returned (type/since/limit-filtered) subset. Errors: NOT_RUNNING, BAD_ARGUMENT (promptText without an accepting prompt policy, or oneShot without a policy to arm).
  • electron_discover_runningScan the conventional CDP debug ports (9222-9225 by default) for already-running, debuggable Electron apps on loopback only. No session required. Returns: { ok, targets, count, scanned } where each target is { targetId, port, appName, pid } and scanned reports { host, ports, elapsed_ms } so an empty result is unambiguous. Errors: BAD_ARGUMENT (non-loopback host, invalid port list, or timeout outside bounds). A failed probe is simply "no target on that port".
  • electron_doctorRun non-mutating preflight checks without starting an Electron session: Node version, Playwright, Electron, Linux display, configured app root and screenshot directory, eval policy, and project Electron runtime alignment. Returns: { ok, doctor_ok, checks, runtime }, where runtime includes server and, with --app-root, target Electron/Node/V8/ABI facts plus a bounded native-addon inventory. Inspect failed checks and warnings before electron_launch. Errors: none.
  • electron_dragDrag the source element (ref or selector) onto the target element (targetRef or targetSelector), using the real mouse API. Options: force, timeoutMs. Returns: { ok, session_id, source, target }. Errors: SELECTOR_NO_MATCH / REF_NOT_FOUND (carries similar_refs), ELEMENT_NOT_VISIBLE (retryable), NOT_RUNNING, BAD_ARGUMENT (a side missing or both ref+selector given).
  • electron_drop_fileSimulate dropping OS files onto the element identified by ref or selector. Web DataTransfer mode: reads each path on the host running the server, rebuilds the files in the renderer, and dispatches dragenter/dragover/drop with a real DataTransfer — engaging standard web drop handlers. Paths must be ABSOLUTE (max 10 files, 5242880 bytes each). default_prevented reports whether a drop handler engaged (called preventDefault); false usually means the target has no web drop handler. Apps that resolve dropped files to native OS paths need an app-specific IPC convention this tool does not simulate. Options: mimeType, timeoutMs. Returns: { ok, session_id, target, files, default_prevented }. Errors: ABSOLUTE_PATH_REQUIRED, FILE_NOT_FOUND, BAD_ARGUMENT (too many/large files, or ref+selector both), SELECTOR_NO_MATCH / REF_NOT_FOUND (carries similar_refs), NOT_RUNNING.
  • +43 more on the listing page

IMessage MCP tools 8

  • search_messagesSearch by substring, exact text, token, or phrase. Message text by default; conversation names and attachment filenames are opt-in. Filter by service, sent or received, and date
  • get_conversationRead a conversation by `chat_id` or by a contact or group name, with edits, reactions, receipts, replies, group events, and attachments. The cursor pages to older events
  • list_conversationsFind conversations by contact, service, kind, reply state, or date, each with its latest message, newest first or by who you text most
  • get_attachmentShow one attachment from `get_conversation`: images as a JPEG with location and camera metadata removed, text files as text. Needs the `full` privacy mode
  • sync_messagesPull every change since a cursor: new, edited, unsent, and deleted messages, conversation memberships, reactions, and receipts
  • analyze_communicationMessage counts by hour and weekday, response times, streaks, and who starts conversations
  • resolve_contactMatch a name, phone number, or email to a contact in your Mac's Address Book, and report ambiguity rather than guess
  • server_statusVersion, update availability, privacy mode, index and cache state, schema support, conversation membership counts, and Contacts access

Ready-to-paste client configs

Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.

Core

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "core": {
      "command": "npx",
      "args": [
        "-y",
        "--package",
        "@electron-stagewright/core@0.5.0",
        "--package",
        "playwright@1.61.1",
        "--package",
        "electron@42.3.0",
        "electron-stagewright"
      ]
    }
  }
}

IMessage MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "imessage-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "imessage-mcp@latest"
      ]
    }
  }
}

Frequently asked questions

Core is categorized under OS Automation and uses a local stdio subprocess. IMessage MCP belongs to OS Automation and uses a local stdio subprocess. Pick Core for os automation work and IMessage MCP for os automation.

Copy the mcpServers block from the config section on this page into your client's config (for example claude_desktop_config.json or ~/.cursor/mcp.json), then fully restart the client.

Core has no declared pricing — check the project's own site. IMessage MCP has no declared pricing — check the project's own site. If a server needs environment variables such as API keys, define them under the env key in your client's MCP config.

Yes. MCP clients support multiple servers: add core and imessage-mcp as separate keys in the same mcpServers object, and your assistant will call tools from either one.

On AllMCPs, Core has a quality signal of 59/100 (Good) with 6 views, 0 installs and 12 GitHub stars. IMessage MCP has 59/100 (Good) with 3 views, 0 installs and 28 GitHub stars.