Skip to main content
Understanding the shape helps when something goes wrong, and it is the reason several of Pomeroy’s promises can be kept at all.

Three doors, one contract

Whichever door an assistant comes through, it reaches the same app.
What each door is for

The bridges do not understand MCP

Two of the three doors are byte pipes: the .mcpb extension inside Claude Desktop, and pomeroy-mcp inside the app bundle. Both do the same three things: connect to the socket, launch the app if it is not running, copy bytes. Neither parses JSON-RPC. Neither knows what a tool is. That is why the Claude Desktop extension never has to be updated. Pomeroy can add tools, change what they return, and rewrite every answer, and the extension carries on copying bytes. Both speak bridge protocol version 1, and the app cannot tell them apart. The HTTP endpoint is different. It terminates HTTP and speaks MCP, which is exactly why it is confined to a small number of files and gated by a credential.

The app holds everything that matters

Every permission, every toggle and every tool lives in the app. That is the decision the rest follows from:
  • One place to check a toggle. A tool call is gated once, in the app, whichever door it came through. There is no second path to your data that could miss the gate.
  • One process holds the grants. macOS grants permission to an application, and Pomeroy.app is the application. A bridge holds nothing.
  • The pipe carries no weight. A stdio session loads no AppKit, no Sparkle and no analytics library.

Why the local door is a socket, and the remote one is not

The default path is a Unix domain socket in your home folder, mode 0600: readable and writable only by processes running as you, on this Mac. The filesystem decides who reaches it, so there is no key to manage and nothing to leak. A TCP port has no such gate, because any process on the Mac can open one. When the HTTP endpoint was added for the cases stdio cannot serve (a container, a VM, a runner), it did not inherit the socket’s guarantee and had to bring its own: a credential, in one of three exclusive modes, and a binding to loopback only. Two doors, two threat models, stated separately rather than averaged into one reassuring sentence.

A connection is not a grant

When an assistant connects, Pomeroy labels the connection from what the assistant says about itself in its opening request. That label is descriptive, not a security boundary. The socket’s file permissions, or the endpoint’s credential, are the boundary. Nothing about an assistant survives the connection. There is no stored consent and nothing to revoke, because the only gate on a tool call is the app’s toggle. Setting an assistant up is the consent: it was you choosing that assistant.

What this buys you

CheckableEvery request that can leave your Mac goes through one client with one allowlist, so a test can drive every flow through a recorder and read what went out, byte by byte.
NarrowPomeroy reaches an app only through the interface that app publishes for automation. It holds no grant over your screen, and none over any file except the one Messages database you hand it.

What leaves your Mac

Every request, what is in it, and what can reach Pomeroy.

What Pomeroy asks macOS for

The grants it requests, and the two it never asks for.