sub-bridge 1.0.0
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.
- package/.cursor/commands/mcp-only.md +1 -0
- package/.github/workflows/npm-publish.yml +33 -0
- package/.github/workflows/pages.yml +40 -0
- package/.github/workflows/release-please.yml +21 -0
- package/.release-please-manifest.json +3 -0
- package/CHANGELOG.md +8 -0
- package/DEVELOPMENT.md +31 -0
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/api/index.ts +12 -0
- package/bun.lock +102 -0
- package/dist/auth/oauth-flow.d.ts +24 -0
- package/dist/auth/oauth-flow.d.ts.map +1 -0
- package/dist/auth/oauth-flow.js +184 -0
- package/dist/auth/oauth-flow.js.map +1 -0
- package/dist/auth/oauth-manager.d.ts +13 -0
- package/dist/auth/oauth-manager.d.ts.map +1 -0
- package/dist/auth/oauth-manager.js +25 -0
- package/dist/auth/oauth-manager.js.map +1 -0
- package/dist/auth/provider.d.ts +42 -0
- package/dist/auth/provider.d.ts.map +1 -0
- package/dist/auth/provider.js +270 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/mcp/proxy.d.ts +16 -0
- package/dist/mcp/proxy.d.ts.map +1 -0
- package/dist/mcp/proxy.js +85 -0
- package/dist/mcp/proxy.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +50 -0
- package/dist/mcp.js.map +1 -0
- package/dist/routes/auth.d.ts +6 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +149 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/chat.d.ts +6 -0
- package/dist/routes/chat.d.ts.map +1 -0
- package/dist/routes/chat.js +808 -0
- package/dist/routes/chat.js.map +1 -0
- package/dist/routes/tunnels.d.ts +7 -0
- package/dist/routes/tunnels.d.ts.map +1 -0
- package/dist/routes/tunnels.js +44 -0
- package/dist/routes/tunnels.js.map +1 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +157 -0
- package/dist/server.js.map +1 -0
- package/dist/tunnel/providers/cloudflare.d.ts +9 -0
- package/dist/tunnel/providers/cloudflare.d.ts.map +1 -0
- package/dist/tunnel/providers/cloudflare.js +47 -0
- package/dist/tunnel/providers/cloudflare.js.map +1 -0
- package/dist/tunnel/providers/index.d.ts +4 -0
- package/dist/tunnel/providers/index.d.ts.map +1 -0
- package/dist/tunnel/providers/index.js +13 -0
- package/dist/tunnel/providers/index.js.map +1 -0
- package/dist/tunnel/providers/ngrok.d.ts +10 -0
- package/dist/tunnel/providers/ngrok.d.ts.map +1 -0
- package/dist/tunnel/providers/ngrok.js +52 -0
- package/dist/tunnel/providers/ngrok.js.map +1 -0
- package/dist/tunnel/providers/tailscale.d.ts +10 -0
- package/dist/tunnel/providers/tailscale.d.ts.map +1 -0
- package/dist/tunnel/providers/tailscale.js +48 -0
- package/dist/tunnel/providers/tailscale.js.map +1 -0
- package/dist/tunnel/registry.d.ts +14 -0
- package/dist/tunnel/registry.d.ts.map +1 -0
- package/dist/tunnel/registry.js +86 -0
- package/dist/tunnel/registry.js.map +1 -0
- package/dist/tunnel/types.d.ts +26 -0
- package/dist/tunnel/types.d.ts.map +1 -0
- package/dist/tunnel/types.js +6 -0
- package/dist/tunnel/types.js.map +1 -0
- package/dist/tunnel/utils.d.ts +18 -0
- package/dist/tunnel/utils.d.ts.map +1 -0
- package/dist/tunnel/utils.js +57 -0
- package/dist/tunnel/utils.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/anthropic-to-openai-converter.d.ts +103 -0
- package/dist/utils/anthropic-to-openai-converter.d.ts.map +1 -0
- package/dist/utils/anthropic-to-openai-converter.js +376 -0
- package/dist/utils/anthropic-to-openai-converter.js.map +1 -0
- package/dist/utils/chat-to-responses.d.ts +59 -0
- package/dist/utils/chat-to-responses.d.ts.map +1 -0
- package/dist/utils/chat-to-responses.js +395 -0
- package/dist/utils/chat-to-responses.js.map +1 -0
- package/dist/utils/chatgpt-instructions.d.ts +3 -0
- package/dist/utils/chatgpt-instructions.d.ts.map +1 -0
- package/dist/utils/chatgpt-instructions.js +12 -0
- package/dist/utils/chatgpt-instructions.js.map +1 -0
- package/dist/utils/cli-args.d.ts +3 -0
- package/dist/utils/cli-args.d.ts.map +1 -0
- package/dist/utils/cli-args.js +10 -0
- package/dist/utils/cli-args.js.map +1 -0
- package/dist/utils/cors-bypass.d.ts +4 -0
- package/dist/utils/cors-bypass.d.ts.map +1 -0
- package/dist/utils/cors-bypass.js +30 -0
- package/dist/utils/cors-bypass.js.map +1 -0
- package/dist/utils/cursor-byok-bypass.d.ts +37 -0
- package/dist/utils/cursor-byok-bypass.d.ts.map +1 -0
- package/dist/utils/cursor-byok-bypass.js +53 -0
- package/dist/utils/cursor-byok-bypass.js.map +1 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +192 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/port.d.ts +27 -0
- package/dist/utils/port.d.ts.map +1 -0
- package/dist/utils/port.js +78 -0
- package/dist/utils/port.js.map +1 -0
- package/dist/utils/setup-instructions.d.ts +10 -0
- package/dist/utils/setup-instructions.d.ts.map +1 -0
- package/dist/utils/setup-instructions.js +49 -0
- package/dist/utils/setup-instructions.js.map +1 -0
- package/env.example +25 -0
- package/index.html +992 -0
- package/package.json +57 -0
- package/public/.nojekyll +0 -0
- package/public/assets/chat.png +0 -0
- package/public/assets/demo.gif +0 -0
- package/public/assets/demo.mp4 +0 -0
- package/public/assets/setup.png +0 -0
- package/public/assets/ui.png +0 -0
- package/public/index.html +292 -0
- package/release-please-config.json +10 -0
- package/src/auth/provider.ts +412 -0
- package/src/cli.ts +97 -0
- package/src/mcp/proxy.ts +64 -0
- package/src/mcp.ts +56 -0
- package/src/oauth/authorize.ts +270 -0
- package/src/oauth/crypto.ts +198 -0
- package/src/oauth/dcr.ts +129 -0
- package/src/oauth/metadata.ts +40 -0
- package/src/oauth/token.ts +173 -0
- package/src/routes/auth.ts +149 -0
- package/src/routes/chat.ts +983 -0
- package/src/routes/oauth.ts +220 -0
- package/src/routes/tunnels.ts +45 -0
- package/src/server.ts +204 -0
- package/src/tunnel/providers/cloudflare.ts +50 -0
- package/src/tunnel/providers/index.ts +7 -0
- package/src/tunnel/providers/ngrok.ts +56 -0
- package/src/tunnel/providers/tailscale.ts +50 -0
- package/src/tunnel/registry.ts +96 -0
- package/src/tunnel/types.ts +32 -0
- package/src/tunnel/utils.ts +59 -0
- package/src/types.ts +55 -0
- package/src/utils/anthropic-to-openai-converter.ts +578 -0
- package/src/utils/chat-to-responses.ts +512 -0
- package/src/utils/chatgpt-instructions.ts +7 -0
- package/src/utils/cli-args.ts +8 -0
- package/src/utils/cors-bypass.ts +39 -0
- package/src/utils/cursor-byok-bypass.ts +56 -0
- package/src/utils/logger.ts +174 -0
- package/src/utils/port.ts +99 -0
- package/src/utils/setup-instructions.ts +59 -0
- package/tsconfig.json +22 -0
- package/vercel.json +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
You can't read any files in the codebase, only use custom MCP tools to answer the user's questions.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Setup Node
|
|
19
|
+
uses: actions/setup-node@v4
|
|
20
|
+
with:
|
|
21
|
+
node-version: 20
|
|
22
|
+
registry-url: https://registry.npmjs.org
|
|
23
|
+
|
|
24
|
+
- name: Install deps
|
|
25
|
+
run: npm ci
|
|
26
|
+
|
|
27
|
+
- name: Build
|
|
28
|
+
run: npm run build
|
|
29
|
+
|
|
30
|
+
- name: Publish
|
|
31
|
+
run: npm publish --access public
|
|
32
|
+
env:
|
|
33
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Deploy Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- public/**
|
|
8
|
+
- .github/workflows/pages.yml
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
pages: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: pages
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
deploy:
|
|
22
|
+
environment:
|
|
23
|
+
name: github-pages
|
|
24
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Configure Pages
|
|
31
|
+
uses: actions/configure-pages@v4
|
|
32
|
+
|
|
33
|
+
- name: Upload artifact
|
|
34
|
+
uses: actions/upload-pages-artifact@v3
|
|
35
|
+
with:
|
|
36
|
+
path: public
|
|
37
|
+
|
|
38
|
+
- name: Deploy
|
|
39
|
+
id: deployment
|
|
40
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
release-please:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Run release-please
|
|
17
|
+
uses: googleapis/release-please-action@v4
|
|
18
|
+
with:
|
|
19
|
+
config-file: release-please-config.json
|
|
20
|
+
manifest-file: .release-please-manifest.json
|
|
21
|
+
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
package/CHANGELOG.md
ADDED
package/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## MCP settings (dev server)
|
|
4
|
+
|
|
5
|
+
Add an MCP server in Cursor with (includes auto-reload):
|
|
6
|
+
|
|
7
|
+
- Command: `npx`
|
|
8
|
+
- Args: `-y tsx watch /ABS/PATH/TO/sub-bridge/src/cli.ts --verbose`
|
|
9
|
+
|
|
10
|
+
Full JSON:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"command": "npx",
|
|
15
|
+
"args": [
|
|
16
|
+
"-y",
|
|
17
|
+
"tsx",
|
|
18
|
+
"/ABS_PATH_TO_PROJECT/src/cli.ts",
|
|
19
|
+
"--port",
|
|
20
|
+
"8080",
|
|
21
|
+
"--tunnel",
|
|
22
|
+
"8080.buremba.com",
|
|
23
|
+
"--mcp-only",
|
|
24
|
+
"--verbose"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Replace `ABS_PATH_TO_PROJECT` with your local checkout path.
|
|
30
|
+
|
|
31
|
+
Ex: `/Users/burakemre/Code/ai-experiments/cursor-claude-connector/src/cli.ts`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Your Organization
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Sub Bridge
|
|
2
|
+
|
|
3
|
+
Use ChatGPT Pro/Max, Claude Max, etc. directly in Cursor via an MCP-managed OpenAI-compatible proxy.
|
|
4
|
+
|
|
5
|
+
[](public/index.html)
|
|
6
|
+
|
|
7
|
+
## Why Sub Bridge
|
|
8
|
+
|
|
9
|
+
- Subscriptions win: Claude Code and ChatGPT Max typically deliver 3x to 5x more tokens per dollar than usage pricing.
|
|
10
|
+
- Use existing subscriptions: keep what you already pay for and route usage into Cursor.
|
|
11
|
+
- Keep Cursor UX: chat, agents, and tools continue to work; autocomplete still needs a Cursor plan.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
1. Install the MCP server:
|
|
16
|
+
|
|
17
|
+
[](cursor://anysphere.cursor-deeplink/mcp/install?name=sub-bridge&config=eyJjb21tYW5kIjogIm5weCIsICJhcmdzIjogWyIteSIsICJzdWItYnJpZGdlIl19)
|
|
18
|
+
|
|
19
|
+
1) Ask chat to connect ChatGPT Pro or Claude Max and login with your credentials locally and generate API Key for Cursor locally.
|
|
20
|
+
|
|
21
|
+
<img src="public/assets/ui.png" alt="Login and connect accounts" width="420">
|
|
22
|
+
|
|
23
|
+
2) Finish setup in Cursor (two steps side-by-side)
|
|
24
|
+
|
|
25
|
+
<table>
|
|
26
|
+
<tr>
|
|
27
|
+
<td align="center"><strong>Install Sub Bridge in Cursor</strong></td>
|
|
28
|
+
<td align="center"><strong>Paste the Base URL and API key</strong></td>
|
|
29
|
+
</tr>
|
|
30
|
+
<tr>
|
|
31
|
+
<td align="center"><img src="public/assets/setup.png" alt="Install Sub Bridge in Cursor" width="360"></td>
|
|
32
|
+
<td align="center"><img src="public/assets/chat.png" alt="Use the generated key in Cursor" width="360"></td>
|
|
33
|
+
</tr>
|
|
34
|
+
</table>
|
|
35
|
+
|
|
36
|
+
## How it works
|
|
37
|
+
|
|
38
|
+
```mermaid
|
|
39
|
+
graph LR
|
|
40
|
+
A[Cursor] --> B[MCP server]
|
|
41
|
+
A --> C[Local OpenAI-compatible proxy]
|
|
42
|
+
B --> F[OpenAI OAuth]
|
|
43
|
+
B --> G[Claude OAuth]
|
|
44
|
+
C --> D[Claude APIs]
|
|
45
|
+
C --> E[OpenAI APIs]
|
|
46
|
+
subgraph SB[Sub-bridge]
|
|
47
|
+
B
|
|
48
|
+
C
|
|
49
|
+
end
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Sub Bridge is an MCP server that includes OpenAI API proxy. It lets you login with Claude or ChatGPT and generate API keys for the proxy, which then set in Cursor Settings as an external provider.
|
|
53
|
+
|
|
54
|
+
The proxy uses Codex and Claude Code specific instructions that enables you to use Cursor with your local credentials.
|
|
55
|
+
|
|
56
|
+
## API key format and parsing
|
|
57
|
+
|
|
58
|
+
Sub Bridge reads the `Authorization: Bearer ...` header and supports multiple tokens so you can route Cursor models to Claude while still passing an OpenAI or ChatGPT token.
|
|
59
|
+
|
|
60
|
+
Rules:
|
|
61
|
+
- Tokens are space-separated. Comma separation is supported as a fallback.
|
|
62
|
+
- A routed key contains mappings before the last `:` and the API key after it.
|
|
63
|
+
- A mapping is `cursor_model=claude_model`, and multiple mappings are comma-separated.
|
|
64
|
+
- A plain token (no `=`) is treated as the default key.
|
|
65
|
+
- If a token contains `#account_id`, the suffix is used as the ChatGPT account id.
|
|
66
|
+
- Model aliases `opus-4.5` and `sonnet-4.5` expand to their full Claude model IDs.
|
|
67
|
+
- If the default key is a JWT or has an account id, requests go to the ChatGPT backend; otherwise they go to the OpenAI API.
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
Authorization: Bearer o3=opus-4.5,o3-mini=sonnet-4.5:sk-ant-xxx sk-openai-xxx
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Routes `o3` and `o3-mini` to Claude using `sk-ant-xxx`, while `sk-openai-xxx` becomes the default token.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
Authorization: Bearer o3=opus-4.5:sk-ant-xxx,sk-openai-xxx
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Comma fallback: splits into a routed Claude token plus a default token.
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
Authorization: Bearer sk-chatgpt-xxx#account_id
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Single default token routed to the ChatGPT backend.
|
package/api/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { handle } from 'hono/vercel'
|
|
2
|
+
import app from '../src/server'
|
|
3
|
+
|
|
4
|
+
export const runtime = 'nodejs'
|
|
5
|
+
|
|
6
|
+
// Export handlers for all HTTP methods
|
|
7
|
+
export const GET = handle(app)
|
|
8
|
+
export const POST = handle(app)
|
|
9
|
+
export const PUT = handle(app)
|
|
10
|
+
export const DELETE = handle(app)
|
|
11
|
+
export const PATCH = handle(app)
|
|
12
|
+
export const OPTIONS = handle(app)
|
package/bun.lock
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "proxy",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@hono/node-server": "^1.14.1",
|
|
8
|
+
"@upstash/redis": "^1.35.1",
|
|
9
|
+
"hono": "^4.8.3",
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/bun": "^1.2.18",
|
|
13
|
+
"@types/node": "^20.0.0",
|
|
14
|
+
"tsx": "^4.0.0",
|
|
15
|
+
"typescript": "^5.0.0",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
"packages": {
|
|
20
|
+
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="],
|
|
21
|
+
|
|
22
|
+
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="],
|
|
23
|
+
|
|
24
|
+
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="],
|
|
25
|
+
|
|
26
|
+
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="],
|
|
27
|
+
|
|
28
|
+
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="],
|
|
29
|
+
|
|
30
|
+
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="],
|
|
31
|
+
|
|
32
|
+
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="],
|
|
33
|
+
|
|
34
|
+
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="],
|
|
35
|
+
|
|
36
|
+
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="],
|
|
37
|
+
|
|
38
|
+
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="],
|
|
39
|
+
|
|
40
|
+
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="],
|
|
41
|
+
|
|
42
|
+
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="],
|
|
43
|
+
|
|
44
|
+
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="],
|
|
45
|
+
|
|
46
|
+
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="],
|
|
47
|
+
|
|
48
|
+
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="],
|
|
49
|
+
|
|
50
|
+
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="],
|
|
51
|
+
|
|
52
|
+
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="],
|
|
53
|
+
|
|
54
|
+
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="],
|
|
55
|
+
|
|
56
|
+
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="],
|
|
57
|
+
|
|
58
|
+
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="],
|
|
59
|
+
|
|
60
|
+
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="],
|
|
61
|
+
|
|
62
|
+
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="],
|
|
63
|
+
|
|
64
|
+
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="],
|
|
65
|
+
|
|
66
|
+
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="],
|
|
67
|
+
|
|
68
|
+
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="],
|
|
69
|
+
|
|
70
|
+
"@hono/node-server": ["@hono/node-server@1.15.0", "", { "peerDependencies": { "hono": "^4" } }, "sha512-MjmK4l5N4dQpZ9OSWN0tCj7ejuc7WvuWMzSKtc89bnknJykAeHxzRigXBTYZk85H6Awrii6RM59iUiUluApu2A=="],
|
|
71
|
+
|
|
72
|
+
"@types/bun": ["@types/bun@1.2.18", "", { "dependencies": { "bun-types": "1.2.18" } }, "sha512-Xf6RaWVheyemaThV0kUfaAUvCNokFr+bH8Jxp+tTZfx7dAPA8z9ePnP9S9+Vspzuxxx9JRAXhnyccRj3GyCMdQ=="],
|
|
73
|
+
|
|
74
|
+
"@types/node": ["@types/node@20.19.4", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA=="],
|
|
75
|
+
|
|
76
|
+
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
|
77
|
+
|
|
78
|
+
"@upstash/redis": ["@upstash/redis@1.35.1", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-sIMuAMU9IYbE2bkgDby8KLoQKRiBMXn0moXxqLvUmQ7VUu2CvulZLtK8O0x3WQZFvvZhU5sRC2/lOVZdGfudkA=="],
|
|
79
|
+
|
|
80
|
+
"bun-types": ["bun-types@1.2.18", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-04+Eha5NP7Z0A9YgDAzMk5PHR16ZuLVa83b26kH5+cp1qZW4F6FmAURngE7INf4tKOvCE69vYvDEwoNl1tGiWw=="],
|
|
81
|
+
|
|
82
|
+
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
83
|
+
|
|
84
|
+
"esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="],
|
|
85
|
+
|
|
86
|
+
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
|
87
|
+
|
|
88
|
+
"get-tsconfig": ["get-tsconfig@4.10.1", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ=="],
|
|
89
|
+
|
|
90
|
+
"hono": ["hono@4.8.3", "", {}, "sha512-jYZ6ZtfWjzBdh8H/0CIFfCBHaFL75k+KMzaM177hrWWm2TWL39YMYaJgB74uK/niRc866NMlH9B8uCvIo284WQ=="],
|
|
91
|
+
|
|
92
|
+
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
|
|
93
|
+
|
|
94
|
+
"tsx": ["tsx@4.20.3", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ=="],
|
|
95
|
+
|
|
96
|
+
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
|
97
|
+
|
|
98
|
+
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
|
99
|
+
|
|
100
|
+
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface PKCE {
|
|
2
|
+
verifier: string;
|
|
3
|
+
challenge: string;
|
|
4
|
+
}
|
|
5
|
+
interface TokenResponse {
|
|
6
|
+
access_token: string;
|
|
7
|
+
refresh_token: string;
|
|
8
|
+
expires_in: number;
|
|
9
|
+
}
|
|
10
|
+
interface ExchangeOptions {
|
|
11
|
+
persist?: boolean;
|
|
12
|
+
log?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function getAuthorizationUrl(pkce: PKCE): string;
|
|
15
|
+
export declare function exchangeCodeForTokens(code: string, verifier: string, options?: ExchangeOptions): Promise<TokenResponse>;
|
|
16
|
+
export declare function generateAuthSession(): Promise<{
|
|
17
|
+
authUrl: string;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function handleOAuthCallback(code: string, sessionId: string): Promise<TokenResponse>;
|
|
21
|
+
export declare function login(): Promise<boolean>;
|
|
22
|
+
export declare function logout(): Promise<boolean>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=oauth-flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-flow.ts"],"names":[],"mappings":"AAQA,UAAU,IAAI;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,aAAa;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAiBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAetD;AAuCD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAuCxB;AAGD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAC,CASD;AAGD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CAMxB;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAgB9C;AAED,wBAAsB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAS/C"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getAuthorizationUrl = getAuthorizationUrl;
|
|
40
|
+
exports.exchangeCodeForTokens = exchangeCodeForTokens;
|
|
41
|
+
exports.generateAuthSession = generateAuthSession;
|
|
42
|
+
exports.handleOAuthCallback = handleOAuthCallback;
|
|
43
|
+
exports.login = login;
|
|
44
|
+
exports.logout = logout;
|
|
45
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
46
|
+
const authManager = __importStar(require("./oauth-manager"));
|
|
47
|
+
const CLIENT_ID = process.env.ANTHROPIC_OAUTH_CLIENT_ID ||
|
|
48
|
+
'9d1c250a-e61b-44d9-88ed-5944d1962f5e';
|
|
49
|
+
const REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';
|
|
50
|
+
function splitCodeState(code) {
|
|
51
|
+
const splits = code.split('#');
|
|
52
|
+
return { code: splits[0], state: splits[1] || undefined };
|
|
53
|
+
}
|
|
54
|
+
function generatePKCE() {
|
|
55
|
+
const verifier = crypto_1.default.randomBytes(32).toString('base64url');
|
|
56
|
+
const challenge = crypto_1.default
|
|
57
|
+
.createHash('sha256')
|
|
58
|
+
.update(verifier)
|
|
59
|
+
.digest('base64url');
|
|
60
|
+
return { verifier, challenge };
|
|
61
|
+
}
|
|
62
|
+
function getAuthorizationUrl(pkce) {
|
|
63
|
+
const authUrl = new URL('https://claude.ai/oauth/authorize');
|
|
64
|
+
authUrl.searchParams.set('code', 'true');
|
|
65
|
+
authUrl.searchParams.set('client_id', CLIENT_ID);
|
|
66
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
67
|
+
authUrl.searchParams.set('redirect_uri', REDIRECT_URI);
|
|
68
|
+
authUrl.searchParams.set('scope', 'org:create_api_key user:profile user:inference');
|
|
69
|
+
authUrl.searchParams.set('code_challenge', pkce.challenge);
|
|
70
|
+
authUrl.searchParams.set('code_challenge_method', 'S256');
|
|
71
|
+
authUrl.searchParams.set('state', pkce.verifier);
|
|
72
|
+
return authUrl.toString();
|
|
73
|
+
}
|
|
74
|
+
async function startAuthFlow() {
|
|
75
|
+
const pkce = generatePKCE();
|
|
76
|
+
const authUrl = getAuthorizationUrl(pkce);
|
|
77
|
+
console.log('\n🔐 OAuth Authentication Required');
|
|
78
|
+
console.log('Please visit the following URL to authenticate:');
|
|
79
|
+
console.log(`\n${authUrl}\n`);
|
|
80
|
+
console.log('After authentication, you will get a code.');
|
|
81
|
+
console.log('Please paste the entire code here and press Enter:\n');
|
|
82
|
+
// Read code from stdin
|
|
83
|
+
const code = await readCodeFromStdin();
|
|
84
|
+
if (!code) {
|
|
85
|
+
throw new Error('No code provided');
|
|
86
|
+
}
|
|
87
|
+
// Exchange code for tokens
|
|
88
|
+
return await exchangeCodeForTokens(code, pkce.verifier);
|
|
89
|
+
}
|
|
90
|
+
async function readCodeFromStdin() {
|
|
91
|
+
return new Promise((resolve) => {
|
|
92
|
+
let code = '';
|
|
93
|
+
process.stdin.setEncoding('utf8');
|
|
94
|
+
process.stdin.resume();
|
|
95
|
+
process.stdin.on('data', (chunk) => {
|
|
96
|
+
code += chunk;
|
|
97
|
+
if (code.includes('\n')) {
|
|
98
|
+
process.stdin.pause();
|
|
99
|
+
resolve(code.trim());
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async function exchangeCodeForTokens(code, verifier, options = {}) {
|
|
105
|
+
const { code: authCode, state } = splitCodeState(code);
|
|
106
|
+
const response = await fetch('https://console.anthropic.com/v1/oauth/token', {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
code: authCode,
|
|
113
|
+
state: state || verifier,
|
|
114
|
+
grant_type: 'authorization_code',
|
|
115
|
+
client_id: CLIENT_ID,
|
|
116
|
+
redirect_uri: REDIRECT_URI,
|
|
117
|
+
code_verifier: verifier,
|
|
118
|
+
}),
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const error = await response.text();
|
|
122
|
+
throw new Error(`Failed to exchange code: ${error}`);
|
|
123
|
+
}
|
|
124
|
+
const data = (await response.json());
|
|
125
|
+
const shouldPersist = options.persist ?? true;
|
|
126
|
+
const shouldLog = options.log ?? true;
|
|
127
|
+
if (shouldPersist) {
|
|
128
|
+
await authManager.set({
|
|
129
|
+
type: 'oauth',
|
|
130
|
+
refresh: data.refresh_token,
|
|
131
|
+
access: data.access_token,
|
|
132
|
+
expires: Date.now() + data.expires_in * 1000,
|
|
133
|
+
});
|
|
134
|
+
if (shouldLog) {
|
|
135
|
+
console.log('✅ OAuth tokens saved successfully!');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return data;
|
|
139
|
+
}
|
|
140
|
+
// New function to generate auth URL and store PKCE verifier
|
|
141
|
+
async function generateAuthSession() {
|
|
142
|
+
const pkce = generatePKCE();
|
|
143
|
+
const authUrl = getAuthorizationUrl(pkce);
|
|
144
|
+
// Store PKCE verifier temporarily (in production, use a proper session store)
|
|
145
|
+
// For now, we'll use the verifier as the session ID
|
|
146
|
+
const sessionId = pkce.verifier;
|
|
147
|
+
return { authUrl, sessionId };
|
|
148
|
+
}
|
|
149
|
+
// New function to handle OAuth callback
|
|
150
|
+
async function handleOAuthCallback(code, sessionId) {
|
|
151
|
+
// In production, retrieve the verifier from session store
|
|
152
|
+
// For now, we use the sessionId as the verifier
|
|
153
|
+
const verifier = sessionId;
|
|
154
|
+
return await exchangeCodeForTokens(code, verifier);
|
|
155
|
+
}
|
|
156
|
+
async function login() {
|
|
157
|
+
try {
|
|
158
|
+
// Check if we already have valid credentials
|
|
159
|
+
const existing = await authManager.get();
|
|
160
|
+
if (existing && existing.access && existing.expires > Date.now()) {
|
|
161
|
+
console.log('✅ Valid OAuth credentials already exist');
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Start OAuth flow
|
|
165
|
+
await startAuthFlow();
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error('OAuth login failed:', error);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function logout() {
|
|
174
|
+
try {
|
|
175
|
+
await authManager.remove();
|
|
176
|
+
console.log('✅ OAuth credentials removed');
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
console.error('Logout failed:', error);
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=oauth-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-flow.js","sourceRoot":"","sources":["../../src/auth/oauth-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface OAuthCredentials {
|
|
2
|
+
type: 'oauth';
|
|
3
|
+
refresh: string;
|
|
4
|
+
access: string;
|
|
5
|
+
expires: number;
|
|
6
|
+
}
|
|
7
|
+
declare function get(): Promise<OAuthCredentials | null>;
|
|
8
|
+
declare function set(credentials: OAuthCredentials): Promise<boolean>;
|
|
9
|
+
declare function remove(): Promise<boolean>;
|
|
10
|
+
declare function getAll(): Promise<Record<string, OAuthCredentials>>;
|
|
11
|
+
declare function getAccessToken(): Promise<string | null>;
|
|
12
|
+
export { get, set, remove, getAll, getAccessToken };
|
|
13
|
+
//# sourceMappingURL=oauth-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-manager.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-manager.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB;IACxB,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,iBAAe,GAAG,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAErD;AAED,iBAAe,GAAG,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAElE;AAED,iBAAe,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAExC;AAED,iBAAe,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAEjE;AAED,iBAAe,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAItD;AAED,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get = get;
|
|
4
|
+
exports.set = set;
|
|
5
|
+
exports.remove = remove;
|
|
6
|
+
exports.getAll = getAll;
|
|
7
|
+
exports.getAccessToken = getAccessToken;
|
|
8
|
+
async function get() {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
async function set(credentials) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
async function remove() {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
async function getAll() {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
async function getAccessToken() {
|
|
21
|
+
console.error('OAuth is disabled. Provide tokens via Cursor API Key instead.');
|
|
22
|
+
console.error('Use MCP tool get_status for Claude OAuth, or run `claude setup-token` or `codex login`.');
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=oauth-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-manager.js","sourceRoot":"","sources":["../../src/auth/oauth-manager.ts"],"names":[],"mappings":";;AA6BS,kBAAG;AAAE,kBAAG;AAAE,wBAAM;AAAE,wBAAM;AAAE,wCAAc;AAtBjD,KAAK,UAAU,GAAG;IAChB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,WAA6B;IAC9C,OAAO,KAAK,CAAA;AACd,CAAC;AAED,KAAK,UAAU,MAAM;IACnB,OAAO,KAAK,CAAA;AACd,CAAC;AAED,KAAK,UAAU,MAAM;IACnB,OAAO,EAAE,CAAA;AACX,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAA;IAC9E,OAAO,CAAC,KAAK,CAAC,yFAAyF,CAAC,CAAA;IACxG,OAAO,IAAI,CAAA;AACb,CAAC"}
|