Commit Graph

59 Commits

Author SHA1 Message Date
12b06ce66f fix: black formatting for CI (Python 3.12 compat)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:52:54 +02:00
9905a28eb0 feat: v3.4.0 — OpenPanel plugin public release (42 tools)
OpenPanel product analytics plugin fully reviewed, tested, and published.
Works with both self-hosted and cloud (openpanel.dev) instances.

- 42 tools: event tracking, data export, analytics, project/client management
- All tools use public REST APIs (Track, Export, Insights, Manage)
- Client modes: write (tracking), read (analytics), root (full access)
- Service page with description, setup notes, WordPress plugin download
- Dynamic URL hints in Add Site form
- 62 unit tests
- ENABLED_PLUGINS default now includes openpanel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:48:12 +02:00
68c84b3ece fix(tests): update supported clients count to 6 (added claude_connectors)
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v3.3.0
2026-03-31 14:58:59 +02:00
9b70b259bb release: v3.3.0 — platform hardening & admin unification (Track F.1–F.8)
Plugin visibility control, UI/UX fixes, unified admin panel,
database-backed settings, and security hardening.

Highlights:
- ENABLED_PLUGINS env var for plugin visibility (F.1)
- Admin designation via ADMIN_EMAILS (F.4a)
- Master key scope control (F.4b)
- Panel unification + settings from UI (F.4c)
- exec() removal, shell injection fix, bcrypt migration (F.8)
- 5 new test suites

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 09:55:49 +02:00
airano
f6dbbeaab0 sync: v3.2.0 pre-release audit — namespace fix, config types, docs update
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
- fix(seo): REST API namespace seo-api-bridge/v1 → airano-mcp-seo-bridge/v1
- fix(config): add transport type field (streamableHttp/http) to config snippets
- feat(dashboard): support section for OAuth users, connect page guidance
- docs: hosted option, test count 481, WP plugin link, OAuth env vars, per-user endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.2.0
2026-03-11 04:23:45 +03:30
airano
c0d55f9061 sync: v3.2.0 — Supabase fixes, site edit, WP plugin rename, black formatting
- Supabase: fix filters, count_rows, upsert, anon_key optional, meta_url field
- Dashboard: site edit page + PATCH update route
- WP Plugin: rename SEO API Bridge → Airano MCP SEO Bridge
- supabase/client.py: black formatting fix
- .gitignore: exclude BUILD_REPORT.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:21:28 +03:30
airano
a806671e2d fix(oauth): fix invalid_scope and invalid_token errors for user OAuth clients
Three bugs fixed for social-login users connecting Claude.ai via OAuth:

1. User OAuth clients now allow 'admin' scope by default — previously
   defaulted to ['read', 'write'], causing invalid_scope when Claude.ai
   requests 'admin' scope during authorization.

2. Fix JWT tokens with 'aud' claim being rejected by middleware — when
   Claude.ai sends RFC 8707 resource parameter, the issued JWT gets an
   aud claim. validate_access_token() now sets verify_aud=False to
   prevent PyJWT InvalidAudienceError from silently marking valid tokens
   as invalid in _is_valid_token().

3. Fix NameError in user_mcp_handler tools/call scope check — key_info
   was only defined in the mhu_ auth path but referenced in tools/call
   for both paths. Replaced with key_scopes variable set by both mhu_
   and JWT auth paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 00:37:43 +03:30
airano
4a5381d765 fix(server): register user OAuth client routes in server.py Route list (404 fix) 2026-02-25 23:54:49 +03:30
airano
fdb050454e feat: OAuth user fixes + dashboard UI improvements (v3.2.0)
- Bug A: Fix OAuth consent redirect loop (return_url path-relative)
- Bug B: Accept OAuth JWT tokens on /u/{user_id}/{alias}/mcp
- Bug C: Add user OAuth client CRUD (list/create/delete) + new page
- D-1: Sidebar border via Tailwind class, version footer in sidebar
- D-2: Remove broken setInterval targeting #stats-container
- D-3: 404.html purple primary colors + system dark mode support
- D-4: Fix invisible buttons (bg-gray-200 + text-white in light mode)
- D-5: Pin Alpine.js to 3.14.8, remove duplicate CSRF meta tag
- D-6: Fix invisible lang toggle button in settings (dark mode)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 23:27:59 +03:30
airano
ea51c10e03 chore: release v3.2.0 — version bump, changelog, test badge
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:52:13 +03:30
airano
479d0c7252 feat(oauth): Phase C — social login on OAuth consent screen
Enable dashboard users (GitHub/Google social login) to approve OAuth
consent without needing to create and paste an API key. Adds mhu_ user
key support, session-based consent with __session__ marker, social login
links on the consent page, and return URL redirect after login.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:13:17 +03:30
airano
d3bcb31053 feat(oauth): Phase B — claude.ai protocol compatibility
Add 3 features for claude.ai Connectors compatibility:

- FEATURE-3: client_secret_basic auth on token endpoint (RFC 6749 §2.3.1)
- FEATURE-2: Token revocation endpoint /oauth/revoke (RFC 7009)
- FEATURE-4: resource parameter support with JWT aud claim (RFC 8707)

23 new tests (481 total), all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:49:23 +03:30
airano
1736779d69 fix: SUG-6 API key modal, SUG-4 project activity filter, WooCommerce health auth
- SUG-6: Replace auto-closing inline banner with persistent modal on Connect
  page — key stays visible until user clicks "Done"
- SUG-4: Filter health_metric_recorded/health_check from project detail activity
- WooCommerce: Accept consumer_key/consumer_secret credentials (preferred) with
  username/app_password fallback; fix health check to use WC endpoint and creds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 07:16:05 +03:30
airano
983d93c2a7 fix: BUG-7, BUG-10, BUG-11, BUG-12 — remaining bug fixes
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
- BUG-12: ENCRYPTION_KEY validation now exits with sys.exit(1) on invalid key
- BUG-11: WP Advanced health check adds authenticated fallback with auth_valid
- BUG-7: Catch-all GET route serves styled 404 HTML instead of plain text
- BUG-10: Recent Activity fetches extra entries before filtering, fixes None project

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.1.1
2026-02-24 05:40:36 +03:30
airano
80377a1a22 fix: 15 bug fixes for v3.1.0 dashboard and Track E features
Bug fixes (ordered by priority):
- BUG-14 (P1): Fix ImportError in per-user MCP endpoint
- BUG-8 (P2): Raise clear error when PUBLIC_URL missing for OAuth
- BUG-12 (P3): Validate ENCRYPTION_KEY at startup
- BUG-13 (P4): Handle stale JWT gracefully on site creation
- BUG-11 (P5): Add auth validation to WordPress health checks
- BUG-15 (P6): Fix copy button showing Python repr (dict method shadow)
- BUG-1 (P7): Dynamic version from pyproject.toml instead of hardcoded
- BUG-5 (P8): Fix server mode default (sse → streamable-http)
- BUG-9 (P9): Plugin-specific example tools in endpoint instructions
- BUG-4 (P10): Fix settings page sidebar RBAC (session type mismatch)
- BUG-6 (P11): Show real plugin descriptions instead of 'No description'
- BUG-2 (P12): Remove stale 'phase: X.3' from system info
- BUG-10 (P13): Guard timestamps against None in Recent Activity
- BUG-3 (P14): Guard timestamps against None in audit logs
- BUG-7 (P15): Styled 404 page instead of plain text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 03:30:16 +03:30
airano
684c889c27 style: fix import ordering in test_dashboard.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:31:00 +03:30
airano
55d30ba876 style: fix ruff lint errors (unused imports, import sorting, SIM103)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:27:27 +03:30
airano
eceba04578 chore: remove pytest-out.txt and update .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:24:31 +03:30
airano
1fcc539093 style: format 9 files with Black
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:22:52 +03:30
airano
9e6f06d933 feat: v3.1.0 — Live Platform Foundation (Track E.1-E.3)
Major release introducing the Live Platform architecture:

- SQLite database backend with async operations and migrations (E.1)
- AES-256-GCM credential encryption with HKDF key derivation (E.1)
- OAuth Social Login with GitHub and Google (E.2)
- Site management API with encrypted credential storage (E.3)
- Per-user MCP endpoints at /u/{user_id}/{alias}/mcp (E.3)
- User API keys with bcrypt hashing (E.3)
- Auto-generated config snippets for 5 MCP clients (E.3)
- Dashboard: dark/light mode, RBAC, My Sites, Connect page
- Active background health checks
- 452 tests (up from 303), all passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:20:03 +03:30
airano
42ea75bcb3 fix: remove unused asyncio import in test_wordpress_plugin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:07:44 +03:30
airano
647a650629 feat(error-handling): add network error differentiation, retry, and REST API detection (C.5)
WordPress client improvements:
- Add ConnectionError exception for network-level failures
- Differentiate DNS, SSL, timeout, and connection refused errors
- Add retry with exponential backoff for transient errors (502, 503, 504, 429)
- Auth/config errors are never retried
- Add request timeout (30s default)

Health check improvements:
- Detect REST API disabled (403/404 on /wp-json)
- Classify errors by type: dns_failure, ssl_error, timeout, connection_refused

Bare except cleanup:
- Replaced all bare except: with except Exception: across 12 files

Tests: 303 passed (13 new tests for error handling)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:58:16 +03:30
airano
c57fd666c9 feat(registry): add smithery.yaml, server.json, and MCP Registry verification tag
- smithery.yaml: Smithery.ai configuration for PyPI install via uvx
- server.json: Official MCP Registry manifest (io.github.airano-ir/mcphub)
- README.md: add <!-- mcp-name --> verification tag for MCP Registry publishing

Part of D.4 — MCP Registry submissions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:10:54 +03:30
airano
7a16a260f1 fix: use find_dotenv(usecwd=True) for PyPI .env loading
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
load_dotenv() without usecwd=True fails for mcphub.exe because
find_dotenv() walks the call stack and searches from site-packages/
instead of the user's working directory. Bump to v3.0.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.0.4
2026-02-19 04:45:53 +03:30
airano
f29dc299b2 fix: make version display dynamic across all surfaces
- routes.py: fallback reads from importlib.metadata instead of hardcoded
- login.html: remove hardcoded default version
- README: use dynamic GitHub Release badge from shields.io
- DOCKER_README: remove hardcoded version string

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 04:04:15 +03:30
airano
5d97b31c12 fix: auto-load .env file for PyPI installations
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
PyPI users running `mcphub` had to manually export env vars because
server.py didn't call load_dotenv(). Docker users were unaffected
since docker-compose loads .env automatically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.0.3
2026-02-19 03:59:26 +03:30
airano
72cfdad5e3 style: fix black formatting in health.py
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.0.2
2026-02-19 03:40:08 +03:30
airano
5ce70f120e chore: bump version to 3.0.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:38:13 +03:30
airano
cafcd64eff fix(health): resolve "Site not found" for wordpress_advanced health checks
The health monitor's _basic_site_health_check() used split("_", 1) to parse
project IDs like "wordpress_advanced_site1", incorrectly yielding
plugin_type="wordpress" and site_id="advanced_site1". Now uses SiteManager's
list_all_sites() for proper full_id lookup, and creates a temporary plugin
instance for proper health checks (REST API, WP-CLI) instead of basic HTTP.

Also fixes the same split bug in SiteManager.get_effective_path_suffix().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:29:05 +03:30
airano
d74594524a docs(readme): clarify OAuth as optional, document CONTAINER env var
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.0.1
2026-02-19 02:52:44 +03:30
airano
b6551abe0a docs: clarify OAuth as optional, document CONTAINER env var
- docker-compose: OAuth vars commented out by default
- env.example: added WordPress Advanced section with CONTAINER docs
- DOCKER_README: added CONTAINER to env var table with usage notes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:46:53 +03:30
airano
cb2a835d0e fix: revert docker-compose ports for standalone users, fix endpoint path
- docker-compose: ports "8000:8000" active by default
- README: fix /wordpress_advanced → /wordpress-advanced
- DOCKER_README: add version 3.0.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:32:08 +03:30
airano
bb2a416dd5 fix(qa): health check, admin notice, docs, logo, Coolify port
- WP Advanced health_check uses aiohttp to /wp-json/ directly
- SEO Bridge admin notice only on Plugins page
- SEO Bridge README.md consolidated, changelog complete
- OpenPanel Self-Hosted README.md created
- Dashboard sidebar uses actual logo.svg
- docker-compose: expose instead of ports for Coolify
- README: version badge, wordpress_advanced endpoint, env var table
- Docs: SSE references fixed to streamable-http

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:55:29 +03:30
airano
ff79968170 feat(wp): rename OpenPanel plugin to OpenPanel Self-Hosted for WP.org
- Separate plugin identity for WordPress.org submission
- Text domain, folder, and file renamed to openpanel-self-hosted
- Description updated as fork of official OpenPanel plugin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:57:48 +03:30
airano
bb851e4be2 fix(qa): health monitor SiteManager, WP plugins, favicon, download ZIPs
- Health monitor now uses SiteManager for complete site discovery
- SEO Bridge: GPLv2+ license, Tested up to 6.9, fix escaping
- OpenPanel: fix wp_unslash, reduce tags, update branding
- Add logo.svg favicon, static file serving, plugin ZIPs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:11:49 +03:30
airano
91979ee18d fix(qa): SEO API Bridge fixes, transport type corrections, README improvements
- Fix SEO API Bridge branding, meta keys, route namespaces, GET auth
- Create WordPress.org-compatible readme.txt
- Fix transport types across all docs (streamableHttp/http, not sse)
- Add WordPress Plugin Requirements section to README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 19:42:32 +03:30
airano
809dc264af fix(qa): resolve remaining v3.0.1 issues — CI, code bugs, docs
CI: Fix black formatting in core/site_registry.py
Code: list_projects uses SiteManager, WP Advanced health uses REST API
Docs: Fix transport types, endpoint guide, env var reference for all plugins

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:55:12 +03:30
airano
cb6bcd8136 fix(qa): resolve A.1-A.7 code bugs and B.1-B.8 documentation issues
Code fixes:
- Rename "Coolify Admin" to "MCP Hub Admin" in endpoints
- Enrich list_projects with alias and endpoint URL
- Downgrade OAuth InvalidTokenError log from WARNING to DEBUG
- Add 7 missing health tools to /system/mcp endpoint (now 24 tools)
- Remove "Phase 7.2" from health monitor log
- Fix WP Advanced health check to pass with REST API only
- Downgrade duplicate alias warnings to INFO

Documentation fixes:
- Document SSE transport and Bearer auth requirement
- Recommend plugin-specific endpoints to save tokens
- Document plugin vs project endpoint differences
- WordPress plugin requirements for SEO/WP-CLI tools
- Docker socket mounting guide for WP-CLI
- Mark MASTER_API_KEY as recommended (auto-generates temp key)
- Env var naming convention with prefix table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 18:29:15 +03:30
airano
3b87c01d78 fix(discovery): prevent WORDPRESS_ADVANCED_ prefix collision with WORDPRESS_
ProjectManager and SiteManager now skip env vars that belong to a more
specific plugin type (e.g. WORDPRESS_ADVANCED_*) when discovering sites
for a shorter prefix (WORDPRESS_). This prevents ghost projects, ERROR
logs, and false health alerts on startup.

Also downgrades Docker socket errors in WP-CLI to warnings — if Docker
socket is not mounted, WP-CLI features are silently unavailable instead
of logging ERROR and triggering health alerts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:08:34 +03:30
airano
85379ec36c fix(security): validate Bearer token value in MCP endpoints, not just presence
Previously any Bearer token (even invalid) passed the HTTP middleware and
got a session with access to tools/list and resources/list. Now the
OAuthRequiredMiddleware validates tokens against master key, API keys,
and OAuth JWT before allowing initialize.

Also fixes:
- WordPress Advanced env prefix: WORDPRESS_ → WORDPRESS_ADVANCED_ in docs
- Bump version to 3.0.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 16:24:04 +03:30
airano
4a45178d2d fix(auth): support auto-generated temp key in dashboard login
When no MASTER_API_KEY env var is set, AuthManager generates a temp key
but DashboardAuth didn't know about it. Now validate_api_key() also
checks AuthManager as a fallback, so temp key login works for first-time
Docker users.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:56:19 +03:30
airano
f303a04322 fix(auth): fix dashboard login with project API keys
validate_key() requires project_id argument but was called without it
in dashboard auth. Fixed by passing skip_project_check=True.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 15:43:05 +03:30
airano
bb74703311 fix(ux): improve new user onboarding experience
- Show full temporary API key in logs (not masked) so users can log in
- Redirect root URL / to /dashboard (was 404)
- Add setup guidance and docs link to login page
- Make footer version dynamic (read from pyproject.toml)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 03:41:04 +03:30
airano
aa8afce707 fix: correct tool count (596), default English dashboard, clean up stale references
- Tool count corrected: 589→596 (was missing 4 OAuth + 4 system config tools)
- System tools: 17→24 (accurate count of @mcp.tool() functions)
- Dashboard defaults to English; Farsi only via ?lang=fa query param
- Updated across all files: README, CLAUDE.md, CONTRIBUTING, DOCKER_README,
  getting-started, CHANGELOG, endpoints config
- Removed remaining Phase references from server.py startup log
- Tests: 289 passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 03:14:28 +03:30
airano
076a0b940e fix(server): resolve lint error and clean up production logs
- Fix F821 undefined name `core` by using local import in fallback path
- Remove all internal terminology from logs (Phase X, Option B)
- Clean Phase/Option B references from tool docstrings (visible to MCP clients)
- Suppress websockets DeprecationWarning (noisy, harmless)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:59:48 +03:30
airano
7daf604a32 fix(packaging): move templates into core/ for PyPI distribution
Templates were at project root (templates/) which is outside the Python
package, so `pip install mcphub-server` would not include them. Moved to
core/templates/ and updated path references in server.py and
core/dashboard/routes.py. Also added py-modules for server.py and
server_multi.py to pyproject.toml.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:41:28 +03:30
airano
5e0441c85e docs: add env.example template for new users
Previously excluded from community edition by mistake.
This template has placeholder values only (no real secrets)
and is needed for the Quick Start: `cp env.example .env`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:23:46 +03:30
airano
3a3f04aca8 docs(onboarding): improve new user experience + fix OpenPanel tools
- Add DOCKER_README.md for Docker Hub overview page
- Fix docker-compose.yaml port mapping for local users ("8000:8000")
- Add "Verify It Works" section with dashboard URL to README
- Restructure env.example with clear REQUIRED section
- Add post-Docker verification checklist to getting-started.md
- Fix 4 OpenPanel tools: parameter ordering (non-default before default)
- Rebrand all "Coolify Projects" to "MCP Hub" in server and Dockerfile
- Make MCP namespace prefix stripping generic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 02:22:48 +03:30
airano
58aa0684b2 fix(ci): add OAuth env vars to release workflow test step
Some checks failed
Release / Test before release (push) Has been cancelled
Release / Publish to PyPI (push) Has been cancelled
Release / Publish to Docker Hub (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v3.0.0
2026-02-17 18:54:42 +03:30
airano
0aefc29dee fix(oauth): fallback storage path for CI and local dev
Both JSONStorage and ClientRegistry now use ./data when /app doesn't
exist (Docker vs local/CI environments).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:32:44 +03:30