Independent AI intelligence Two editions daily · ET
FervorAI

Analysis · July 31, 2026 · repo

OpenConnectoroomol-labModel Context Protocolagent-infrastructureagent-securitymcpagent-identity

OpenConnector Hands Your Agent 8,310 SaaS Actions. Credential Encryption Is Off by Default.

The Apache-2.0 auth gateway climbing the trending boards this week is a real credential boundary for AI agents. Three environment variables decide whether it behaves like one.

You can count the providers in oomol-lab/open-connector four different ways without leaving the repository, and you will get four different answers.

The GitHub description says "1000+ SaaS providers." The README's opening paragraph says "800+ providers" and "6,680 prebuilt Actions." A bullet six lines below says "800+ providers and 8000+ prebuilt Actions." The architecture diagram in the same README has a node labeled "643 Providers." And docs/providers.md says 842 providers and 8,310 prebuilt Actions.

Only that last number is worth anything, and the reason is instructive: it is the only one that ships with the command to recount it. The doc includes a nine-line Node script that walks src/providers, imports each definition, and sums the actions. Run it and you get the truth as of your checkout. Every other figure in the repo is a rounded marketing number that drifted from the code at a different moment.

That gap is the whole review in miniature. The advertised metric is the least reliable thing about this project, and the part actually worth your attention never appears in the pitch.

Provider count is the wrong thing to shop for

Every agent integration platform sells on catalog size, which trains everyone to compare the wrong numbers. Nobody is going to wire an agent into 842 SaaS products. You will wire it into four, maybe seven. What matters is where the token lives while the agent is calling those four, and who can make it call the fifth.

That is the question OpenConnector is actually built to answer, and it answers it well on paper. The agent never touches a provider credential. It calls an Action through the gateway, and the gateway holds the secret. What comes back to the agent is a connection profile: accountId, displayName, and grantedScopes when the provider exposes them. The docs are explicit that "raw provider tokens are never exposed."

Compare that to how most people give an agent access to Gmail today, which is a .env file, an API key in a system prompt, or an MCP server started with the token in its process environment. In all three of those, the credential is one prompt injection away from being read back out. A gateway that keeps the secret on the other side of an execution boundary is a genuinely better shape, and it is Apache-2.0, self-hostable, and running on Node 22 or Cloudflare Workers.

So my position is that this repo is worth running. My other position is that docker compose up --build, which is the first command in the README, does not give you the thing I just described.

Three switches decide whether the boundary is real

Read docs/credentials.md before you connect a single provider. The security model is good and it is opt-in, which is a sentence that should worry you.

Credential encryption is off unless you set a key. Connections, OAuth client configuration, pending OAuth states, and run logs go into SQLite at ./data/connect.sqlite. Set OOMOL_CONNECT_ENCRYPTION_KEY and the runtime encrypts credentials and OAuth client secrets with AES-256-GCM. Leave it unset and, in the project's own words, "the runtime stays usable for local development and prints a startup warning." A startup warning in a Docker log is not a control. That file is your GitHub PAT, your Slack token, and your Google refresh token sitting in plaintext next to your source tree, and it will get backed up, synced, or copied into a container image by someone eventually.

One catch worth reading twice: the key is not stored by OpenConnector, and if you lose it, the encrypted records cannot be recovered. There is a rotate-key command for planned rotation. There is nothing for the day you lose the key.

Every action is callable unless you narrow it. OOMOL_CONNECT_ALLOWED_ACTIONS takes a comma-separated list with provider wildcards, like hackernews.*,github.get_current_user. OOMOL_CONNECT_BLOCKED_ACTIONS denies specific ones even when a wildcard would allow them. Set neither and the agent's tool surface is the entire catalog you happened to install. An agent connected to GitHub with no allowlist can call github.delete_repository, and that specific example is the one the docs use.

There is a genuinely good default hiding in this section. Provider proxy requests through /v1/proxy/:service can reach API endpoints beyond the curated action catalog, and the docs say that once any action policy is configured, proxy requests are denied by default unless the service is explicitly allowed. Deny-by-default on the escape hatch is the right call. It is a shame it only engages after you have set a policy.

The admin API is unauthenticated unless you give it a token. The server binds to 127.0.0.1 by default, which is a good default. Set HOST=0.0.0.0 for a container reachable from elsewhere and you have moved the admin API and web console onto the network with no auth until you set OOMOL_CONNECT_ADMIN_TOKEN. Runtime tokens for /v1 and /mcp are handled better: they are shown once at creation and only a hash is stored.

A design opinion worth stealing

Buried in the credentials doc is a rule I liked more than anything else in the repository. Submitted credential fields are validated against the provider's declared auth metadata, and unknown fields are rejected rather than silently stored. The stated reason: "credential forms, scripts, and provider definitions should fail fast when they drift."

That is the correct instinct for a catalog with 842 provider definitions maintained by a small team. Definitions will drift. Setup scripts written against last month's schema will keep running and silently store a field nobody reads. Rejecting the unknown key turns a slow, invisible failure into a loud one at connect time. If you maintain any config surface that a script writes to, copy that rule.

Put this into practice

The first useful run takes about ten minutes and touches no real credentials.

  1. Start the runtime and prove it works with no secrets. docker compose up --build, then hit the no-auth action the README ships for exactly this purpose:

    curl -s -X POST http://localhost:3000/v1/actions/hackernews.get_top_stories \
      -H 'content-type: application/json' -d '{"input":{}}'
    

    If that returns stories, the gateway, catalog, and executor layer all work. You have verified the plumbing without handing it anything you care about.

  2. Stop, and set the three variables before you connect anything real. Restart with an encryption key, an admin token, and an allowlist scoped to the actions you actually want. Something like OOMOL_CONNECT_ENCRYPTION_KEY, OOMOL_CONNECT_ADMIN_TOKEN, and OOMOL_CONNECT_ALLOWED_ACTIONS="github.get_current_user,github.list_issues". Store the encryption key wherever you keep real secrets, because you cannot recover the database without it.

  3. Connect one provider with the narrowest credential you can make. GitHub with a fine-grained PAT is the easiest first case because it skips OAuth entirely. The scopes you grant the token are the outer limit of what any allowlist mistake can do, so make them small.

  4. Point one agent host at it. MCP lives at http://localhost:3000/mcp, with the HTTP runtime at /v1/actions and a generated OpenAPI document at /openapi.json if you would rather call it directly. Start with the single provider from step three and confirm in the web console's run log that the call went through the gateway.

  5. Read a run log before you add a second provider. The console shows recent runs with redaction applied. Look at what actually got recorded, decide whether you are comfortable with it, and only then widen the allowlist.

Budget the real time for OAuth2 providers rather than API-key ones. Each OAuth provider needs you to register your own OAuth app on that provider's side and paste the exact expectedRedirectUri from /api/oauth/configs. That is per-provider paperwork, and it is the step that turns a ten-minute setup into an afternoon.

Honest limitations

The star count is not measuring what you think. Three page loads of this repository during one working session returned 10 stars with 2 forks, then 403 stars with 18 forks, then 1.1k stars with 57 forks. GitHub's anonymous page cache is doing that, not a thousand people starring in an hour. The repo also shows 138 commits and no published releases. Treat the trending placement as momentum, not adoption, and do not pin a version you cannot name.

Catalog size is generated surface area, not audited surface area. 8,310 Actions across 842 providers, maintained by a contributor list you can count, means most Action definitions have never been exercised by anyone. The executors are lazy-loaded and open source, which is the right design, and it also means the first person to call some_obscure_provider.update_record in anger is doing QA.

The credential boundary is a boundary, not a sandbox. It stops the agent from reading your token. It does nothing about an agent that was talked into calling an allowed destructive action with attacker-chosen arguments. The allowlist is your only real control there, and it operates on action IDs, not on arguments.

Self-hosting moves the risk, it does not remove it. On Cloudflare, the same records live in D1 with transit files in R2. You now run a service that holds every SaaS credential your agents use in one database. That concentration is the point and it is also the blast radius. It deserves the backup, rotation, and access review you would give a password manager.

The open-source repo is also a funnel. The README routes teams "blocked by OAuth approval or launch deadlines" to oomol's hosted runtime, and individuals to a desktop product called Wanta. That is a fair open-core model and worth naming out loud, because the OSS path is the one where you do the OAuth paperwork yourself. The Apache-2.0 license also explicitly does not grant rights to third-party provider trademarks, logos, or brand assets, which matters if you plan to ship that logo wall in your own product.

Where this leaves you

The provider count on the front of this repo will keep drifting, and it does not matter. What matters is that somebody built an open, self-hostable place for an agent's credentials to live that is not a .env file, published the Action executors so you can read what they do, and wrote down a policy language for narrowing what an agent is allowed to call.

They also shipped it with the locks in the box instead of on the door. That is a five-minute fix, and it is only a five-minute fix if you know to make it before the first real token goes in.

Start it, call the Hacker News action, and then close the terminal and go decide what your allowlist should say. That decision, not the catalog size, is the thing you are actually buying here.

Sources: oomol-lab/open-connector on GitHub; docs/providers.md; docs/credentials.md.