Skip to content

Commit 705b0e8

Browse files
committed
feat: support custom scope in auth flow
1 parent dc76e41 commit 705b0e8

File tree

7 files changed

+47
-58
lines changed

7 files changed

+47
-58
lines changed

client/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/inspector-client",
3-
"version": "0.13.0",
3+
"version": "0.12.0",
44
"description": "Client-side application for the Model Context Protocol inspector",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -23,9 +23,8 @@
2323
"test:watch": "jest --config jest.config.cjs --watch"
2424
},
2525
"dependencies": {
26-
"@modelcontextprotocol/sdk": "^1.11.5",
26+
"@modelcontextprotocol/sdk": "^1.11.3",
2727
"@radix-ui/react-checkbox": "^1.1.4",
28-
"ajv": "^6.12.6",
2928
"@radix-ui/react-dialog": "^1.1.3",
3029
"@radix-ui/react-icons": "^1.3.0",
3130
"@radix-ui/react-label": "^2.1.0",

client/src/App.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ const App = () => {
114114
return localStorage.getItem("lastOauthClientId") || "";
115115
});
116116

117+
const [oauthScope, setOauthScope] = useState<string>(() => {
118+
return localStorage.getItem("lastOauthScope") || "";
119+
});
120+
117121
const [pendingSampleRequests, setPendingSampleRequests] = useState<
118122
Array<
119123
PendingRequest & {
@@ -189,6 +193,7 @@ const App = () => {
189193
bearerToken,
190194
headerName,
191195
oauthClientId,
196+
oauthScope,
192197
config,
193198
onNotification: (notification) => {
194199
setNotifications((prev) => [...prev, notification as ServerNotification]);
@@ -236,6 +241,10 @@ const App = () => {
236241
localStorage.setItem("lastOauthClientId", oauthClientId);
237242
}, [oauthClientId]);
238243

244+
useEffect(() => {
245+
localStorage.setItem("lastOauthScope", oauthScope);
246+
}, [oauthScope]);
247+
239248
useEffect(() => {
240249
localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
241250
}, [config]);
@@ -594,6 +603,8 @@ const App = () => {
594603
setHeaderName={setHeaderName}
595604
oauthClientId={oauthClientId}
596605
setOauthClientId={setOauthClientId}
606+
oauthScope={oauthScope}
607+
setOauthScope={setOauthScope}
597608
onConnect={connectMcpServer}
598609
onDisconnect={disconnectMcpServer}
599610
stdErrNotifications={stdErrNotifications}

client/src/components/Sidebar.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ interface SidebarProps {
5858
setHeaderName?: (name: string) => void;
5959
oauthClientId: string;
6060
setOauthClientId: (id: string) => void;
61+
oauthScope: string;
62+
setOauthScope: (scope: string) => void;
6163
onConnect: () => void;
6264
onDisconnect: () => void;
6365
stdErrNotifications: StdErrNotification[];
@@ -87,6 +89,8 @@ const Sidebar = ({
8789
setHeaderName,
8890
oauthClientId,
8991
setOauthClientId,
92+
oauthScope,
93+
setOauthScope,
9094
onConnect,
9195
onDisconnect,
9296
stdErrNotifications,
@@ -369,6 +373,14 @@ const Sidebar = ({
369373
data-testid="oauth-client-id-input"
370374
className="font-mono"
371375
/>
376+
<label className="text-sm font-medium">Scope</label>
377+
<Input
378+
placeholder="Scope (space-separated)"
379+
onChange={(e) => setOauthScope(e.target.value)}
380+
value={oauthScope}
381+
data-testid="oauth-scope-input"
382+
className="font-mono"
383+
/>
372384
<label className="text-sm font-medium">
373385
Redirect URL (auto-populated)
374386
</label>

client/src/components/__tests__/Sidebar.test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ describe("Sidebar Environment Variables", () => {
4444
setSseUrl: jest.fn(),
4545
oauthClientId: "",
4646
setOauthClientId: jest.fn(),
47+
oauthScope: "",
48+
setOauthScope: jest.fn(),
4749
env: {},
4850
setEnv: jest.fn(),
4951
bearerToken: "",

client/src/lib/auth.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
3232
// Save the client information to session storage if provided
3333
if (clientInformation) {
3434
this.saveClientInformation(clientInformation);
35+
} else {
36+
this.clearClientInformation();
3537
}
3638
}
3739

@@ -113,6 +115,12 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
113115
getServerSpecificKey(SESSION_KEYS.CODE_VERIFIER, this.serverUrl),
114116
);
115117
}
118+
119+
clearClientInformation() {
120+
sessionStorage.removeItem(
121+
getServerSpecificKey(SESSION_KEYS.CLIENT_INFORMATION, this.serverUrl),
122+
);
123+
}
116124
}
117125

118126
// Overrides debug URL and allows saving server OAuth metadata to

client/src/lib/hooks/useConnection.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ interface UseConnectionOptions {
5757
bearerToken?: string;
5858
headerName?: string;
5959
oauthClientId?: string;
60+
oauthScope?: string;
6061
config: InspectorConfig;
6162
onNotification?: (notification: Notification) => void;
6263
onStdErrNotification?: (notification: Notification) => void;
@@ -75,6 +76,7 @@ export function useConnection({
7576
bearerToken,
7677
headerName,
7778
oauthClientId,
79+
oauthScope,
7880
config,
7981
onNotification,
8082
onStdErrNotification,
@@ -280,7 +282,10 @@ export function useConnection({
280282
oauthClientInformation,
281283
);
282284

283-
const result = await auth(serverAuthProvider, { serverUrl: sseUrl });
285+
const result = await auth(serverAuthProvider, {
286+
serverUrl: sseUrl,
287+
scope: oauthScope,
288+
});
284289
return result === "AUTHORIZED";
285290
}
286291

package-lock.json

Lines changed: 6 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)