archwall 把架构画全Every architecture, drawn in full

OpenConnector:AI 智能体连你的应用,只连一次,不碰密钥OpenConnector: agents use your apps without seeing your keys

agentsmcpoauthgatewaysecurity

OpenConnector overview: in come AI agents and apps that need your accounts; 1 way in: MCP (POST /mcp, 5 tools), the HTTP API /v1 (SDK, oo CLI, OpenAPI) and the Web Console (admin API /api), with the same action IDs and schemas on every way in; 2 checks: a bearer token when one is set (runtime token, JWT or admin), allow and block rules per action, and which account to act as; a denied call stops before any secret is read; 3 run: the input is checked against the action schema, the provider's code loads the first time it runs, and requests go through a guarded fetch with no private addresses, out to 1,000+ provider APIs or to OOMOL Marketplace / SaaS; 4 records: a redacted run log (last 5,000 by default), connections with their secrets (encrypted when a key is set) and temporary transit files, in SQLite, PostgreSQL or Cloudflare D1

OpenConnector 是开源网关,连接 AI 智能体和你用的应用。账号只连一次,智能体就能跑现成的动作,但看不到密码和令牌。

一次调用从 MCP、HTTP API 或 Web 控制台进来。网关查令牌和允许、禁止规则,选账号、查输入,跑服务的代码,记一条脱敏日志。

One action call: in comes POST /v1/actions/<id> or MCP execute_action; 1 who is calling: a bootstrap token from an env variable, a persistent token (oct_…, only its hash stored) or a JWT (Node only, needs 3 settings), sent as Authorization: Bearer when runtime auth is configured; 2 is it allowed: action rules from deployment, runtime and token, then a named or the default connection, then the token's allowed connection IDs; no means denied before any secret is read; 3 run: the input is checked against the JSON schema (else 400), then local provider code runs, or Marketplace / SaaS; local code has a 30 s timeout on provider API requests by default; 4 record and answer: a run log with input and output redacted; with an Idempotency-Key, HTTP only, a retry within 24 h replays the first answer; the answer has data and an executionId
一次调用:查令牌、查规则、选账号、跑、记日志

连接。 API 密钥和 OAuth 令牌存在网关的数据库里,设了加密密钥才加密。有些服务不用账号。Marketplace 的动作用一把密钥在 OOMOL 那边跑。SaaS OAuth 账号的令牌留在 OOMOL。

Connections: in comes a call that names a connection, or none; 1 pick: a named one is never swapped for another account; with no name the order is default, then no_auth, then Marketplace; a token can be limited to its allowed connection IDs; agents see an account label, never the secret; 2 stored here: API key or custom fields the provider declares, and OAuth2 through your own OAuth app, refreshed automatically when the access token has expired and a refresh token exists; encrypted only with OOMOL_CONNECT_ENCRYPTION_KEY; 3 no account secret: no_auth providers such as Hacker News, and Marketplace actions run by OOMOL with one deployment Marketplace key that sends only the action and input; 4 kept on SaaS: a SaaS OAuth account through an OOMOL project key; its tokens stay on SaaS, only a reference is kept here, and it runs remotely with no local fallback
连接:调用用哪个账号,密钥放在哪

安全护栏。 管理令牌守着控制台。每个持久调用方令牌带自己的授权。每一层都放行才能调用,禁止规则永远优先。请求到不了内网地址,除非打开开关。

Safety rails: 1 admin side: the admin token guards /api, /docs and the Console; the server binds to 127.0.0.1 and needs HOST=0.0.0.0 to open; runtime tokens are made here and shown once; set it whenever the Console is reachable beyond your machine; 2 caller tokens: a persistent token carries action rules, a proxy grant (empty means no /v1/proxy), a connection grant (exact connection IDs) and a trigger grant (empty means no triggers); 3 layers: deployment allow and block lists from env, the runtime policy saved in the Console, and token grants that can only narrow; every layer must allow and a block always wins; 4 data and egress: the guarded fetch blocks private and cloud metadata addresses, private networks need a flag and are for self-hosted providers only, and secrets at rest use AES-256-GCM when a key is set
安全护栏:管理令牌、调用方令牌、三层规则、出站和存储

目录。 每个服务一个文件夹:一份定义,加上调它 API 的代码。脚本把定义生成目录。代码第一次用到时才加载。

Providers and the catalog: in come 1,000+ providers, one folder each; 1 source: definition.ts (actions, schemas, scopes) and executors.ts (calls the provider API) under src/providers/<service>/; 2 build: npm run generate:catalog writes a JSON per provider plus an index, and the provider registry maps each service to a lazy import; 3 runtime: the catalog loads at startup for list and search, with the optional flag below the generated index is read instead of every provider file, provider code loads on first use, and keeping schemas on disk is that same flag OOMOL_CONNECT_CATALOG_LAZY_SCHEMAS, on Node and the single binary; 4 what callers see: an agent.md guide per action, /openapi.json, read / write / destructive labels, and whether an action runs locally or is catalog only
目录:每个服务一个文件夹,生成目录,用到时才加载代码

触发器用轮询或 webhook,把服务那边的事件交给 Open Flow,那是另一个工作流引擎。

Triggers: in comes Open Flow, the workflow engine, which keeps checkpoints, schedules and de-duplicates; 1 poll: read with the last checkpoint, at most 100 events a page, read again while hasMore; 2 webhook: reconcile creates or keeps the provider hook, receive checks the signature on bodies up to 64 KiB; hook IDs and secrets stay on the server; 3 state: subscriptions are encrypted with SQL leases, stateful operations need a persistent token, and only local connections work, not SaaS or Marketplace; 4 cleanup: a maintenance loop on Node or a cron on Workers removes revoked hooks, and admins can cancel or abandon a subscription
触发器:轮询或 webhook,把事件交给 Open Flow

部署在哪: Node 服务(Docker、单个可执行文件、Helm)、Cloudflare Workers、嵌进你自己的应用当库用,或者用 OOMOL 托管。

Where it runs: 1 Node server: the Docker image from GHCR on port 3000, a single binary for 6 platforms built with Bun, or the Helm chart and Fly.io from the same Dockerfile; SQLite by default or PostgreSQL 15+, transit files on local disk or S3; 2 Cloudflare: Workers run the gateway, D1 keeps records, R2 or Workers KV keeps transit files, and a cron runs cleanup once a minute; 3 inside your app: the npm library @oomol-lab/open-connector, your server owns HTTP, config and the process, no Web Console, one runtime per process; 4 OOMOL hosted: OAuth apps ready with no app setup, a hosted runtime managed by OOMOL, the same provider and action IDs so you can move to self-hosting later
部署:Node 服务、Cloudflare、嵌进应用、OOMOL 托管

OpenConnector is an open-source gateway between AI agents and the apps you use. You connect an account once. Agents then run ready-made actions on it, but never see its password or token.

One call comes in through MCP, the HTTP API or the Web Console. The gateway checks the token and the allow and block rules, picks the account, checks the input, runs the provider's code and writes a redacted log.

One action call: in comes POST /v1/actions/<id> or MCP execute_action; 1 who is calling: a bootstrap token from an env variable, a persistent token (oct_…, only its hash stored) or a JWT (Node only, needs 3 settings), sent as Authorization: Bearer when runtime auth is configured; 2 is it allowed: action rules from deployment, runtime and token, then a named or the default connection, then the token's allowed connection IDs; no means denied before any secret is read; 3 run: the input is checked against the JSON schema (else 400), then local provider code runs, or Marketplace / SaaS; local code has a 30 s timeout on provider API requests by default; 4 record and answer: a run log with input and output redacted; with an Idempotency-Key, HTTP only, a retry within 24 h replays the first answer; the answer has data and an executionId
One call: token, rules, account, run, log

Connections. API keys and OAuth tokens are stored in the gateway's database, encrypted only when you set an encryption key. Some providers need no account. Marketplace actions run at OOMOL with one key. A SaaS OAuth account keeps its tokens at OOMOL.

Connections: in comes a call that names a connection, or none; 1 pick: a named one is never swapped for another account; with no name the order is default, then no_auth, then Marketplace; a token can be limited to its allowed connection IDs; agents see an account label, never the secret; 2 stored here: API key or custom fields the provider declares, and OAuth2 through your own OAuth app, refreshed automatically when the access token has expired and a refresh token exists; encrypted only with OOMOL_CONNECT_ENCRYPTION_KEY; 3 no account secret: no_auth providers such as Hacker News, and Marketplace actions run by OOMOL with one deployment Marketplace key that sends only the action and input; 4 kept on SaaS: a SaaS OAuth account through an OOMOL project key; its tokens stay on SaaS, only a reference is kept here, and it runs remotely with no local fallback
Connections: which account a call uses, and where its secret lives

Safety rails. An admin token guards the console. Each persistent caller token carries its own grants. Every layer must allow a call, and a block always wins. Requests can't reach private addresses unless you turn on a flag.

Safety rails: 1 admin side: the admin token guards /api, /docs and the Console; the server binds to 127.0.0.1 and needs HOST=0.0.0.0 to open; runtime tokens are made here and shown once; set it whenever the Console is reachable beyond your machine; 2 caller tokens: a persistent token carries action rules, a proxy grant (empty means no /v1/proxy), a connection grant (exact connection IDs) and a trigger grant (empty means no triggers); 3 layers: deployment allow and block lists from env, the runtime policy saved in the Console, and token grants that can only narrow; every layer must allow and a block always wins; 4 data and egress: the guarded fetch blocks private and cloud metadata addresses, private networks need a flag and are for self-hosted providers only, and secrets at rest use AES-256-GCM when a key is set
Safety rails: admin token, caller tokens, three rule layers, egress and storage

The catalog. Each provider is one folder: a definition and the code that calls its API. A script turns the definitions into the catalog. The code loads only the first time it is used.

Providers and the catalog: in come 1,000+ providers, one folder each; 1 source: definition.ts (actions, schemas, scopes) and executors.ts (calls the provider API) under src/providers/<service>/; 2 build: npm run generate:catalog writes a JSON per provider plus an index, and the provider registry maps each service to a lazy import; 3 runtime: the catalog loads at startup for list and search, with the optional flag below the generated index is read instead of every provider file, provider code loads on first use, and keeping schemas on disk is that same flag OOMOL_CONNECT_CATALOG_LAZY_SCHEMAS, on Node and the single binary; 4 what callers see: an agent.md guide per action, /openapi.json, read / write / destructive labels, and whether an action runs locally or is catalog only
The catalog: one folder per provider, generated, code loaded on first use

Triggers pass provider events to Open Flow, a separate workflow engine, by polling or by webhook.

Triggers: in comes Open Flow, the workflow engine, which keeps checkpoints, schedules and de-duplicates; 1 poll: read with the last checkpoint, at most 100 events a page, read again while hasMore; 2 webhook: reconcile creates or keeps the provider hook, receive checks the signature on bodies up to 64 KiB; hook IDs and secrets stay on the server; 3 state: subscriptions are encrypted with SQL leases, stateful operations need a persistent token, and only local connections work, not SaaS or Marketplace; 4 cleanup: a maintenance loop on Node or a cron on Workers removes revoked hooks, and admins can cancel or abandon a subscription
Triggers: polling or webhooks, handing events to Open Flow

Where it runs: a Node server (Docker, one binary, Helm), Cloudflare Workers, a library inside your app, or OOMOL's hosted service.

Where it runs: 1 Node server: the Docker image from GHCR on port 3000, a single binary for 6 platforms built with Bun, or the Helm chart and Fly.io from the same Dockerfile; SQLite by default or PostgreSQL 15+, transit files on local disk or S3; 2 Cloudflare: Workers run the gateway, D1 keeps records, R2 or Workers KV keeps transit files, and a cron runs cleanup once a minute; 3 inside your app: the npm library @oomol-lab/open-connector, your server owns HTTP, config and the process, no Web Console, one runtime per process; 4 OOMOL hosted: OAuth apps ready with no app setup, a hosted runtime managed by OOMOL, the same provider and action IDs so you can move to self-hosting later
Where it runs: Node server, Cloudflare, inside your app, OOMOL hosted

来源Source: github.com

← 全部架构← All architectures