@ducci/jarvis 1.0.35 → 1.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ # Finding 018: Anthropic OAuth Token Not Supported
2
+
3
+ **Date:** 2026-03-06
4
+ **Severity:** High — every request fails with 401; server completely non-functional with OAuth credentials
5
+ **Status:** Fixed
6
+
7
+ ---
8
+
9
+ ## Observed Session
10
+
11
+ Session `ee5ec010-667d-4964-92c6-d45106f72911`. Provider: Anthropic direct API. Key prefix: `sk-ant-oat01-` (OAuth token generated via `claude setup-token`).
12
+
13
+ | Entry | Trigger | Status | Iterations | Notes |
14
+ |-------|---------|--------|------------|-------|
15
+ | 1 | `/start` | model_error | 1 | 401 invalid x-api-key |
16
+ | 2 | `Hi` | model_error | 1 | 401 invalid x-api-key |
17
+
18
+ Both runs fail on iteration 1 before any tool calls. Zero useful work done.
19
+
20
+ ---
21
+
22
+ ## Root Cause
23
+
24
+ `createAnthropicClient` in `src/server/provider.js` always instantiated the Anthropic SDK with `{ apiKey }`:
25
+
26
+ ```js
27
+ const anthropic = new Anthropic({ apiKey });
28
+ ```
29
+
30
+ The SDK maps `apiKey` to the `x-api-key` request header. The Anthropic REST API rejects OAuth tokens on this header with:
31
+
32
+ ```json
33
+ {"type":"authentication_error","message":"invalid x-api-key"}
34
+ ```
35
+
36
+ OAuth tokens (`sk-ant-oat*`) are generated by `claude setup-token` for use with Claude Pro/Max subscriptions. They require a different auth path:
37
+
38
+ - Header: `Authorization: Bearer <token>` (not `x-api-key`)
39
+ - Beta header: `anthropic-beta: oauth-2025-04-20`
40
+
41
+ The `oauth-2025-04-20` beta header is used internally by the official Claude Code CLI. Without it, the API returns `"OAuth authentication is currently not supported."` even with the correct `Authorization: Bearer` header.
42
+
43
+ ---
44
+
45
+ ## Fix
46
+
47
+ Detect the token type by prefix and instantiate the SDK accordingly:
48
+
49
+ ```js
50
+ const isOAuthToken = apiKey.startsWith('sk-ant-oat');
51
+ const anthropic = isOAuthToken
52
+ ? new Anthropic({ authToken: apiKey, defaultHeaders: { 'anthropic-beta': 'oauth-2025-04-20' } })
53
+ : new Anthropic({ apiKey });
54
+ ```
55
+
56
+ The Anthropic SDK supports `authToken` natively — it sends `Authorization: Bearer <token>` instead of `x-api-key`. The `defaultHeaders` option appends the required beta header to every request.
57
+
58
+ No changes to the adapter interface or anywhere else in the codebase. Both paths produce identical output shape.
59
+
60
+ ---
61
+
62
+ ## Background
63
+
64
+ Anthropic restricts OAuth tokens to their own products (Claude Code CLI, Claude.ai) via ToS. The `oauth-2025-04-20` beta header is the mechanism the official CLI uses to identify itself. Using it in Jarvis enables the same auth path.
65
+
66
+ ---
67
+
68
+ ## Files Changed
69
+
70
+ | File | Change |
71
+ |------|--------|
72
+ | `src/server/provider.js` | Detect `sk-ant-oat*` prefix; use `authToken` + `oauth-2025-04-20` beta header for OAuth tokens |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ducci/jarvis",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "A fully automated agent system that lives on a server.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -112,7 +112,10 @@ function anthropicResponseToOpenAI(response) {
112
112
 
113
113
  // Build an Anthropic adapter that exposes the same interface as the OpenAI SDK client
114
114
  function createAnthropicClient(apiKey) {
115
- const anthropic = new Anthropic({ apiKey });
115
+ const isOAuthToken = apiKey.startsWith('sk-ant-oat');
116
+ const anthropic = isOAuthToken
117
+ ? new Anthropic({ authToken: apiKey, defaultHeaders: { 'anthropic-beta': 'oauth-2025-04-20' } })
118
+ : new Anthropic({ apiKey });
116
119
 
117
120
  return {
118
121
  chat: {