The catalog finds the tool. The gateway decides whether this token may call it, and writes down why.
The catalog answers whether the agent can find the tool. OpenConnector answers whether this token is allowed to call it, and whether you can hand an examiner the record afterward.
Yesterday I closed the middleware stack on a rotation test. If the secret lives in the process, a rotation is an outage. The missing piece on that diagram was not another registry. It was a gateway that keeps the credential, applies a policy, and writes a log you can verify. That is the job OOMOL Lab shipped as OpenConnector.
If you still have github.com/openconnector/openconnector in a bookmark, throw it out. That repo does not exist. The tree is oomol-lab/open-connector, Apache 2.0, TypeScript, Node 22 or newer. It was created June 29. This morning it sits at 5,337 stars and 454 forks, last push about an hour ago. The latest tag is v1.4.0, published August 20. Forty-six commits have landed on main since that tag. The live catalog at connector.oomol.com reports 1,445 providers and 14,791 actions. Two months ago the research note in this vault called the project twenty days old and sitting near 3,000 stars. The count moved. The architecture did not: credentials stay behind the runtime boundary, and agents get schemas and results.
The packaging is the first trap. The marketing site and the open-source runtime are not the same product with different wrapping.
openconnector.dev is a private-beta waitlist that pitches a Composio alternative with a one-line base URL change and an SDK named @open-connector/sdk. That package 404s on npm this morning. The client that actually installs is @oomol-lab/connector 1.1.0, published August 6, MIT, 21 stars, in oomol-lab/connector-sdk. The CLI lives in a third repo, oomol-lab/oo-cli, at v1.7.10 as of this morning. If you are evaluating the governance claim, read the self-hosted runtime. The landing page is a waitlist.
The runtime is a gateway. You point an agent at MCP, HTTP, or OpenAPI. The agent never sees a GitHub PAT or a Gmail refresh token. It presents a runtime token, names an action, optionally names a connection alias, and gets a result. The gateway decrypts the stored credential with AES-256-GCM, injects it server-side, and returns the upstream response. Admin surfaces take OOMOL_CONNECT_ADMIN_TOKEN. Agents take an oct_… runtime token, shown once, stored as a hash. Mix those up and the console works while /v1 and /mcp return unauthorized, or the reverse. The docs split those tokens on purpose. Treat a 401 on the wrong surface as a configuration error, not an SDK bug.
MCP is Saturday’s USB-C connector used as a discovery surface rather than a dump of fourteen thousand tools into the prompt. The local server at /mcp speaks the 2026-07-28 protocol as of v1.4.0. Stateless JSON-RPC POST. No hanging SSE stream. Five tools:
list_apps
list_connections
search_actions
get_action_guide
execute_action
That is the Composio meta-tool idea executed on a process you run. Search, fetch the guide, then execute. The guide is markdown: input schema, required scopes, the safe account label for the connection you selected. Omitting connectionName uses default. A named connection that does not exist does not silently fall back. Persistent tokens with a non-empty allowedConnections list never see the other accounts in discovery. Denied calls fail with HTTP 403 or MCP connection_not_allowed before credential lookup. That last sentence is the product.
Policy has two layers, and you want both.
Deployment policy is environment. OOMOL_CONNECT_ALLOWED_ACTIONS and OOMOL_CONNECT_BLOCKED_ACTIONS. Their own docs use github.* with github.delete_repository on the block list. I would ship that on day one. Blocked wins.
OOMOL_CONNECT_ALLOWED_ACTIONS="github.*" \
OOMOL_CONNECT_BLOCKED_ACTIONS="github.delete_repository" \
docker compose up --buildRuntime tokens add a second cut: allowedActions, blockedActions, allowedProxies, allowedConnections. Proxies default to empty, so a token cannot call /v1/proxy/:service until you grant a provider or *. Bootstrap tokens and JWTs have no stored grant. They inherit only the deployment policy. Stand this up on a public origin with the bootstrap token and a wide allow list, and you have rebuilt the PAT-in-the-environment problem with extra YAML.
v1.4.0 is the release that makes the OAuth side less embarrassing. Connection-scoped OAuth apps. Clients can request a scope subset. Gmail dropped the admin-only scope from user OAuth. Figma went to public scopes plus PKCE. Run-log redaction got three passes in the same tag because URL-shaped secrets kept leaking into summaries. That is the work a gateway has to do, and it is the work a hosted catalog can hide until an incident.
The audit trail is the claim that will get a security team in the room. Every credential use writes an append-only NDJSON record under .audit/, hash-chained with SHA-256 over the canonical content plus the previous hash. Actor, target, action, outcome. No token values, no request bodies. A verifier in the repo re-derives the chain. Set OTLP_ENDPOINT and Loki becomes the queryable mirror. The on-disk file is the integrity artifact.
Here is where I would not let a vendor slide. The default hash-chain state is in-memory and single-process. Restart the process without the shared-state strategy they document, and the chain does not mean what you told the auditor it means. There is no audit read or export HTTP API. Long-term tenant-scoped export is gated on an @open-connector/ee-audit license that is a follow-up, not shipping. Encryption-key rotation has no command. Change CONNECTOR_ENCRYPTION_KEY without re-encrypting and every stored credential is gone. Phoenix traces a span. This journal is closer to what I asked for on Tuesday. Closer is not an examiner signing off.
The identity hole from Tuesday is still a hole. Agents authenticate with a project-scoped API key or a runtime token. That attributes a call to a project. It does not mint an agent principal that can acquire a short-lived, audience-bound token without a human in the loop. First connection for OAuth is still a browser. The user clicks Allow. The refresh token lives in your vault instead of Composio’s. That is a real improvement for custody. It is not agent-scale authentication. Fill the blank with a shared service account behind this gateway and you will still fail the CISO question after the first bad tool call. You will fail it with better logs.
Composio remains the catalog I would rent for the long tail I refuse to operate. 29,879 stars yesterday, hosted OAuth, seven meta-tools, a session tied to your user_id. You do not run Postgres. You also do not own the credential, the policy, or the log. Strands remains the in-process hook for the call that is the product: BeforeToolCallEvent on a refund you wrote. OpenConnector sits between those two on purpose. Self-host it when the SaaS tail has to live in your VPC, when allow/block has to be independent of the model’s tool list, and when a hash-chained record of who called what is a requirement rather than a nice-to-have. Skip it when you have five MCP servers you already wrote. Skip it when the integration is load-bearing internal code and the gate belongs in your process. Skip the hosted waitlist until the SDK on the homepage exists on npm.
I would stand it up as Docker Compose on a private network, encryption key in a secrets manager, ALLOWED_ACTIONS set to the three providers the agent is allowed to see, BLOCKED_ACTIONS set to every delete and every send, one runtime token per agent with allowedConnections pointing at the work GitHub account, MCP pointed at /mcp. Then rotate the GitHub PAT in the console and confirm the next github.get_current_user still works without bouncing the agent.
curl -s -X POST http://localhost:3000/v1/actions/github.get_current_user \
-H 'authorization: Bearer RUNTIME_TOKEN' \
-H 'x-oo-connector-alias: work' \
-H 'content-type: application/json' \
-d '{"input":{}}'That is yesterday’s test, applied to this gateway. If that call dies with the old key, you bought a catalog with extra ceremony.
The connector is settled. The catalog is still a rental unless you run it. The hook is still yours. The gateway is how you say no, and how you prove you said no after the model has already tried.
Friday I will pick the runtime news that actually moved this week. The decision tonight is narrower than whether OpenConnector is “the enterprise Composio.” Can you name the agent, the user, the action, and the policy that allowed it, without opening the process?
If this was useful, forward it to one engineer who needs less noise in their feed.


