HelpCode-ai/anythingmcp
Self-hosted, open-source MCP gateway: turn any API, database or MCP server into custom connectors for Claude, ChatGPT, Gemini, Copilot & Cursor — no code. Convert REST, SOAP, WSDL, GraphQL & SQL to MCP, with OAuth2, RBAC & audit log. 175+ pre-built adapters (Deutsche Bahn, weclapp, Etsy, DHL, Shopware…)
🐛 Fixed
- MCP server no longer 500s on duplicate tool names. A connector that produced two tools with the same name could take down the `/mcp` endpoint; tool names are now deduplicated. (#313)
📦 Self-hosting
- Run multiple stacks on one host. `docker-compose.yml` now derives the project, network, volume and container names from `COMPOSE_PROJECT_NAME` (default `amcp`, so existing setups are unchanged). Set it to isolate a second instance without name collisions. (#316)
- Single source of truth for the Node version in the Dockerfile (`ARG NODE_VERSION`), and an explicit `engines.node >=22` so the supported minimum is machine-readable. (#316)
- `.env.example` documents `COMPOSE_PROJECT_NAME` and the internal-`PORT` vs host-`BACKEND_PORT` distinction.
📦 Packaging / license
- AnythingMCP is now licensed under AGPL-3.0 (OSI-approved open source), with operator-only cloud features kept under a separate commercial license in `ee/` directories. Self-hosting is unaffected. (#314, #315)
📦 Upgrade
- ```bash
- docker compose pull && docker compose up -d
- ```
- No configuration changes required.
🐛 Fixes
- auth: membership-based tenant isolation for `/mcp/:serverId` — multi-org users can reach every workspace they belong to; cross-org access stays denied (#311)
- auth: resolve OAuth org by id OR email — fixes a production 403 lockout where legitimate owners were denied their own MCP servers after OAuth login (#309)
- dashboard: Claude Desktop connection config now uses `type: "http"` (was the invalid `"url"`, which Claude Desktop silently skipped) (#310)
- weclapp: fix filter 400s via a general `__rawquery` engine passthrough — weclapp `property-operator` filters now work (#308)
📦 Connectors
- 8 reverse-engineered read-only connectors live: Playtomic (+ public), OpenTable, Resy, Vinted, Untappd, Idealista, Trenitalia
- Etsy migrated to OAuth2 with automatic refresh-token rotation
📦 Notes
- No breaking changes. Tenant isolation remains fail-closed and was verified against production data.
📦 Proxy / Web-Unblocker (#280, #281, #282)
- Per-tool opt-in: `mcp_tools.use_proxy` (seeded from the adapter spec's `useProxy`), toggled via a per-tool UI checkbox shown only when `CONNECTOR_PROXY_URL` is set.
- Cloud rate limit: `PROXY_RATE_LIMIT_DEFAULT` (default 100) proxy calls/hour per workspace; over-cap returns an explicit error. Overridable only by a service admin via `organizations.proxy_rate_limit` (no API).
- Engine: REST + GraphQL attach an `HttpsProxyAgent`. SOAP/DB/MCP ignore it.
- Adapters shipped with `useProxy: true`: Deutsche Bahn, Playtomic (+ public), Sorare, OpenTable, Resy, Vinted, Untappd, idealista, Trenitalia, ImmobilienScout24, Etsy, Mercado Libre.
- Docs: `docs/connectors/proxy.md`.
📦 Onboarding (#272, #273, #276)
- In-app `/welcome` wizard with a gate-aware redirect (respects LicenseWall + license-choice).
- Email drip cron for users who registered but never created a connector.
📦 Connectors
- Help Scout → OAuth2 client-credentials with auto-refresh (#277).
- Clockify → expanded to 18 tools (#279).
- Sendcloud → `to_country` required to avoid 14s "all carriers" calls (#274).
🐛 Fixes
- Audit: resolve `user_id` from the JWT email so cloud analytics aren't always NULL (#275).
- License wall: hide on logout + auth routes, clear stale block state (#278).
📦 Diff
- [`v0.1.31...v0.1.32`](https://github.com/HelpCode-ai/anythingmcp/compare/v0.1.31...v0.1.32)
📦 Adapters
- #250 — 7 reverse-engineered SaaS adapters: OpenTable, Resy, Vinted, Untappd, idealista, Trenitalia, Trainline
- #266 — Remove Trainline (TOS / instability — removed shortly after #250)
- #267 — Etsy → migrate to OAuth2 with refresh-token auto-rotation (long-lived auth, no more manual token rotation)
- #268 — Deutsche Bahn → rewrite adapter against bahn.de directly (drop the third-party `v6.db.transport.rest` proxy)
🐛 Fixes
- #249 — Playtomic logo: add `fill` style so the wordmark actually renders
📦 Diff
- [`v0.1.30...v0.1.31`](https://github.com/HelpCode-ai/anythingmcp/compare/v0.1.30...v0.1.31)
📋 What's Changed
- Fix/dropdown option placement on touch by @ozer0602 in https://github.com/HelpCode-ai/anythingmcp/pull/235
- license: soft-warn cap policy + /usage endpoint + UsageBanner by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/239
- Update README to remove 'Fork' instruction by @CatWotan in https://github.com/HelpCode-ai/anythingmcp/pull/240
- connectors: render brand logos in the installed-connector list by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/241
- store: align Adapter Store cards with the marketing-site Marketplace by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/242
- connectors: add google-analytics-4 (Admin + Data + Realtime + Funnel) by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/243
- adapters: SAP Concur + Business One + S/4HANA Cloud + 2 engine extensions by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/245
- store: instructions panel + reveal-toggle in install modal + GA4 logo by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/244
- + 3 more
✨ New Contributors
- @CatWotan made their first contribution in https://github.com/HelpCode-ai/anythingmcp/pull/240
- Full Changelog: https://github.com/HelpCode-ai/anythingmcp/compare/v0.1.29...v0.1.30
📋 What's Changed
- Fix Copy button on http by @D3nisty in https://github.com/HelpCode-ai/anythingmcp/pull/223
- docs(sorare): embed launch video on the 3 announcement landings (DSGVO 2-click) by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/224
- docs(sorare): YouTube video embed on every Sorare guide (DSGVO 2-click) by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/226
- auth: mandatory email verification in cloud mode by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/227
- feat(settings): redesign organization settings page by @mirkopoloni in https://github.com/HelpCode-ai/anythingmcp/pull/229
- fix(css): add custom chevron arrow for select elements and adjust pad… by @ozer0602 in https://github.com/HelpCode-ai/anythingmcp/pull/228
- whatsapp-business: add WhatsApp Business Cloud API connector + multilingual guides by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/230
- connectors: add WordPress + WooCommerce adapters by @keysersoft in https://github.com/HelpCode-ai/anythingmcp/pull/231
- + 5 more
✨ New Contributors
- @D3nisty made their first contribution in https://github.com/HelpCode-ai/anythingmcp/pull/223
- @mirkopoloni made their first contribution in https://github.com/HelpCode-ai/anythingmcp/pull/229
- @ozer0602 made their first contribution in https://github.com/HelpCode-ai/anythingmcp/pull/228
- Full Changelog: https://github.com/HelpCode-ai/anythingmcp/compare/v0.1.28...v0.1.29
Follow-ups to v0.1.27 — see #221. LicenseWall now blocks the cloud UI when an org has no license (was silently allowed through after the per-org isolation fix). dynamic-mcp-tools now passes organizationId through to checkLicenseActive so MCP tool calls work in cloud.
📦 Highlights
- Security/billing fix: cross-tenant license entitlement leak in cloud mode.
- `getCurrentLicense`: in cloud, returns `null` when the calling org has no license. No global pointer fallback, no auto-binding of orphan licenses.
- `verifyLicense`: scoped to `organizationId` in cloud.
- `setLicenseKey` / `requestTrialLicense`: stop writing the global pointer in cloud; persist `organizationId` on the trial record.
- `verifyOnStartup`: no-op in cloud.
- Self-hosted single-tenant behavior is unchanged — the `site_settings.license_key` mechanism still works for self-hosted installs.
📦 Companion PR
- anythingmcp#219 — the fix + 6 unit tests
- anythingmcp#220 — version bump
📦 Highlights
- End-to-end license auto-activation between the cloud instance and `anythingmcp.com/pricing`:
- Activate License Key field is now always visible on `/settings/license` for admins — including during an active cloud trial. Previously hidden until the trial expired, which surprised customers who purchased a license mid-trial.
- `Upgrade Plan` / `View Plans` links carry a `return_url` pointing back to the originating cloud instance, driven by `NEXT_PUBLIC_MARKETING_URL` (default `https://anythingmcp.com`).
- New `/settings/license/activate` callback page: reads `?key=AMCP-...`, validates the format, calls `PUT /api/license/key` if an admin is signed in, otherwise bounces through `/login?redirect=...` and resumes activation after sign-in.
- Companion change on the marketing site ([anythingmcp-website#57](https://github.com/HelpCode-ai/anythingmcp-website/pull/57)): after a successful Stripe checkout, the marketing site redirects the customer back to `${return_url}?key=<licenseKey>` (host allowlisted to prevent open-redirects), turning the email-and-paste loop into a one-click handoff.
📦 Companion PRs
- anythingmcp#216 — cloud frontend
- anythingmcp-website#57 — marketing site
- anythingmcp#217 — version bump
✨ New: Sorare Fantasy Football adapter (18 tools)
- Tools (live-audited against api.sorare.com with real credentials, 17/19 happy-path pass, the two remaining are deliberate NOT_FOUND probes against fake IDs):
- Identity & wallet: \`sorare_current_user\`, \`sorare_wallet_balance\`, \`sorare_my_trophies_summary\`, \`sorare_user_by_slug\`
- Cards & inventory: \`sorare_list_my_cards\`, \`sorare_get_card_by_slug\`, \`sorare_list_player_cards\`
- Players & form: \`sorare_search_player\`, \`sorare_player_recent_scores\`, \`sorare_player_floor_price\`
- Market & auctions: \`sorare_live_sale_offers\`, \`sorare_token_prices\`, \`sorare_get_auction\`, \`sorare_get_lineup\`
- Generic GraphQL escape hatch (auto-injected for every GraphQL connector): \`sorare_graphql_schema_url\`, \`sorare_graphql_schema\`, \`sorare_graphql_query\`, \`sorare_graphql_mutation\`, \`sorare_graphql_subscription\`
✨ New: GraphQL schema-slicing proxy — every GraphQL connector, automatically
- Every connector of type \`GRAPHQL\` — both catalog adapters and user-created connectors — automatically receives five generic helper tools at creation time:
- | Tool | What it does |
- |---|---|
- | \`<prefix>_graphql_schema_url\` | Returns the URL of the SDL. |
- | \`<prefix>_graphql_query\` / \`_mutation\` / \`_subscription\` | Execute arbitrary GraphQL operations; the document and variables are tool params. |
- Catalog adapters get them via \`adapters/catalog.ts.withGraphqlBuiltins\`; user-created connectors get them via \`connectors.controller.ts\`, parallel to the existing DATABASE auto-tools logic.
- The \`GraphqlSchemaService\` caches the SDL per URL for 24 h and parses block boundaries with a tiny line-based scanner — no full GraphQL parser dependency.
📦 Engine improvements
- \`GraphqlEngine\` learns \`method: \"static\"\` (return \`endpointMapping.path\` verbatim, no HTTP call) and \`method: \"schema\"\` (delegate to \`GraphqlSchemaService\`).
- A new \`path: \"\$paramName\" + variablesFromParam\` form lets generic tools take the GraphQL document and the variables map from tool params at runtime (used by the three op-builtins).
- \`AdapterMeta\` gains optional \`featured?: boolean\` and \`priority?: number\` so the marketing site can rank adapters in the home rail without a code change there.
📦 Schema & migration
- Prisma schema: \`AuthType\` enum gains \`LOGIN_TOKEN\`; new \`ConnectorAuthCache\` model. Migration \`20260518000000_add_login_token_auth\` ships in this release.
📝 Documentation
- New: [\`docs/guides/sorare-to-mcp.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/guides/sorare-to-mcp.md), [\`connect-sorare-to-claude.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/guides/connect-sorare-to-claude.md), [\`connect-sorare-to-chatgpt.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/guides/connect-sorare-to-chatgpt.md), [\`connect-sorare-to-openclaw.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/guides/connect-sorare-to-openclaw.md), [\`connect-sorare-to-cloud.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/guides/connect-sorare-to-cloud.md).
- New: [\`docs/connectors/login-token-auth.md\`](https://github.com/HelpCode-ai/anythingmcp/blob/main/docs/connectors/login-token-auth.md).
- \`docs/tool-definition.md\` gets a LOGIN_TOKEN authConfig section and a GraphQL section covering \`method: \"static\"\`, \`method: \"schema\"\`, and the \`\$param + variablesFromParam\` pattern.
- README: new 🎮 Gaming & Web3 — featured rail putting Sorare in front, plus a Featured adapter walkthroughs sub-section under Connector guides linking the five Sorare guides for in-repo discoverability.
🐛 Fixes
- Sale-offer prices came back as zero because the query read \`senderSide.amounts\` — for a sale offer the sender is the seller, not the buyer. Switched \`sorare_live_sale_offers\` and \`sorare_get_card_by_slug\` to \`receiverSide.amounts\` so prices actually show up.
- Several Sorare query field names were wrong against the real schema (\`football.players(search:…)\`, \`currentUser.football.myCards\`, \`Player.cards\`, \`So5AppearanceBonusInterface.name\`). All rewritten against the production SDL.
- The cloud went down briefly after #199 because \`McpServerModule\` registers its own copy of \`RestEngine\` / \`GraphqlEngine\` and didn't have \`LoginTokenService\` as a provider — fixed in #201.
🧪 Tests
- 746 backend tests pass (up from 694 at v0.1.24). New coverage:
- \`LoginTokenService\` unit specs (login flow, cache hit, force-relogin, fallback TTL, missing token error).
- \`GraphqlSchemaService\` unit specs (full / type slice / search / summary / cache).
- \`GraphqlEngine\` specs for the new \`static\` / \`schema\` / \`\$param\` paths.
- \`graphql-builtins\` unit specs (slugify edge cases + five-tool shape).
- Catalog parametrised tests now assert every GRAPHQL adapter exposes the five builtins.
📦 Connector import / parsing
- #163 — OpenAPI 3.1 docs (FastAPI ≥ 0.100, NestJS modern, spring-doc 3.x, Hono) now import cleanly. Internal normalizer downgrades 3.1-only constructs (\`type: [X,'null']\`, \`anyOf+null\`, \`const\`, \`examples\` plural, \`exclusiveMinimum:<n>\`) to their 3.0 equivalents and relabels the document to \`3.0.3\` so swagger-parser accepts it. \`info.summary\` stripped defensively.
- #168 — Re-importing a spec no longer wipes operator customisations. Tools are matched by \`operationId\` first, then \`(method, path)\`. Custom \`responseMapping\` and the operator's \`isEnabled\` toggle survive. Tools removed from upstream get a \`deprecated\` badge instead of staying as zombies; role assignments and invocation history preserved.
📦 Tool runtime
- #169 — MCP tool param schemas use \`z.coerce.*\` for \`integer\` / \`number\` / \`boolean\` / \`date-time\`, so clients that serialize arguments as strings (\`{\"top_k\": \"5\"}\`) pass validation. Coercion still rejects non-coercible strings (\`\"abc\"\`).
🐛 Test / debug UX
- #165 — \`Connector.healthcheckPath\` auto-detected from imported OpenAPI specs (\`/health\`, \`/healthz\`, \`/_health\`, \`/ping\`, \`/status\`, or first GET with no required params). Editable from the connector detail page. Test response now classifies the result as \`ok\` / \`auth_failed\` (401–403) / \`not_found\` (404 + hint) / \`unreachable\` (DNS/SSRF/timeout) / \`error\`. UI banners coloured by kind.
- #162 — All public-API DTOs decorated with \`@ApiProperty\`. \`/api/docs-json\` now exposes proper schemas for everything (CreateConnectorDto, LoginDto, ImportToolsDto, …). Tool test endpoint accepts MCP-standard \`{ arguments: {...} }\` alongside legacy \`{ params: {...} }\`.
🔒 Security / on-prem
- #166 — SSRF allowlist editable from \`/admin/settings#ssrf\` (global, ADMIN-only). DB-backed list merges with \`SSRF_ALLOWED_HOSTS\` env var. Failing connector tests due to SSRF carry a \`suggestedFix\` link straight to the allowlist page.
✨ DB migrations (both additive, nullable, no backfill)
- \`connectors.healthcheck_path\`
- \`mcp_tools.operation_id\`, \`mcp_tools.deprecated_at\`
Silences `Dynamic tool 'X' already registered in module — Overwriting.` warnings emitted at boot. The internal `ToolRegistry` correctly handles cross-tenant tool-name collisions; only the upstream single-tenant `@rekog/mcp-nest` registry was generating noise. The fix registers each name on the upstream registry only when it first appears, and releases it only when the last entry leaves. See #152 for details.
✨ New connector
- HR WORKS v2 — full read access to the German HR/payroll platform: 30 tools across persons, absences, sick leaves, remote work, working times, projects, applicants, holidays, cost centers.
📦 Infrastructure
- Dependabot auto-merge workflow + branch protection on \`main\` with required CI checks. Patch/minor npm and github-actions PRs now auto-merge once CI is green; majors and runtime bumps are labelled \`needs-review\` for human triage.
- CI: rxjs duplicate-Observable fix — root override + backend pin to deduplicate rxjs across the workspace, unblocking the @nestjs/cli 11.0.21 bump and future nestjs upgrades.
📦 Dependency bumps merged
- next 16.2.4 → 16.2.6 (security fixes), react patch
- soap 1.7.1 → 1.9.1
- graphql 16.13 → 16.14
- @rekog/mcp-nest 1.9.6 → 1.9.9
- @nestjs/cli 11.0.16 → 11.0.21, @nestjs/testing 11.1.18 → 11.1.19 (via lockfile refresh)
- prisma + @prisma/client (group)
- jest + ts-jest (group)
- @types/* (group)
- + 2 more
🐛 Code fixes
- Frontend: fix \`use-before-define\` in \`connectors/store/page.tsx\` and \`settings/license/page.tsx\` (eslint-plugin-react-hooks 7.1.x rule).
🐛 Fixes (from #135)
- POST /register OAuth DCR no longer 500s on malformed bodies. 17 hits in production crashed with \`TypeError: Cannot read properties of undefined (reading 'redirect_uris')\` when callers (multipart/form-data Server Actions, OAuth clients sending non-JSON) hit the upstream \`@rekog/mcp-nest\` controller. New \`OAuthRegisterGuardMiddleware\` returns RFC 7591 \`invalid_client_metadata\` / \`invalid_redirect_uri\` with 400 instead of letting the library 500.
- Verification codes no longer logged in plaintext. \`EmailService\` was warning \`verification code for X: 641958\` whenever local SMTP wasn't configured (4 different users in the past week). Replaced with a debug line that just records that delegation to the external mailer happened.
- OpenApiParser accepts YAML and OpenAPI 3.1. \`Unexpected token 'o', \"openapi: 3\"...\` was the second-most-common 5xx — users pasted YAML specs and the parser called \`JSON.parse\` blindly. Now decodes JSON-or-YAML and routes 3.1 specs through \`SwaggerParser.dereference()\` (skipping the strict 3.0-only validator) so \`$ref\` still resolves.
- Cross-tenant tool-name collision on the global /mcp endpoint fixed. Three orgs had a connector with the same tool name; \`getTool(name)\` returned whichever was registered first. Added \`organizationId\` to \`RegisteredTool\` and a new \`getToolForOrg(name, orgId)\` lookup, wired through the auth handler in \`mcp-server.service\` and the executor in \`dynamic-mcp-tools\` so authenticated callers resolve their own org's tool. \`/mcp/:serverId\` was already safe via connector-id scoping.
📦 Verification
- backend jest: 561 passed, 1 skipped, 0 failed (5 new tests)
- \`scripts/smoke-test/run.sh\`: 12/12 PASS end-to-end
- frontend Playwright: 3/3 PASS
- All CI gates green (CodeQL, Trivy filesystem scan, lint, tsc, build)
📦 Highlights
- Validated DTOs on the remaining write endpoints (#129): \`POST /import-all\`, \`PUT /:id/env-vars\`, \`POST tools/bulk\`, \`POST tools/:toolId/test\` now reject malformed payloads with class-validator + \`@ValidateNested\` + \`@ArrayMinSize(1)\` instead of accepting bare object literals.
- Sentry integration, opt-in (#130): \`@sentry/nestjs\` + \`@sentry/nextjs\` wired across backend, client, server, and edge runtimes. \`SENTRY_DSN\` / \`NEXT_PUBLIC_SENTRY_DSN\` are required to enable; default install ships nothing. \`beforeSend\` strips auth headers and credential field names. Sample rates default to 0.
- OpenTelemetry tracing, opt-in (#131): NodeSDK with auto-instrumentations for http/express/pg/mysql/redis when \`OTEL_EXPORTER_OTLP_ENDPOINT\` is set. \`fs\` and \`/health\` excluded.
- Settings page → toast + a11y htmlFor (#132): Profile + Change Password sections now have proper label/input pairing and emit toast notifications via \`useToast()\`.
- Operations docs (#133): \`docs/operations/{backup-restore,disaster-recovery,slo,observability}.md\` with concrete pg_dump procedures, RPO/RTO targets, six failure-mode runbooks (including the unrecoverable \`ENCRYPTION_KEY\`-loss case), 99.9% SLO definition, and the three-pipeline observability story threaded by \`X-Request-Id\`.
📦 Verification
- Playwright e2e: 3/3 PASS.
- Backend jest: 554 passing, 1 skipped, 0 failing.
📦 Compatibility
- No breaking changes. All new pipelines (Sentry, OpenTelemetry) are opt-in; defaults unchanged.
📦 Highlights
- Graceful shutdown (#121): \`enableShutdownHooks\` + SIGTERM/SIGINT handlers so in-flight tool invocations drain and Prisma/Redis disconnect cleanly during a rolling deploy.
- CI is now actually a gate (#121): the previous workflow only ran on \`workflow_dispatch\` and pointed at a non-existent \`working-directory: anythingmcp\`. Now runs on push and PR, with backend+frontend lint, \`tsc --noEmit\`, jest, build, plus CodeQL and Trivy (filesystem + image) scanning. Both packages got proper flat ESLint configs.
- Structured logging with Pino + correlation IDs (#122): replaces the default NestJS console logger. Every request carries a UUID echoed back as \`X-Request-Id\`; \`userId\` / \`orgId\` / \`authMethod\` propagated to every log line; auth headers and \`password\` / \`token\` / \`apiKey\` field names redacted. JSON in prod, pretty in dev.
- Frontend error fallbacks + a11y (#123): \`error.tsx\` and \`not-found.tsx\` for App Router; \`htmlFor\` + \`autoComplete\` rewired across login, register, forgot-password, reset-password — fixes the broken label/input pairing for screen readers and password managers.
- Pagination (#124): \`?limit=&offset=\` accepted on \`/api/connectors\` and \`/api/mcp-servers\` via a class-validator-checked DTO. Backwards compatible.
- Toast system (#125): \`@radix-ui/react-toast\` was in deps but unused; \`components/toast.tsx\` exposes a global \`ToastProvider\` + \`useToast()\`. \`forgot-password\` migrated as the first consumer.
- Type contracts for engine inputs (#126): \`engine-types.ts\` with discriminated \`endpointMapping\` unions per connector type plus a \`ResponseMapping\` interface.
- Playwright e2e (#127): boots \`next dev\` and asserts the new label/input pairing, focus behaviour, and the branded 404. Wired into a dedicated CI workflow that uploads the report on failure.
- + 1 more
📦 Verification
- Playwright e2e in CI: 3/3 passed.
📦 Compatibility
- No breaking changes. Same env vars, same API shape, same defaults.
📦 Highlights
- Secrets: removed hardcoded `JWT_SECRET` / `ENCRYPTION_KEY` fallbacks; the app refuses to start if either is missing or below 32 chars or matches a known placeholder.
- SSRF guard: DNS-aware host check that blocks loopback, link-local (incl. `169.254.169.254` cloud metadata), RFC1918, CGNAT and IPv4-mapped IPv6 — applied to REST/GraphQL/SOAP/MCP-client engines, OAuth2 token service, mcp-oauth, and OpenAPI/Postman/GraphQL spec fetchers.
- SQL injection: `DatabaseEngine` now compiles templates to driver-specific prepared statements (`$1` pg, `?` mysql/sqlite, `@p0` mssql, `:b0` oracle); user values are bound, never inlined.
- Template injection: REST `bodyTemplate` rejects `__proto__` / `constructor` / `prototype` keys and JSON-encodes interpolated values.
- IDOR: tools `update`/`delete` pinned to `connectorId`; roles and users admin endpoints scoped to the requesting organization.
- HTTP: Helmet middleware, HSTS in prod, CORS rejects `'*' + credentials` in production, per-endpoint rate limiting on auth flows.
- Dependencies: `npm audit fix` brings vulnerabilities from 43 (1 critical, 22 high, 20 moderate) down to 11 (1 high, 10 moderate transitive); Dependabot config added.
✨ What's new
- Account self-delete — Users can now delete their own account from `/settings` (Danger Zone). Requires password confirmation + typing `DELETE`. Audit logs are preserved without identifying information; OAuth artifacts and active MCP API keys are revoked atomically.
- Organization delete — Org admins can delete the entire organization from `/settings/organization` (Danger Zone). Requires typing the org name. Cascade-removes all members, connectors, MCP servers, API keys, custom roles, invitations, and settings.
📦 Behavior details
- Sole-admin guardrail: self-delete is blocked when the user is the only admin of an org with other members; the dialog lists which orgs need attention.
- Sole-occupant cleanup: orgs where the deleting user is the only member are removed in the same transaction.
- Orphan migration: when an org is deleted, other members whose cached active org pointed to it are migrated to their oldest remaining membership; if none, their `organizationId` becomes `null` and the next request auto-resyncs.
- Last-org safety net: deleting your last org auto-creates a fresh Personal Workspace and reissues a JWT, so admins are never stranded without a workspace.
📦 Migration
- `User.organizationId` is now nullable with `onDelete: SetNull`. Apply the included Prisma migration before deploying:
- ```
- npm run db:migrate
- ```
📦 REST engine
- `mapParams` recurses into nested objects/arrays (fixes FastBill-style nested bodies).
- New `QUERY_AUTH` auth type for APIs that carry credentials in the URL (Destatis, Oxomi, HERE).
- Embedded `${param}` interpolation inside strings (e.g. OData filters).
- Endpoint `queryParams` merge with auth-injected params instead of overwriting them.
🐛 Existing adapters (16) — bugs fixed
- `${x}` → `{x}` in paths; `${x}` → `$x` in queryParams/bodyMapping/headers.
- `BASIC` → `BASIC_AUTH` (FastBill, MFR).
- `body` → `bodyMapping`/`bodyTemplate` (FastBill, Scopevisio, MFR link endpoints).
- Destatis: credentials moved from queryParams to `QUERY_AUTH` authConfig.
✨ New adapters (13)
- Public data: vies-vat, handelsregister, deutsche-bahn, openplz
- Baustoff/Wholesale: oxomi
- Logistics: dpd-germany, gls-tracking, shipcloud, sendcloud
- Other: xentral (ERP), shopware-6 (e-commerce), here-geocoding (mapping), personio (HR)
- Catalog is now 29 adapters. All declare `requiredEnvVars` so the import UI auto-prompts for credentials.
🧪 Tests
- 275/275 passing across `rest.engine.spec` + `catalog.spec` (new parametrized catalog smoke test). TypeScript clean.
- PRs: #96 (adapters), #97 (version bump).
🐛 Bug Fixes
- Fix password reset email silently dropped on cloud deployments without SMTP (#93). Password reset now falls back to the central Resend endpoint at anythingmcp.com/api/email/password-reset when SMTP is not configured, matching the existing pattern used by invite, welcome, and verification emails.
🐛 Security Fix
- Cross-org tool collision: ToolRegistry now uses tool ID (globally unique) as primary key instead of tool name. Prevents org A from accidentally executing org B's tool when both have tools with the same name.
- Tool lookup scoped to connector IDs of the requesting MCP server.
🐛 Bug Fixes
- Trial banner no longer shows on login/register pages
- License status endpoint returns empty in cloud mode without auth
- Email fallback finds license key from DB when site_settings is stale
- Cloud registration correctly assigns ADMIN role to org creator
📦 Improvements
- Docker workflow now tags both version + latest in a single build (was two separate builds)
🐛 Bug Fixes
- Cloud registration role: Users self-registering in cloud mode now correctly become ADMIN of their own organization (was incorrectly assigned EDITOR)
- License lookup after migration: 3-tier fallback ensures migrated licenses are found: per-org → global site_settings → any unassigned active license. Auto-assigns orphan licenses to the requesting org on first access
- License status endpoint: Now uses optional authentication — works both with and without JWT token. When authenticated, returns org-scoped license; when not, returns global license
📦 Improvements
- Organization settings page: Accessible to all users (not just ADMIN). Non-admins can view their current org info, create new organizations, and switch between orgs
- Create new organization: Any user can create a new organization from Settings > Organization. Creator automatically becomes ADMIN
- Sidebar permissions: Individual sidebar items gated by adminOnly flag — Organization > General visible to all, Users/Roles/License/Administration visible only to ADMIN
- Production DB fix: All org creators correctly set as ADMIN, orphan licenses assigned to their organizations
📋 Full changelog from v0.1.11
- 3 commits, 6 files changed
📦 Multi-Tenant Organization System
- AnythingMCP now supports full multi-tenancy with organization-based data isolation. This is a major architectural upgrade that enables secure multi-user SaaS deployments.
- Each user registration creates a new Organization (workspace)
- Invited users join the inviter's Organization automatically
- Users can belong to multiple organizations with different roles per org
- Slack/GitHub-style org switcher in the navbar dropdown
- Settings > Organization page to manage workspace name and create new orgs
- All resources (connectors, MCP servers, tools, audit logs) are scoped per organization
- Cross-organization access is blocked at the API level (403/404)
- + 17 more
📦 Technical Details
- 46 files changed, 1421 insertions, 238 deletions
- 2 database migrations with automatic data backfill
- 24/24 API tests passing (isolation, multi-org, switch, license, audit)
- Frontend and backend fully tested
📋 Changes
- Fix license wall loop when trial expires in cloud mode
✨ What's new
- Instructions support: Add optional `instructions` field to Connectors and MCP Servers. Instructions are composed (server + connectors) and returned via the MCP protocol `initialize` response.
- MFR Fieldservice adapter update: Full 71-tool definition with OData conventions and workflow instructions.
- UX fix: MCP assign modal only appears when a connector has tools and is not yet assigned to a server.
✨ What's new
- Fix Swagger UI URL import: When importing OpenAPI specs, users can now provide a Swagger UI page URL (e.g. `/docs`) instead of the raw spec URL. The parser auto-resolves the actual spec from:
- `swagger-ui-init.js` embedded specs (swagger-ui-express / NestJS)
- `SwaggerUIBundle({ url: ... })` config in HTML
- Common spec endpoint paths (`/openapi.json`, `/swagger.json`, etc.)
✨ New Features
- Built-in Adapter Store — 15 pre-configured connectors for popular German/European APIs (DHL, DATEV, TeamViewer, N26, weclapp, FastBill, Billomat, ScopeVisio, Kenjo, MFR, ImmobilienScout24, PAYONE, Bundesbank, DESTATIS, NINA)
- MCP Server Assignment Modal — After importing/creating a connector, a modal guides users to assign it to an MCP server
- Auto-install via URL — Support `?install=<slug>` parameter for one-click import from the website marketplace
- Login deep linking — `?mode=register|login` URL parameter for direct registration/login
- Public adapter catalog API — `GET /api/adapters` is now public for website integration
- 80+ SEO guide pages — Connect-to-Claude / Connect-to-ChatGPT guides in EN, DE, IT
📦 Improvements
- Auth redirect preserves full URL path with query params
- Version bump to 0.1.7
📦 Cloud Deployment Mode
- `DEPLOYMENT_MODE=cloud` env var for managed SaaS deployments
- Trial license activation (7-day free trial via cloud onboarding)
- License guards enforcing plan-based limits on connectors and MCP servers
- Cloud-specific frontend: LicenseWall, TrialBanner, trial onboarding in login
📦 Deployment
- `docker-compose.cloud.yml` for cloud deployment with Caddy HTTPS, Redis
- GitHub Action for manual cloud deployment via SSH
- Caddyfile with path-based routing
📦 Infrastructure
- DeploymentService for centralized deployment mode detection
- CloudModule conditionally loaded in cloud mode
- `deploymentMode` exposed in health endpoint
- `trialDaysLeft` in license status response
📋 What's Changed
- Auto-show registration form — When no users exist, the login page automatically shows the registration form instead of sign-in
- Skip email verification — First user (admin) can skip email verification during initial setup if the email doesn't arrive
- Email deliverability fix — Verification and invitation email links now route through anythingmcp.com to match the Resend sending domain, reducing spam filter issues
- Full Changelog: https://github.com/HelpCode-ai/anythingmcp/compare/v0.1.3...v0.1.4
✨ What's new
- Proactive OAuth2 token refresh
- Tokens are now refreshed automatically *before* they expire (5-minute buffer), so AI clients never encounter a 401 due to token expiration
- Per-connector refresh mutex prevents concurrent refresh storms
- `McpClientEngine` now uses the shared `OAuth2TokenService` with DB persistence (removed duplicate logic)
- `expiresAt` timestamp is stored at initial OAuth grant for accurate expiry tracking
- Frontend session management
- Saved JWT is validated against the backend on page load — stale tokens are cleared immediately
- Auto-logout on 401: if any API call returns Unauthorized, the user is redirected to login
