Skip to content

feat(connectors): DATEV sandbox adapter + reload REST OAuth tools (v0.3.6)#436

Merged
keysersoft merged 3 commits into
mainfrom
keysersoft/datev-sandbox-adapter-reload
Jul 20, 2026
Merged

feat(connectors): DATEV sandbox adapter + reload REST OAuth tools (v0.3.6)#436
keysersoft merged 3 commits into
mainfrom
keysersoft/datev-sandbox-adapter-reload

Conversation

@keysersoft

Copy link
Copy Markdown
Contributor

Summary

Two DATEV improvements, both driven by a real customer onboarding failure.

1. Dedicated DATEV Sandbox adapter

Adds "DATEV Online APIs (Sandbox)" to the marketplace, pre-configured for DATEV's sandbox environment:

  • authorize login.datev.de/openidsandbox/authorize, token sandbox-api.datev.de/token, API base platform-sandbox/v2
  • client_secret_basic (required by DATEV)

Every DATEV app must run in the sandbox until DATEV grants production approval (a 4–12 week certification). The single production adapter required editing ~9 URLs/paths by hand to reach sandbox — the exact error-prone step that left a customer with a half-prod/half-sandbox connector. The sandbox adapter is generated from the production one (scripts/generate-datev-sandbox.mjs) so the 6 tool definitions never drift; only the environment URLs differ. The production adapter's instructions now point to the sandbox connector instead of manual editing.

2. Reload REST OAuth tools after the token is stored

The in-memory MCP registry caches an authConfig snapshot (including the access token) per tool. The only reloadConnectorTools() call lived inside the MCP auto-discovery block in the OAuth callback — which throws for non-MCP (REST/GraphQL) servers, so the reload was skipped. Result: a REST connector that just completed OAuth kept serving with the stale, token-less snapshot → tool calls went out with an empty Bearer and 401'd despite a valid token in the DB. The reload now runs unconditionally right after the token is persisted.

Verification

  • Backend typecheck + lint clean.
  • src/connectors + src/auth: 384 tests pass (new: callback reload regression test proving the reload fires even when MCP discovery throws; DATEV adapters validate + register in the catalog).
  • Sandbox adapter endpoints verified reachable read-only against DATEV (401 not 404 → paths correct); client_secret_basic accepted by DATEV's sandbox token endpoint.

Two DATEV improvements driven by a real onboarding failure:

1. Add a dedicated "DATEV Online APIs (Sandbox)" marketplace adapter,
   pre-configured for DATEV's sandbox (openidsandbox authorize, sandbox-api
   token, platform-sandbox/v2 paths) with client_secret_basic. Every DATEV
   app must run in sandbox until DATEV grants production approval, and the
   old single adapter required editing ~9 URLs/paths by hand to get there —
   the error-prone step that broke onboarding. The sandbox adapter is
   generated from the production one (scripts/generate-datev-sandbox.mjs) so
   the 6 tool definitions never drift; only the environment URLs differ.

2. Reload a connector's tools into the in-memory MCP registry immediately
   after the OAuth token is stored. The registry caches an authConfig
   snapshot per tool, and the existing reload lived inside the MCP
   auto-discovery block — which throws for non-MCP (REST/GraphQL) servers,
   so REST OAuth connectors never picked up their freshly-issued token and
   served with a stale token-less snapshot. Now the reload runs
   unconditionally after the token is persisted.
Two correctness fixes for OAuth2 REST connectors (surfaced with DATEV, which
rotates the refresh token on every use and uses 2-year rolling refresh tokens):

- refreshToken() now re-reads the freshest authConfig from the DB before
  refreshing, instead of trusting the in-memory registry snapshot. The snapshot
  is not updated after a refresh (only the DB is), so a second refresh would
  replay the already-rotated token and the provider would reject it.

- The OAuth callback now MERGES the issued tokens into the existing authConfig
  (updateAuthConfigMerge) instead of replacing it, preserving static config such
  as authorizationUrl and scopes that later re-authorization needs.
@keysersoft
keysersoft merged commit b82d476 into main Jul 20, 2026
11 checks passed
@keysersoft
keysersoft deleted the keysersoft/datev-sandbox-adapter-reload branch July 20, 2026 13:02
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant