尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Open IpaaS is a high-performance Node.js (Next.js) framework designed to unify communication with any global SaaS platform (CRMs, ERPs, HRIS, Ticketing, Accounting, e-Commerce, etc.) under a single **English-first**, **strongly-typed**, and **runtime-validated** API.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
The open-source standard for universal B2B integrations.
Open IpaaS is a high-performance Next.js framework that unifies communication with any SaaS platform (ERPs, CRMs, e-commerce, accounting, ticketing) behind a single English-first, strongly-typed, runtime-validated API.
Enterprise-grade integrations shouldn't be locked behind closed-source paywalls.查看完整 README ↗The open-source standard for universal B2B integrations.
Open IpaaS is a high-performance Next.js framework that unifies communication with any SaaS platform (ERPs, CRMs, e-commerce, accounting, ticketing) behind a single English-first, strongly-typed, runtime-validated API.
Enterprise-grade integrations shouldn't be locked behind closed-source paywalls.
Website · Docs · Contributing
/passthrough exposes the raw provider API with credentials handled, so a missing unified field never stops you.graph LR
Client([Your app]) --> Auth[withUnifiedAuth]
Auth --> Registry[Provider registry]
Registry --> Base[BaseProvider]
Base --> Mapper[Zod mapper]
Mapper --> SaaS[(Upstream API)]
withUnifiedAuth handles authentication, rate limiting, idempotency, error translation and request logging. BaseProvider handles URL building, throttling, retries, token refresh and passthrough. A provider implementation is left with mappers and endpoint paths.
src/lib/providers/
core/ registry, BaseProvider, http, rate-limit, pagination, errors, types
implementations/
contaazul/ manifest.ts · provider.ts · mappers/ · types/
omie/
tiny/
git clone https://github.com/entende-ai/openipaas.git
cd openipaas
docker compose up --build
That is the whole setup. Postgres, Redis, migrations, seed data and the app, with working development defaults for every secret.
http://localhost:3000/docshttp://localhost:3000/dashboard. The first visit asks you to
create an account; confirm it with the server password, development-only
by default (DASHBOARD_PASSWORD). After that you sign in with your email.Connecting a provider needs its OAuth credentials, which are yours to register.
Put them in .env as <SLUG>_CLIENT_ID and <SLUG>_CLIENT_SECRET, and register
http://localhost:3000/api/oauth/callback/<provider-slug> as the callback.
npm install
npm run setup:env # writes .env with real generated secrets
npm run setup # starts Postgres and Redis, migrates, seeds
npm run dev
.env.example documents every variable and ships the same development defaults
as docker compose. For anything real, replace the secrets:
npm run setup:env -- --print # prints generated values to paste in
| Variable | Purpose |
|---|---|
DATABASE_URL | PostgreSQL connection string |
NEXT_PUBLIC_APP_URL | Public URL of this app. Builds the OAuth redirect URI, so it must match what the provider has registered |
CREDENTIALS_ENCRYPTION_KEY | 32 bytes (base64/hex). Encrypts stored provider tokens at rest |
DASHBOARD_PASSWORD + DASHBOARD_SESSION_SECRET | Gate the admin console. Without both, /dashboard is unreachable |
INTERNAL_JOB_SECRET | Authorizes the webhook delivery job |
REDIS_URL | Shared rate limit and idempotency state. Optional for one instance, required for more than one |
<SLUG>_CLIENT_ID / <SLUG>_CLIENT_SECRET | OAuth app per provider, e.g. CONTA_AZUL_CLIENT_ID |
The development defaults are published in this repository, so they are not secret. The app refuses to start in production while any of them is still in place, rather than running exposed.
Deploying for real is covered in docs/DEPLOYMENT.md.
Start with the integration guide: client, key, connection, first call, and what each provider does differently. The reference below is the short version; the live API reference is at /docs.
The key is the client, the service picks the system. A key belongs to exactly one client and reaches that client's connections and nothing else. Each request then says which of them it is for, by service name:
curl https://your-host/api/unified/v1/customers \
-H "Authorization: Bearer oip_live_..." \
-H "X-Provider: CONTA_AZUL"
X-Account-Token: <connection token> pins one exact connection instead, which is only needed when a client has two accounts on the same service. GET /api/unified/v1/connections lists what a client has, with the service name, the status and the token of each.
Scopes: a key carries what it may do, as read:contacts or write:*, chosen when it is issued. A call outside them is 403 FORBIDDEN before any provider is reached.
Pagination is cursor-based and provider-agnostic:
{ "items": [...], "hasMore": true, "nextCursor": "eyJwYWdlIjoyfQ", "totalItems": 120 }
Pass nextCursor back as ?cursor=. totalItems is best effort, because cursor based upstreams cannot report a total.
Idempotency: send Idempotency-Key on writes. Retrying with the same key replays the original response; reusing it with a different body returns 422.
Errors carry a stable code and a requestId (also in X-Request-Id). Upstream payloads are logged, never returned.
Capabilities: GET /api/unified/v1/providers returns the catalog and the exact operation matrix, and is public. A 501 NOT_SUPPORTED means the connected provider lacks that operation, and it is answered before any upstream call.
Webhooks: a client is told when one of its connections is made, breaks or is removed. Deliveries are signed and retried. See the integration guide.
Admin API: creating clients, issuing and rotating their keys, and registering their webhook endpoints, from your own product rather than from the dashboard. See docs/ADMIN.md.
Hosted connect: hand an end customer a one-time link and let them authorize their own provider account, in an iframe inside your product, in a popup, or from an email. They never see this dashboard, the link can attach an account to exactly one client, and your backend never holds their credentials. See docs/ADMIN.md.
Passthrough, for anything the unified model does not cover:
curl https://your-host/api/unified/v1/passthrough/pessoas?pagina=1 \
-H "Authorization: Bearer oip_live_..." \
-H "X-Provider: OMIE"
The same deployment is a remote MCP server at /api/mcp, so an AI agent can use a client's connected accounts without anyone writing a client:
claude mcp add --transport http openipaas https://your-host/api/mcp \
--header "Authorization: Bearer oip_live_..."
With the key alone, the server covers every account that client has connected, and each tool name starts with the account it belongs to (rd_station_crm__list_contacts). Adding X-Provider or X-Account-Token narrows it to one connection, with plain tool names.
Tools are derived from each account's capability matrix, so they differ per connected provider and nothing is written per provider. A scoped key gets a shorter list rather than tools that refuse. See docs/MCP.md.
An empty CRM makes for a bad first call: every list comes back {"data": []} and there is no way to tell a working integration from a broken one. This fills a trial account with fake companies, contacts and deals, through the unified API itself:
# Prints the plan and writes nothing
npm run seed:crm -- --api-key oip_live_... --account-token <account token>
# Writes
npm run seed:crm -- --api-key oip_live_... --account-token <account token> --confirm
Every record is named with a [sandbox] marker so it can be found and deleted later, and each resource is capped at 50 per run. Point it at a trial account, never at one with real customers in it.
npm run generate-provider bling
This scaffolds the folder (manifest, provider class, mapper stub, test) and prints the single registry line to add. The generated provider passes the contract suite immediately: it declares no capabilities and enables passthrough, so it is honest about what it can do from day one.
Then:
manifest.ts: base URL, auth, rate limit.npx vitest runThe manifest is the single source of truth: it drives the public catalog, the connect UI, the OpenAPI capability matrix and the 501 responses. Nothing else needs to know your provider exists.
| Provider | Category | Auth | Status |
|---|---|---|---|
| Conta Azul | Accounting | OAuth2 | Customers, products, sales, sellers, PDF, bulk |
| Omie | Accounting | App key/secret | Customers · passthrough |
| Tiny (Olist) | Accounting | OAuth2 | Passthrough only |
state (PKCE available per manifest).npm test
The contract suite in src/tests/providers/contract.test.ts runs against every registered provider, so a contribution either satisfies the shared contract or the build fails.
We want the largest open source catalog of B2B integrations in the world, from obscure local accounting systems to global CRM giants. The plugin architecture is designed so that adding one costs a folder, not a refactor.
Start with CONTRIBUTING.md. Commits need a
DCO sign off, which git commit -s adds
for you.
Apache License 2.0. Use it commercially, modify it, self host it, ship it inside your product. The only obligations, and only when you redistribute, are to keep the notices and state your changes.
Apache 2.0 rather than MIT for the express patent grant, which is what lets a corporate legal review approve it without an argument. See docs/LICENSING.md for the reasoning.