Skip to content

Commit bcfb332

Browse files
authored
Merge branch 'main' into pcarleton/auth-debugger
2 parents 50a4895 + 89d721e commit bcfb332

28 files changed

+3388
-524
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ jobs:
2626
# - run: npm ci
2727
- run: npm install --no-package-lock
2828

29+
- name: Check linting
30+
working-directory: ./client
31+
run: npm run lint
32+
2933
- name: Run client tests
3034
working-directory: ./client
3135
run: npm test
@@ -54,8 +58,6 @@ jobs:
5458
# - run: npm ci
5559
- run: npm install --no-package-lock
5660

57-
- run: npm run build
58-
5961
# TODO: Add --provenance once the repo is public
6062
- run: npm run publish-all
6163
env:

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,22 @@ Example server configuration file:
9393
}
9494
```
9595

96+
You can also set the initial `transport` type, `serverUrl`, `serverCommand`, and `serverArgs` via query params, for example:
97+
98+
```
99+
http://localhost:6274/?transport=sse&serverUrl=http://localhost:8787/sse
100+
http://localhost:6274/?transport=streamable-http&serverUrl=http://localhost:8787/mcp
101+
http://localhost:6274/?transport=stdio&serverCommand=npx&serverArgs=arg1%20arg2
102+
```
103+
104+
You can also set initial config settings via query params, for example:
105+
106+
```
107+
http://localhost:6274/?MCP_SERVER_REQUEST_TIMEOUT=10000&MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS=false&MCP_PROXY_FULL_ADDRESS=http://10.1.1.22:5577
108+
```
109+
110+
Note that if both the query param and the corresponding localStorage item are set, the query param will take precedence.
111+
96112
### From this repository
97113

98114
If you're working on the inspector itself:

cli/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/inspector-cli",
3-
"version": "0.10.2",
3+
"version": "0.12.0",
44
"description": "CLI for the Model Context Protocol inspector",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -21,7 +21,7 @@
2121
},
2222
"devDependencies": {},
2323
"dependencies": {
24-
"@modelcontextprotocol/sdk": "^1.10.0",
24+
"@modelcontextprotocol/sdk": "^1.11.0",
2525
"commander": "^13.1.0",
2626
"spawn-rx": "^5.1.2"
2727
}

client/bin/client.js

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,34 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
99
const distPath = join(__dirname, "../dist");
1010

1111
const server = http.createServer((request, response) => {
12-
return handler(request, response, {
12+
const handlerOptions = {
1313
public: distPath,
1414
rewrites: [{ source: "/**", destination: "/index.html" }],
15-
});
15+
headers: [
16+
{
17+
// Ensure index.html is never cached
18+
source: "index.html",
19+
headers: [
20+
{
21+
key: "Cache-Control",
22+
value: "no-cache, no-store, max-age=0",
23+
},
24+
],
25+
},
26+
{
27+
// Allow long-term caching for hashed assets
28+
source: "assets/**",
29+
headers: [
30+
{
31+
key: "Cache-Control",
32+
value: "public, max-age=31536000, immutable",
33+
},
34+
],
35+
},
36+
],
37+
};
38+
39+
return handler(request, response, handlerOptions);
1640
});
1741

1842
const port = process.env.PORT || 6274;

client/jest.config.cjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = {
22
preset: "ts-jest",
3-
testEnvironment: "jsdom",
3+
testEnvironment: "jest-fixed-jsdom",
44
moduleNameMapper: {
55
"^@/(.*)$": "<rootDir>/src/$1",
66
"\\.css$": "<rootDir>/src/__mocks__/styleMock.js",

client/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/inspector-client",
3-
"version": "0.10.2",
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,7 +23,7 @@
2323
"test:watch": "jest --config jest.config.cjs --watch"
2424
},
2525
"dependencies": {
26-
"@modelcontextprotocol/sdk": "^1.10.0",
26+
"@modelcontextprotocol/sdk": "^1.11.0",
2727
"@radix-ui/react-checkbox": "^1.1.4",
2828
"@radix-ui/react-dialog": "^1.1.3",
2929
"@radix-ui/react-icons": "^1.3.0",

client/src/App.tsx

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,15 @@ import RootsTab from "./components/RootsTab";
5555
import SamplingTab, { PendingRequest } from "./components/SamplingTab";
5656
import Sidebar from "./components/Sidebar";
5757
import ToolsTab from "./components/ToolsTab";
58-
import { DEFAULT_INSPECTOR_CONFIG } from "./lib/constants";
5958
import { InspectorConfig } from "./lib/configurationTypes";
60-
import { getMCPProxyAddress } from "./utils/configUtils";
59+
import {
60+
getMCPProxyAddress,
61+
getInitialSseUrl,
62+
getInitialTransportType,
63+
getInitialCommand,
64+
getInitialArgs,
65+
initializeInspectorConfig,
66+
} from "./utils/configUtils";
6167

6268
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
6369

@@ -77,26 +83,13 @@ const App = () => {
7783
prompts: null,
7884
tools: null,
7985
});
80-
const [command, setCommand] = useState<string>(() => {
81-
return localStorage.getItem("lastCommand") || "mcp-server-everything";
82-
});
83-
const [args, setArgs] = useState<string>(() => {
84-
return localStorage.getItem("lastArgs") || "";
85-
});
86+
const [command, setCommand] = useState<string>(getInitialCommand);
87+
const [args, setArgs] = useState<string>(getInitialArgs);
8688

87-
const [sseUrl, setSseUrl] = useState<string>(() => {
88-
return localStorage.getItem("lastSseUrl") || "http://localhost:3001/sse";
89-
});
89+
const [sseUrl, setSseUrl] = useState<string>(getInitialSseUrl);
9090
const [transportType, setTransportType] = useState<
9191
"stdio" | "sse" | "streamable-http"
92-
>(() => {
93-
return (
94-
(localStorage.getItem("lastTransportType") as
95-
| "stdio"
96-
| "sse"
97-
| "streamable-http") || "stdio"
98-
);
99-
});
92+
>(getInitialTransportType);
10093
const [logLevel, setLogLevel] = useState<LoggingLevel>("debug");
10194
const [notifications, setNotifications] = useState<ServerNotification[]>([]);
10295
const [stdErrNotifications, setStdErrNotifications] = useState<
@@ -105,27 +98,9 @@ const App = () => {
10598
const [roots, setRoots] = useState<Root[]>([]);
10699
const [env, setEnv] = useState<Record<string, string>>({});
107100

108-
const [config, setConfig] = useState<InspectorConfig>(() => {
109-
const savedConfig = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
110-
if (savedConfig) {
111-
// merge default config with saved config
112-
const mergedConfig = {
113-
...DEFAULT_INSPECTOR_CONFIG,
114-
...JSON.parse(savedConfig),
115-
} as InspectorConfig;
116-
117-
// update description of keys to match the new description (in case of any updates to the default config description)
118-
Object.entries(mergedConfig).forEach(([key, value]) => {
119-
mergedConfig[key as keyof InspectorConfig] = {
120-
...value,
121-
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
122-
};
123-
});
124-
125-
return mergedConfig;
126-
}
127-
return DEFAULT_INSPECTOR_CONFIG;
128-
});
101+
const [config, setConfig] = useState<InspectorConfig>(() =>
102+
initializeInspectorConfig(CONFIG_LOCAL_STORAGE_KEY),
103+
);
129104
const [bearerToken, setBearerToken] = useState<string>(() => {
130105
return localStorage.getItem("lastBearerToken") || "";
131106
});
@@ -683,11 +658,24 @@ const App = () => {
683658
{!serverCapabilities?.resources &&
684659
!serverCapabilities?.prompts &&
685660
!serverCapabilities?.tools ? (
686-
<div className="flex items-center justify-center p-4">
687-
<p className="text-lg text-gray-500">
688-
The connected server does not support any MCP capabilities
689-
</p>
690-
</div>
661+
<>
662+
<div className="flex items-center justify-center p-4">
663+
<p className="text-lg text-gray-500">
664+
The connected server does not support any MCP
665+
capabilities
666+
</p>
667+
</div>
668+
<PingTab
669+
onPingClick={() => {
670+
void sendMCPRequest(
671+
{
672+
method: "ping" as const,
673+
},
674+
EmptyResultSchema,
675+
);
676+
}}
677+
/>
678+
</>
691679
) : (
692680
<>
693681
<ResourcesTab
@@ -755,6 +743,7 @@ const App = () => {
755743
setSelectedPrompt={(prompt) => {
756744
clearError("prompts");
757745
setSelectedPrompt(prompt);
746+
setPromptContent("");
758747
}}
759748
handleCompletion={handleCompletion}
760749
completionsSupported={completionsSupported}

client/src/components/DynamicJsonForm.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,12 @@ const DynamicJsonForm = ({
250250
<div className="space-y-4">
251251
<div className="flex justify-end space-x-2">
252252
{isJsonMode && (
253-
<Button variant="outline" size="sm" onClick={formatJson}>
253+
<Button
254+
type="button"
255+
variant="outline"
256+
size="sm"
257+
onClick={formatJson}
258+
>
254259
Format JSON
255260
</Button>
256261
)}

client/src/components/JsonView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { JsonValue } from "@/utils/jsonUtils";
33
import clsx from "clsx";
44
import { Copy, CheckCheck } from "lucide-react";
55
import { Button } from "@/components/ui/button";
6-
import { useToast } from "@/hooks/use-toast";
6+
import { useToast } from "@/lib/hooks/useToast";
77
import { getDataType, tryParseJson } from "@/utils/jsonUtils";
88

99
interface JsonViewProps {

client/src/components/OAuthCallback.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useEffect, useRef } from "react";
22
import { InspectorOAuthClientProvider } from "../lib/auth";
33
import { SESSION_KEYS } from "../lib/constants";
44
import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
5-
import { useToast } from "@/hooks/use-toast.ts";
5+
import { useToast } from "@/lib/hooks/useToast";
66
import {
77
generateOAuthErrorDescription,
88
parseOAuthCallbackParams,

0 commit comments

Comments
 (0)