Backend:
1. Extend SavedProvider schema with optional mcpAuth field
(accessToken / refreshToken / accessExpiresAt / refreshExpiresAt /
managerLoginUrl / userId / channelId). Wired through
CreateProviderInput and UpdateProviderInput so providerService
persists tokens to providers.json.
2. handleLoginWithCredentials (Path A) now decodes the JWT exp claim
of both tokens (no signature verification — issuer just authed us)
and stores the resulting mcpAuth object on the saved provider.
Documented TTL (24h access / 7d refresh) used as fallback if exp
claim missing.
3. New handler api/heicode-resources.ts — proxy for the local server
route /api/heicode-resources/{*path}. It:
- Reads mcpAuth from the active provider (401 if missing)
- Refreshes the access token if < 60s from expiry by calling
<managerLoginUrl>/api/auth/refresh; persists the new pair
back to providers.json before forwarding
- Returns 401 if refresh token is also expired (re-login needed)
- Forwards request to <managerLoginUrl>/api/resources or
/api/resource-grants with Authorization: Bearer <accessToken>
- Passes status + body through
4. router.ts: register case 'heicode-resources'.
5. errorHandler: add ApiError.unauthorized(401) and badGateway(502)
factories used by the proxy.
Desktop:
6. New api/heicodeResources.ts client + types (ResourceBinding,
ResourceGrant, etc. mirroring mcp-server contract). Slice 3 only
exposes listBindings + getBinding.
7. New stores/resourceStore.ts (zustand) with bindings, isLoading,
hasFetched, error + fetchBindings action.
8. pages/ResourceBindings.tsx upgraded from shell to a real list:
- Auto-fetches on mount
- Shows loading skeleton, error banner with dismiss, empty state,
or a 5-column table (Name / Type / External ref / Status /
Permission scope)
- Refresh button in the header
- Footer note about CRUD coming in slice 4
9. i18n: 14 new keys (common.dismiss + resources.refresh / refreshing
/ col.* / error.title / footer.cruComingSoon) in both zh + en.
E2E behaviour after install: log in via 55@55.com / By@123456., open
Resources tab — local server proxies to apimtaiji and lists whatever
ResourceBindings the user has on mcp-server. New test account 55@55.com
has 0 bindings, so empty state shows up.
Slice 4 next: Create / Edit / Delete binding modals + Grants UI.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Claude Code Haha Desktop
基于 Tauri 2 + React 的桌面客户端。
开发
bun install
bun run tauri dev
构建
# macOS (Apple Silicon)
./scripts/build-macos-arm64.sh
# Windows (x64, MSI only)
.\scripts\build-windows-x64.ps1
构建产物位于 build-artifacts/ 目录,文件名会显式包含平台、架构和包类型。
常见问题
macOS 提示"已损坏,无法打开"
xattr -cr /Applications/Claude\ Code\ Haha.app