Three doors, one contract
Whichever door an assistant comes through, it reaches the same app.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, mode0600:
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.