Skip to content

Commit 9660491

Browse files
committed
format
1 parent 8a71032 commit 9660491

18 files changed

+405
-325
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export default antfu({
55
typescript: true,
66
rules: {
77
'node/prefer-global/process': 'off',
8+
'no-console': 'off',
89
},
910
}, {
1011
files: ['examples/**/*.ts'],

examples/react/index.html

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>MCP Tools Explorer - React Example</title>
77
<style>
8-
body {
9-
margin: 0;
10-
padding: 0;
11-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
12-
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
13-
sans-serif;
14-
-webkit-font-smoothing: antialiased;
15-
-moz-osx-font-smoothing: grayscale;
16-
background-color: #f5f5f5;
17-
}
18-
19-
#root {
20-
min-height: 100vh;
21-
}
22-
23-
.container {
24-
max-width: 1200px;
25-
margin: 0 auto;
26-
padding: 20px;
27-
}
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
font-family:
12+
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
13+
'Droid Sans', 'Helvetica Neue', sans-serif;
14+
-webkit-font-smoothing: antialiased;
15+
-moz-osx-font-smoothing: grayscale;
16+
background-color: #f5f5f5;
17+
}
18+
19+
#root {
20+
min-height: 100vh;
21+
}
22+
23+
.container {
24+
max-width: 1200px;
25+
margin: 0 auto;
26+
padding: 20px;
27+
}
2828
</style>
29-
</head>
30-
<body>
29+
</head>
30+
<body>
3131
<div id="root">
32-
<div class="container">
33-
<h1>Loading MCP Tools Explorer...</h1>
34-
<p>If this message persists, check the browser console for errors.</p>
35-
</div>
32+
<div class="container">
33+
<h1>Loading MCP Tools Explorer...</h1>
34+
<p>If this message persists, check the browser console for errors.</p>
35+
</div>
3636
</div>
37-
37+
3838
<!-- React and ReactDOM will be loaded by the bundler -->
3939
<script type="module" src="./index.tsx"></script>
40-
</body>
40+
</body>
4141
</html>

examples/react/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const container = document.getElementById('root')
66
if (container) {
77
const root = createRoot(container)
88
root.render(<ReactExample />)
9-
} else {
9+
}
10+
else {
1011
console.error('Root element not found')
1112
}

examples/react/oauth-helper.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* OAuth helper for browser-based MCP authentication
3-
*
3+
*
44
* This helper provides OAuth 2.0 authorization code flow support for MCP servers
55
* that require authentication, such as Linear's MCP server.
66
*/
@@ -107,12 +107,13 @@ export class OAuthHelper {
107107
// Any other response (200, 404, 500, etc.) means no auth required
108108
console.log('✅ [OAuthHelper] No authentication required for:', serverUrl)
109109
return false
110-
} catch (error: any) {
110+
}
111+
catch (error: any) {
111112
console.warn('⚠️ [OAuthHelper] Could not check auth requirement for:', serverUrl, error)
112113

113114
// Handle specific error types
114-
if (error.name === 'TypeError' &&
115-
(error.message?.includes('CORS') || error.message?.includes('Failed to fetch'))) {
115+
if (error.name === 'TypeError'
116+
&& (error.message?.includes('CORS') || error.message?.includes('Failed to fetch'))) {
116117
console.log('🔍 [OAuthHelper] CORS blocked direct check, using heuristics for:', serverUrl)
117118
return this.checkAuthByHeuristics(serverUrl)
118119
}
@@ -149,7 +150,7 @@ export class OAuthHelper {
149150
// Known patterns that typically don't require auth (public MCP servers)
150151
const noAuthPatterns = [
151152
/localhost/i, // Local development
152-
/127\.0\.0\.1/i, // Local development
153+
/127\.0\.0\.1/, // Local development
153154
/\.local/i, // Local development
154155
/mcp\..*\.com/i, // Generic MCP server pattern (often public)
155156
]
@@ -182,22 +183,23 @@ export class OAuthHelper {
182183
try {
183184
const discoveryUrl = `${serverUrl}/.well-known/oauth-authorization-server`
184185
const response = await fetch(discoveryUrl)
185-
186+
186187
if (!response.ok) {
187188
throw new Error(`OAuth discovery failed: ${response.status} ${response.statusText}`)
188189
}
189-
190+
190191
this.discovery = await response.json()
191192
return this.discovery
192-
} catch (error) {
193+
}
194+
catch (error) {
193195
throw new Error(`Failed to discover OAuth configuration: ${error}`)
194196
}
195197
}
196198

197199
/**
198200
* Register a new OAuth client dynamically
199201
*/
200-
async registerClient(serverUrl: string): Promise<ClientRegistration> {
202+
async registerClient(_serverUrl: string): Promise<ClientRegistration> {
201203
if (!this.discovery) {
202204
throw new Error('OAuth discovery not performed. Call discoverOAuthConfig first.')
203205
}
@@ -227,7 +229,7 @@ export class OAuthHelper {
227229
headers: {
228230
'Content-Type': 'application/json',
229231
},
230-
body: JSON.stringify(registrationData)
232+
body: JSON.stringify(registrationData),
231233
})
232234

233235
if (!response.ok) {
@@ -242,7 +244,8 @@ export class OAuthHelper {
242244
})
243245

244246
return this.clientRegistration
245-
} catch (error) {
247+
}
248+
catch (error) {
246249
console.error('❌ [OAuthHelper] Client registration failed:', error)
247250
throw new Error(`Failed to register OAuth client: ${error}`)
248251
}
@@ -262,7 +265,7 @@ export class OAuthHelper {
262265
response_type: 'code',
263266
scope: this.config.scope || 'read',
264267
state: this.config.state || this.generateState(),
265-
...additionalParams
268+
...additionalParams,
266269
})
267270

268271
return `${this.discovery.authorization_endpoint}?${params.toString()}`
@@ -272,9 +275,9 @@ export class OAuthHelper {
272275
* Exchange authorization code for access token
273276
*/
274277
async exchangeCodeForToken(
275-
serverUrl: string,
276-
code: string,
277-
codeVerifier?: string
278+
serverUrl: string,
279+
code: string,
280+
codeVerifier?: string,
278281
): Promise<OAuthResult> {
279282
if (!this.discovery) {
280283
throw new Error('OAuth discovery not performed. Call discoverOAuthConfig first.')
@@ -296,7 +299,7 @@ export class OAuthHelper {
296299
headers: {
297300
'Content-Type': 'application/x-www-form-urlencoded',
298301
},
299-
body: body.toString()
302+
body: body.toString(),
300303
})
301304

302305
if (!response.ok) {
@@ -310,7 +313,7 @@ export class OAuthHelper {
310313
/**
311314
* Handle OAuth callback and extract authorization code
312315
*/
313-
handleCallback(): { code: string; state: string } | null {
316+
handleCallback(): { code: string, state: string } | null {
314317
const urlParams = new URLSearchParams(window.location.search)
315318
const code = urlParams.get('code')
316319
const state = urlParams.get('state')
@@ -340,20 +343,21 @@ export class OAuthHelper {
340343
try {
341344
await this.discoverOAuthConfig(serverUrl)
342345
const authUrl = this.generateAuthUrl(serverUrl)
343-
346+
344347
// Open popup window for authentication (similar to your implementation)
345348
const authWindow = window.open(
346349
authUrl,
347350
'mcp-oauth',
348-
'width=500,height=600,scrollbars=yes,resizable=yes,status=yes,location=yes'
351+
'width=500,height=600,scrollbars=yes,resizable=yes,status=yes,location=yes',
349352
)
350353

351354
if (!authWindow) {
352355
throw new Error('Failed to open authentication window. Please allow popups for this site and try again.')
353356
}
354357

355358
console.log('✅ [OAuthHelper] OAuth popup opened successfully')
356-
} catch (error) {
359+
}
360+
catch (error) {
357361
console.error('❌ [OAuthHelper] Failed to start OAuth flow:', error)
358362
this.setState({
359363
isAuthenticating: false,
@@ -374,7 +378,7 @@ export class OAuthHelper {
374378

375379
try {
376380
const tokenResponse = await this.exchangeCodeForToken(serverUrl, code)
377-
381+
378382
this.setState({
379383
isAuthenticating: false,
380384
isAuthenticated: true,
@@ -385,7 +389,8 @@ export class OAuthHelper {
385389

386390
console.log('✅ [OAuthHelper] OAuth flow completed successfully')
387391
return tokenResponse
388-
} catch (error) {
392+
}
393+
catch (error) {
389394
console.error('❌ [OAuthHelper] Failed to complete OAuth flow:', error)
390395
this.setState({
391396
isAuthenticating: false,
@@ -421,8 +426,8 @@ export class OAuthHelper {
421426
* Generate a random state parameter for CSRF protection
422427
*/
423428
private generateState(): string {
424-
return Math.random().toString(36).substring(2, 15) +
425-
Math.random().toString(36).substring(2, 15)
429+
return Math.random().toString(36).substring(2, 15)
430+
+ Math.random().toString(36).substring(2, 15)
426431
}
427432
}
428433

@@ -444,8 +449,8 @@ export function createOAuthMCPConfig(serverUrl: string, accessToken: string) {
444449
linear: {
445450
url: serverUrl,
446451
authToken: accessToken,
447-
transport: 'sse'
448-
}
449-
}
452+
transport: 'sse',
453+
},
454+
},
450455
}
451456
}

examples/react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "mcp-use-react-example",
3-
"version": "1.0.0",
43
"type": "module",
4+
"version": "1.0.0",
55
"scripts": {
66
"dev": "vite",
77
"build": "vite build",

examples/react/react_example.html

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>MCP Tools Explorer - React Example</title>
77
<style>
8-
body {
9-
margin: 0;
10-
padding: 0;
11-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
12-
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
13-
sans-serif;
14-
-webkit-font-smoothing: antialiased;
15-
-moz-osx-font-smoothing: grayscale;
16-
background-color: #f5f5f5;
17-
}
18-
19-
#root {
20-
min-height: 100vh;
21-
}
22-
23-
.container {
24-
max-width: 1200px;
25-
margin: 0 auto;
26-
padding: 20px;
27-
}
8+
body {
9+
margin: 0;
10+
padding: 0;
11+
font-family:
12+
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
13+
'Droid Sans', 'Helvetica Neue', sans-serif;
14+
-webkit-font-smoothing: antialiased;
15+
-moz-osx-font-smoothing: grayscale;
16+
background-color: #f5f5f5;
17+
}
18+
19+
#root {
20+
min-height: 100vh;
21+
}
22+
23+
.container {
24+
max-width: 1200px;
25+
margin: 0 auto;
26+
padding: 20px;
27+
}
2828
</style>
29-
</head>
30-
<body>
29+
</head>
30+
<body>
3131
<div id="root">
32-
<div class="container">
33-
<h1>Loading MCP Tools Explorer...</h1>
34-
<p>If this message persists, check the browser console for errors.</p>
35-
</div>
32+
<div class="container">
33+
<h1>Loading MCP Tools Explorer...</h1>
34+
<p>If this message persists, check the browser console for errors.</p>
35+
</div>
3636
</div>
37-
37+
3838
<!-- React and ReactDOM will be loaded by the bundler -->
3939
<script type="module" src="./index.tsx"></script>
40-
</body>
40+
</body>
4141
</html>

0 commit comments

Comments
 (0)