Connect your users to their apps
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
chore(sdk): generate plugin READMEs, npm metadata, and patch bumps (#1465) | 4 天前 | |
fix(www): add contact form | 1 个月前 | |
feat(mcp): subpath re-exports (mastra/langchain/llamaindex) + turnkey stdio server (#1726) * feat(mastra): add @corsair-dev/mastra ToolProvider for Mastra * feat(mastra): move to adapters/ and address review - move packages/mastra -> adapters/mastra; wire adapters/* into the workspace, publish-changed, deploy/pr-checks, and turbo filters - resolveTenant: a decodable connectionId is authoritative over the tenant function (authorize and resolve can't diverge) - add getToolSchema for the editor tool-detail view - add revokeConnection + supportsRevoke (via corsair manage.disconnect) - peer @mastra/core >=1.64.0; form-field docstrings; README tool recipes - demo/mastra: minimal Mastra playground app * fix(mastra): harden tenant isolation and close review gaps - resolveTenant: the configured tenant is authoritative. A pinned string is never overridden by a connectionId, and when the caller is known a connectionId naming a different tenant is rejected (no cross-tenant access). A fresh connection under a function resolver throws instead of silently opening OAuth under a fallback tenant (Mastra passes no context to authorize). - Document connectionId as an unsigned, server-minted handle. - Require zod ^4.4.0 so z.unknown() rejects omitted required fields. - CI: build/test the full lane over adapters/* too, not just packages/*. - demo: pin the LLM gateway host; ignore SQLite sidecar files. * fix(mastra): optional @mastra/core peer, run checks in CI, document fresh-auth limit * feat(mcp): re-export @corsair-dev/mastra via ./mastra subpath The Mastra ToolProvider now has one home: @corsair-dev/mastra. mcp re-exports it from a dedicated subpath instead of carrying a copy, so the two never drift. Subpath, not the main barrel: the provider extends @mastra/core BaseToolProvider, so importing it evaluates @mastra/core. Keeping it under ./mastra means consumers of @corsair-dev/mcp on other frameworks never load @mastra/core (optional peer). Bump the @mastra/core peer to >=1.64.0 to match what the provider needs. * fix(mcp): pin demo LLM baseURL to the gateway * feat(mcp): re-export langchain and llamaindex adapters on subpaths * docs(adapters): add LangChain and LlamaIndex adapter pages * feat(mcp): add env-configured stdio bin for MCP registries * Update package.json * fix(mcp): correct corsair_permissions schema in bin and demos The turnkey stdio bin and the sqlite demos created corsair_permissions with (account_id, endpoint, status), but the permissions runtime inserts and queries token, plugin, args, tenant_id, expires_at and error. Any permission-gated operation would fail with missing-column errors. Align all three schemas with demo/testing/migration.sql. * fix(mastra): reject tool slugs outside the exposed API operations resolveToolsVNext invoked any dotted path the caller passed as a tool slug, so a management/non-API operation (e.g. manage.disconnect) could be executed even though discovery only exposes type: 'api' operations (CWE-470). Validate each slug against the discovered API set at the single resolution chokepoint, after tenant resolution. Adds a guard assertion. * test(langchain): add runnable demo mirroring demo/mastra Real-usage harness for @corsair-dev/langchain: corsairTools -> LangGraph createReactAgent, model routed through the Corsair LLM gateway, sqlite store with the corrected corsair_permissions schema. Run with pnpm --filter corsair-langchain-demo test (needs real Hub + gateway keys). * fix(mcp): reject databases with an outdated permissions schema CREATE TABLE IF NOT EXISTS is a no-op against a database created by an older schema, so a reused CORSAIR_DB_PATH could lack the permission-runtime columns and fail with missing-column errors mid-operation. Check the corsair_permissions columns at startup and exit with a clear message if the database is incompatible. Also removes internal comment markers. * fix(mcp): run plugins with managed auth in the turnkey bin The bin supplies Hub credentials but instantiated each plugin with no options, so plugins defaulted to api_key auth and a fresh npx run had no usable credentials. Pass authType: 'managed' to match the Hub-backed flow. Also tighten the sqlite handle to a typed interface and document the remaining dynamic-import assertions. | 4 天前 | |
feat(mcp): subpath re-exports (mastra/langchain/llamaindex) + turnkey stdio server (#1726) * feat(mastra): add @corsair-dev/mastra ToolProvider for Mastra * feat(mastra): move to adapters/ and address review - move packages/mastra -> adapters/mastra; wire adapters/* into the workspace, publish-changed, deploy/pr-checks, and turbo filters - resolveTenant: a decodable connectionId is authoritative over the tenant function (authorize and resolve can't diverge) - add getToolSchema for the editor tool-detail view - add revokeConnection + supportsRevoke (via corsair manage.disconnect) - peer @mastra/core >=1.64.0; form-field docstrings; README tool recipes - demo/mastra: minimal Mastra playground app * fix(mastra): harden tenant isolation and close review gaps - resolveTenant: the configured tenant is authoritative. A pinned string is never overridden by a connectionId, and when the caller is known a connectionId naming a different tenant is rejected (no cross-tenant access). A fresh connection under a function resolver throws instead of silently opening OAuth under a fallback tenant (Mastra passes no context to authorize). - Document connectionId as an unsigned, server-minted handle. - Require zod ^4.4.0 so z.unknown() rejects omitted required fields. - CI: build/test the full lane over adapters/* too, not just packages/*. - demo: pin the LLM gateway host; ignore SQLite sidecar files. * fix(mastra): optional @mastra/core peer, run checks in CI, document fresh-auth limit * feat(mcp): re-export @corsair-dev/mastra via ./mastra subpath The Mastra ToolProvider now has one home: @corsair-dev/mastra. mcp re-exports it from a dedicated subpath instead of carrying a copy, so the two never drift. Subpath, not the main barrel: the provider extends @mastra/core BaseToolProvider, so importing it evaluates @mastra/core. Keeping it under ./mastra means consumers of @corsair-dev/mcp on other frameworks never load @mastra/core (optional peer). Bump the @mastra/core peer to >=1.64.0 to match what the provider needs. * fix(mcp): pin demo LLM baseURL to the gateway * feat(mcp): re-export langchain and llamaindex adapters on subpaths * docs(adapters): add LangChain and LlamaIndex adapter pages * feat(mcp): add env-configured stdio bin for MCP registries * Update package.json * fix(mcp): correct corsair_permissions schema in bin and demos The turnkey stdio bin and the sqlite demos created corsair_permissions with (account_id, endpoint, status), but the permissions runtime inserts and queries token, plugin, args, tenant_id, expires_at and error. Any permission-gated operation would fail with missing-column errors. Align all three schemas with demo/testing/migration.sql. * fix(mastra): reject tool slugs outside the exposed API operations resolveToolsVNext invoked any dotted path the caller passed as a tool slug, so a management/non-API operation (e.g. manage.disconnect) could be executed even though discovery only exposes type: 'api' operations (CWE-470). Validate each slug against the discovered API set at the single resolution chokepoint, after tenant resolution. Adds a guard assertion. * test(langchain): add runnable demo mirroring demo/mastra Real-usage harness for @corsair-dev/langchain: corsairTools -> LangGraph createReactAgent, model routed through the Corsair LLM gateway, sqlite store with the corrected corsair_permissions schema. Run with pnpm --filter corsair-langchain-demo test (needs real Hub + gateway keys). * fix(mcp): reject databases with an outdated permissions schema CREATE TABLE IF NOT EXISTS is a no-op against a database created by an older schema, so a reused CORSAIR_DB_PATH could lack the permission-runtime columns and fail with missing-column errors mid-operation. Check the corsair_permissions columns at startup and exit with a clear message if the database is incompatible. Also removes internal comment markers. * fix(mcp): run plugins with managed auth in the turnkey bin The bin supplies Hub credentials but instantiated each plugin with no options, so plugins defaulted to api_key auth and a fresh npx run had no usable credentials. Pass authType: 'managed' to match the Hub-backed flow. Also tighten the sqlite handle to a typed interface and document the remaining dynamic-import assertions. | 4 天前 | |
docs(figma): customize file examples (#1314) | 2 天前 | |
fix: update docs and plugin icons for new plugins | 6 天前 | |
fix(tunnel): reap orphaned frpc so a dev tunnel can't wedge itself (#1732) | 1 天前 | |
fix(ci): skip uninstalled plugins in readmes check (#1727) | 3 天前 | |
docs(skill): reframe the corsair skill around the SDK + Hub (#1436) Co-authored-by: Dev Jain <devrjain32200@gmail.com> | 11 天前 | |
fix(oss): block unclaim after a PR is linked (#1680) | 6 天前 | |
feat(frpc): ship frpc as per-platform npm packages (#803) * feat(frpc): ship frpc as per-platform npm packages Add @corsair-dev/frpc-<platform>-<arch> optional-dependency packages (the esbuild/Turbopack pattern) so corsair resolves frpc from the npm registry instead of a postinstall download — no build script for pnpm to block. resolveFrpcBinary prefers the installed platform package and falls back to the existing postinstall cache (kept for now). Binaries are materialized at publish by scripts/prepare-frpc-packages.mjs (SHA256-verified, frp Apache-2.0 LICENSE + NOTICE bundled), git-ignored, and version-locked to corsair via workspace:*. * fix(frpc): materialize binaries at publish + guard version reuse Address review: (1) each platform package now has a prepack hook that runs prepare-frpc-packages.mjs for its own target, so publishing from a fresh checkout always includes the binary in the tarball; (2) prepare skips only when a .frpc-version marker matches the current FRPC_VERSION, so a binary left from a previous version is re-downloaded + re-verified rather than republished stale. prepare accepts an optional single-target arg for the per-package hook. * chore(frpc): bump platform packages to 0.1.115 (lockstep with corsair) * fix(frpc): add build script so publish tooling materializes the binary publish-changed.mjs runs `pnpm --filter <pkg> build` before publishing each package. The frpc packages had no build script; add one that runs the prepare step (prepack delegates to it), so both release paths — publish-changed.mjs and the turbo `pnpm release` — materialize each binary, not just the prepack hook. * fix(frpc): drop build task + fix EXDEV in prepare script The build task I added made turbo run prepare-frpc-packages.mjs for all six packages during the www app deploy (they are in www's dep graph via corsair's optionalDeps), which both wasted work and failed. Revert to prepack-only: publish-changed.mjs's `pnpm --filter build` is a lenient no-op and `pnpm publish` still fires prepack; turbo no longer runs anything for these packages. Also fix a real latent bug the deploy surfaced: prepare renamed the binary from /tmp into the package dir, which is EXDEV (cross-device) on Linux CI. Use copyFileSync so it works regardless of filesystem. * feat(cli): show the CORSAIR banner + live URL on `corsair http` The banner was orphaned in the old `corsair setup` flow; wire it into the `http` command's success output (it printed plain lines before). Swap the pirate glyph for a celebratory banner + the live tunnel URL. * chore(pr-gate): exclude frpc-* binary packages from the plugin gate The frpc-<platform>-<arch> packages are prebuilt binary shims for the dev tunnel, not integrations, so the plugin rules (per-package tests, demo video, one-plugin-per-PR scope) don't apply. Skip them in pluginOf so the gate no longer flags this PR. * chore(scripts): exclude frpc-* binary packages from plugin validators validate:plugins and validate:docs both scan packages/* and treat every non-ignored dir as an integration, so the frpc-<platform>-<arch> binary shims tripped the structural checks (index.ts, endpoints, jest). Skip them the same way the PR gate does. * fix(frpc): make frpc-binary parse under ts-jest and resolve in the ESM build createRequire(import.meta.url) is ESM-only; ts-jest transpiles this file to CJS, where import.meta and a `const require` both fail to parse — breaking every suite that transitively imports it. Seed createRequire from __filename (tsup `shims` defines it in the ESM build), rename the local to nodeRequire, and map corsair/hub to source in jest so slack/linear don't resolve it to the built dist that now carries the import.meta shim. * refactor(frpc): single source of truth for version + checksums The pinned frp version and the SHA256 table the download paths verify against were duplicated across postinstall-frpc.mjs and prepare-frpc-packages.mjs, kept in sync only by a comment — a drift risk on a security-relevant constant. Extract both to scripts/frpc-release.json, read by each script, and ship it via the package `files` so the end-user postinstall resolves it too. frpc-binary.ts keeps its version literal (a runtime cache-path segment, non-security) with a pointer to the JSON. * chore(frpc): bump corsair + frpc packages to 0.1.117 npm latest is 0.1.116 (without optionalDependencies) and 0.1.115 is already published, so the frpc optional deps only reach `npm i corsair` once latest advances past 0.1.116. workspace:* pins each frpc package to the exact 0.1.117 at publish time (verified via pnpm pack). | 28 天前 | |
fix: updating package.json, adding builder, adding linter, optional peer dependencies, etc | 9 个月前 | |
fix: updating package.json, adding builder, adding linter, optional peer dependencies, etc | 9 个月前 | |
type fix for trpc router in demo | 6 个月前 | |
feat(ci): automated plugin PR review loop (#403) | 2 个月前 | |
feat(ci): automated plugin PR review loop (#403) | 2 个月前 | |
ci: add PR checks workflow, CI/CD automation, and code quality tooling (#259) (#268) | 2 个月前 | |
fix: update contributing.md (#1689) | 6 天前 | |
new auth encryption and decryption with initial cli | 7 个月前 | |
fix: update readme | 19 天前 | |
fix(www): format landing and oss pages (#400) | 2 个月前 | |
ci: skip plugin gate for plugin-docs.yaml PRs (#1248) | 12 天前 | |
chore(sdk): generate plugin READMEs, npm metadata, and patch bumps (#1465) | 4 天前 | |
feat(core): tool-call route (/call) behind an auth gate (#1725) * feat(core): tool-call route resolution with reason-tagged permission errors Adds resolveCall + listRegisteredOps: per-(instance,tenant) client cache so concurrent same-tenant calls share one refresh single-flight, op-tree walk, and error normalization to 401/403/502/500 with response hygiene (never spreads ApiError.request, so the Authorization header can't leak). PermissionRequiredError gains a reason discriminator (denied/policy/ timeout/pending) so a non-TS caller over the route can tell a hard deny from an approval a human still has to grant. * feat(core): expose /call behind an auth gate, keep capability legs public Wires the call route into the management handler: GET /call lists registered ops, POST /:tenant/:plugin/call/:op invokes one. Both are off unless the host owns access control — set unsafeAllowUnauthenticated (its own backend fronts the handler) or supply an authenticate hook (e.g. a Bearer project key on a hosted runtime), which also enables the route. The authenticate hook fronts every route except those flagged public: health, and the OAuth-callback / connect-resolve / permission-lookup legs that arrive without the project key and are guarded by an unguessable state/token instead. * fix(core): harden /call per review — scope, own-prop ops, error leak, cache - route URL tenant through resolveScopedTenant so resolveTenant stays authoritative (null → 401); other tenant routes already did this - walkToBoundFn: own-property only, so constructor/__proto__ resolve to unknown_op not Object methods - internal_error returns a generic message; original logged server-side (CWE-209) - LRU-cap the per-tenant client cache (unbounded URL tenant cardinality) * fix(core): LRU never evicts an in-flight tenant client Naive eviction could drop a tenant's client mid-refresh; a rebuilt client has its own single-flight store, so two concurrent refreshes could stale-write the rotating token. Refcount in-flight ops per tenant and evict only idle clients. * fix(core): never evict the just-inserted tenant client evictIdle ran before resolveCall marked the new op in-flight, so with every older client busy it could drop the client just created. Exclude the inserted tenant from eviction (safe overshoot instead). * fix: regenerate merge-corrupted lockfile; bump corsair to 0.1.132 The origin/main merge text-merged pnpm-lock.yaml into an inconsistent state (ts-jest importer refs pointed at @babel/core@7.29.7 snapshots that weren't emitted), failing --frozen-lockfile in CI. Regenerated from manifests. * fix: regenerate lockfile after main merge | 2 天前 | |
feat(adapters): add LangChain and LlamaIndex tool adapters (#1628) * feat(adapters): add LangChain and LlamaIndex tool adapters Expose Corsair operations as native framework tools — one typed tool per operation. - corsair core: buildCorsairTools + formFieldToZod, a framework-agnostic op→tool builder (discover, schema→zod v4, invoke by dotted path) - @corsair-dev/langchain, @corsair-dev/llamaindex: thin wrappers over it, each dynamic-importing its optional framework peer - workspace: include adapters/* * fix(adapters): preserve endpoint constraints via raw Zod schema Add getInputSchema() to inspect.ts to expose the raw ZodTypeAny from plugin.endpointSchemas. buildCorsairTools now prefers this over the lossy formFieldToZod round-trip, so min/max/regex/refinements defined on the endpoint are reflected in the generated tool schema. Document unknown types on execute results and toContent — each Corsair plugin returns a distinct, opaque shape serialized to string by adapters. In the LlamaIndex adapter, parse args through op.schema before invoking so invalid model-generated inputs are rejected at the boundary. Update READMEs to route model calls through llm.corsair.dev and document why @llamaindex/core 0.6.23 is retained despite the npm deprecation notice (the llamaindex meta-package itself depends on @llamaindex/core 0.6.x; no non-deprecated successor exposes the same tool API). Add constraint-preservation test covering min/max/int on a generated tool schema. * fix(adapters): narrow unknown types and justify remaining assertions - Narrow `unknown[]`/`(args: unknown)` stubs in tests and check files to `Record<string, unknown>` where the call site makes the shape knowable - Add minimal comments on the three `as unknown as` assertions in adapters.test.ts (fake objects that satisfy only what the runtime reads) - Comment `args: Record<string,unknown>` in langchain tool callback and the `as Record<string,unknown>` cast in llamaindex (ZodTypeAny.parse returns unknown; cast is safe because all op schemas are top-level objects) * test(adapters): justify Record<string,unknown> tool-arg fixtures Document why the stub operation args use Record<string,unknown>: tool args are model-generated and validated by each tool's Zod schema before the stub runs, so their per-operation shape is arbitrary at that boundary. * chore(adapters): trim narrating comments; add llamaindex bad-arg check Address code-review: reduce JSDoc/inline comments to non-obvious intent across the shared builder, both adapters, and their checks; add a bad-arg rejection assertion to the llamaindex check for parity with langchain. * build(adapters): keep check files out of the published dts The declaration build shipped a stray *.check.d.ts.map into dist; scope it to src minus *.check.ts so the package publishes only its real modules. * chore(corsair): release 0.1.129 with buildCorsairTools and AnyCorsairInstance fix | 6 天前 | |
fix: resolve cyclic dependencies, formatting drift, and CI errors (#276) | 2 个月前 | |
fix tsconfig and root tsconfig for composite and incremental | 7 个月前 | |
ci: scope PR Checks to the diff and run the plugin gate first (#1104) * perf(turbo): hash www env vars and tsconfig.base, not the lockfile * ci(deploy): pin Node 24, freeze the lockfile, restore turbo cache * ci: add job timeouts and labeler concurrency * feat(ci): classify PRs into plugin, www, full, and docs lanes * ci: run the plugin gate first and scope PR Checks to the diff * fix(ci): stop shell-interpolating package names and persist CodeQL creds * fix(ci): skip live *.api.test.ts without dropping webhook tests | 18 天前 | |
lint fixes | 8 个月前 |
以下内容由 AI 翻译,如有问题请 点此提交 issue 反馈
Corsair:连接你的用户与他们的应用
Corsair 是一个功能完备的产品集成平台,提供无缝的开发者体验。你可以构建任何应用,从跨所有集成运行的 Agent,到供用户接入任意服务的多租户仪表盘。
为什么需要它?
不止于 MCP
大多数 Agent 集成工具仅支持 MCP。Corsair 基于 REST API 构建,因此同一套集成层既可用于 Agent、后端服务,也可用于你的客户所使用的仪表盘。
所有集成,统一语法
你的 Agent 接触的第三方 API 越多,需要编写的胶水代码就越多。Corsair 为每个集成提供统一的语法,并负责维护其背后的适配器。一次接入,即可避免为每个新工具重复搭建底层管道。
开源,数据属于你
封闭式集成平台会将用户的令牌和数据存放在你无法审查或迁出的基础设施上。Corsair 是开源的。你可以自托管,也可以使用 Hub 让我们来处理 OAuth 刷新和 Webhooks。无论哪种方式,数据都始终属于你。
贡献指南
我们欢迎提交针对核心库、文档、工具链以及新集成插件的 PR。完整流程请阅读 CONTRIBUTING.md。
对于新的集成,请先在 OSS Integrations page 上认领,然后再提交一个 issue,说明你要添加的 API。有问题?请在 Discord 中询问。
许可证
本项目基于 Apache License, Version 2.0 授权发布。详见 LICENSE。
