Skip to content

Commit c79ce70

Browse files
committed
Add browserAuth() provider for MCP SDK integration
1 parent c6b6ed6 commit c79ce70

File tree

16 files changed

+1596
-298
lines changed

16 files changed

+1596
-298
lines changed

.github/workflows/main.yml

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
name: CI/CD
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
test:
16+
name: Test (Bun on ${{ matrix.os }})
17+
runs-on: ${{ matrix.os }}
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
os: [ubuntu-latest, macos-latest]
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v5
26+
27+
- name: Setup Bun
28+
uses: oven-sh/setup-bun@v2
29+
with:
30+
bun-version: latest
31+
32+
- name: Install dependencies
33+
run: bun install --frozen-lockfile
34+
35+
- name: Build templates
36+
run: bun run build:templates
37+
38+
- name: Run tests
39+
run: bun test
40+
41+
- name: Type check
42+
if: matrix.os == 'ubuntu-latest'
43+
run: bun run typecheck
44+
45+
build:
46+
name: Build & Validate
47+
runs-on: ubuntu-latest
48+
49+
steps:
50+
- name: Checkout code
51+
uses: actions/checkout@v5
52+
53+
- name: Setup Bun
54+
uses: oven-sh/setup-bun@v2
55+
with:
56+
bun-version: latest
57+
58+
- name: Cache dependencies
59+
uses: actions/cache@v4
60+
with:
61+
path: ~/.bun/install/cache
62+
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
63+
restore-keys: |
64+
${{ runner.os }}-bun-
65+
66+
- name: Install dependencies
67+
run: bun install --frozen-lockfile
68+
69+
- name: Check formatting
70+
run: bun run format:check
71+
72+
- name: Type check
73+
run: bun run typecheck
74+
75+
- name: Build templates
76+
run: bun templates/build.ts
77+
78+
- name: Build package
79+
run: bun run build
80+
81+
- name: Validate package
82+
run: bun run lint:package
83+
84+
- name: Check dist output
85+
run: |
86+
if [ ! -f "dist/index.js" ]; then
87+
echo "Error: dist/index.js not found"
88+
exit 1
89+
fi
90+
if [ ! -f "dist/index.d.ts" ]; then
91+
echo "Error: dist/index.d.ts not found"
92+
exit 1
93+
fi
94+
echo "✅ Build output verified"
95+
96+
- name: Upload build artifacts
97+
uses: actions/upload-artifact@v4
98+
with:
99+
name: dist
100+
path: dist/
101+
retention-days: 1
102+
103+
validate-examples:
104+
name: Validate Examples
105+
runs-on: ubuntu-latest
106+
needs: build
107+
108+
steps:
109+
- name: Checkout code
110+
uses: actions/checkout@v5
111+
112+
- name: Setup Bun
113+
uses: oven-sh/setup-bun@v2
114+
with:
115+
bun-version: latest
116+
117+
- name: Install dependencies
118+
run: bun install --frozen-lockfile
119+
120+
- name: Download build artifacts
121+
uses: actions/download-artifact@v5
122+
with:
123+
name: dist
124+
path: dist/
125+
126+
- name: Test demo example (dry run)
127+
run: bun run examples/demo.ts --no-browser
128+
timeout-minutes: 1
129+
130+
- name: Check example files
131+
run: |
132+
for file in examples/*.ts; do
133+
echo "Checking $file..."
134+
if [[ "$file" == *"demo.ts"* ]]; then
135+
echo "✓ $file - skipping (interactive demo)"
136+
else
137+
bun build "$file" --target=node --outdir=/tmp/build-test > /dev/null && echo "✓ $file builds successfully"
138+
fi
139+
done
140+
141+
publish:
142+
name: Publish to NPM
143+
runs-on: ubuntu-latest
144+
needs: [test, build, validate-examples]
145+
if: startsWith(github.ref, 'refs/tags/v')
146+
environment: npm
147+
permissions:
148+
contents: write
149+
id-token: write
150+
151+
steps:
152+
- name: Checkout code
153+
uses: actions/checkout@v5
154+
155+
- name: Setup Node.js
156+
uses: actions/setup-node@v4
157+
with:
158+
node-version: "20"
159+
registry-url: "https://registry.npmjs.org"
160+
161+
- name: Setup Bun
162+
uses: oven-sh/setup-bun@v2
163+
with:
164+
bun-version: latest
165+
166+
- name: Install dependencies
167+
run: bun install --frozen-lockfile
168+
169+
- name: Build package
170+
run: |
171+
bun run build:templates
172+
bun run build
173+
174+
- name: Verify version match
175+
run: |
176+
PACKAGE_VERSION="v$(node -p "require('./package.json').version")"
177+
TAG_VERSION="${GITHUB_REF#refs/tags/}"
178+
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
179+
echo "Error: Package version ($PACKAGE_VERSION) doesn't match tag ($TAG_VERSION)"
180+
exit 1
181+
fi
182+
echo "✅ Version verified: $PACKAGE_VERSION"
183+
184+
- name: Publish to NPM
185+
run: npm publish --provenance --access public
186+
env:
187+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
188+
189+
- name: Create GitHub Release
190+
uses: softprops/action-gh-release@v2
191+
with:
192+
name: Release ${{ github.ref_name }}
193+
generate_release_notes: true
194+
draft: false
195+
prerelease: ${{ contains(github.ref_name, '-') }}
196+
files: |
197+
dist/**/*
198+
199+
security:
200+
name: Security Scan
201+
runs-on: ubuntu-latest
202+
if: github.event_name == 'pull_request' || github.event_name == 'push'
203+
204+
steps:
205+
- name: Checkout code
206+
uses: actions/checkout@v5
207+
with:
208+
fetch-depth: 0
209+
210+
- name: Run Dependabot security scan
211+
uses: github/super-linter/slim@v7
212+
env:
213+
DEFAULT_BRANCH: main
214+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
215+
VALIDATE_JAVASCRIPT_ES: true
216+
VALIDATE_TYPESCRIPT_ES: true
217+
VALIDATE_JSON: true
218+
VALIDATE_YAML: true
219+
FILTER_REGEX_EXCLUDE: .*node_modules/.*|.*dist/.*|.*bun.lock|.*tsconfig\.json

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"konstantin",
66
"kriasoft",
77
"modelcontextprotocol",
8+
"publint",
89
"streamable",
910
"tarkus"
1011
]

CLAUDE.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# OAuth Callback Project Guide
2+
3+
## Project Structure
4+
5+
```bash
6+
oauth-callback/
7+
├── src/ # Source code
8+
│ ├── index.ts # Main entry - exports getAuthCode(), OAuthError, browserAuth()
9+
│ ├── server.ts # HTTP server for OAuth callbacks
10+
│ ├── errors.ts # OAuthError class and error handling
11+
│ ├── mcp-types.ts # TypeScript interfaces for MCP integration
12+
│ ├── auth/ # Authentication providers
13+
│ │ ├── browser-auth.ts # MCP SDK-compatible OAuth provider
14+
│ │ └── browser-auth.test.ts
15+
│ ├── storage/ # Token storage implementations
16+
│ │ └── memory.ts # In-memory token store
17+
│ └── utils/ # Utility functions
18+
│ └── token.ts # Token expiry calculations
19+
20+
├── templates/ # HTML templates for callback pages
21+
│ ├── success.html # Success page with animated checkmark
22+
│ ├── error.html # Error page for OAuth failures
23+
│ └── build.ts # Template compiler (bundles HTML into TypeScript)
24+
25+
├── examples/ # Usage examples
26+
│ ├── demo.ts # Interactive demo with mock OAuth server
27+
│ ├── github.ts # GitHub OAuth integration example
28+
│ └── notion.ts # Notion MCP with Dynamic Client Registration
29+
30+
├── dist/ # Build output (generated)
31+
│ ├── index.js # Compiled JavaScript
32+
│ ├── index.d.ts # TypeScript declarations
33+
│ └── ...
34+
35+
├── package.json # Project metadata and dependencies
36+
├── tsconfig.json # TypeScript configuration
37+
├── README.md # User documentation
38+
└── CLAUDE.md # This file - AI assistant context
39+
```
40+
41+
## Key Constraints
42+
43+
- Design Philosophy: Prioritize ideal design over backward compatibility
44+
- Runtime: Always use Bun (not Node.js/NPM). Bun auto-loads .env files
45+
- MCP SDK: OAuth/auth implementation in `node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js`, `node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts`

0 commit comments

Comments
 (0)