Skip to content

Commit d567ff3

Browse files
Merge pull request #70 from modelcontextprotocol/ashwin/errorlog
show server stderr in inspector UI
2 parents 668448b + 2e4eedc commit d567ff3

File tree

9 files changed

+135
-25
lines changed

9 files changed

+135
-25
lines changed

.github/workflows/main.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ on:
44
- main
55

66
pull_request:
7+
release:
8+
types: [published]
79

810
jobs:
911
build:
@@ -21,3 +23,30 @@ jobs:
2123
# - run: npm ci
2224
- run: npm install --no-package-lock
2325
- run: npm run build
26+
27+
publish:
28+
runs-on: ubuntu-latest
29+
if: github.event_name == 'release'
30+
environment: release
31+
needs: build
32+
33+
permissions:
34+
contents: read
35+
id-token: write
36+
37+
steps:
38+
- uses: actions/checkout@v4
39+
- uses: actions/setup-node@v4
40+
with:
41+
node-version: 18
42+
cache: npm
43+
registry-url: "https://registry.npmjs.org"
44+
45+
# Working around https://github.com/npm/cli/issues/4828
46+
# - run: npm ci
47+
- run: npm install --no-package-lock
48+
49+
# TODO: Add --provenance once the repo is public
50+
- run: npm run publish-all
51+
env:
52+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

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.1.7",
3+
"version": "0.2.0",
44
"description": "Client-side application for the Model Context Protocol inspector",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -21,7 +21,7 @@
2121
"preview": "vite preview"
2222
},
2323
"dependencies": {
24-
"@modelcontextprotocol/sdk": "0.5.0",
24+
"@modelcontextprotocol/sdk": "0.7.0",
2525
"@radix-ui/react-icons": "^1.3.0",
2626
"@radix-ui/react-label": "^2.1.0",
2727
"@radix-ui/react-select": "^2.1.2",

client/src/App.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@ import {
1616
ListToolsResultSchema,
1717
ProgressNotificationSchema,
1818
ReadResourceResultSchema,
19+
Request,
1920
Resource,
2021
ResourceTemplate,
22+
Result,
2123
Root,
2224
ServerNotification,
2325
Tool,
2426
} from "@modelcontextprotocol/sdk/types.js";
2527
import { useCallback, useEffect, useRef, useState } from "react";
2628

29+
import {
30+
Notification,
31+
StdErrNotification,
32+
StdErrNotificationSchema
33+
} from "./lib/notificationTypes";
34+
2735
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
2836
import {
2937
Bell,
@@ -82,6 +90,9 @@ const App = () => {
8290
>([]);
8391
const [mcpClient, setMcpClient] = useState<Client | null>(null);
8492
const [notifications, setNotifications] = useState<ServerNotification[]>([]);
93+
const [stdErrNotifications, setStdErrNotifications] = useState<
94+
StdErrNotification[]
95+
>([]);
8596
const [roots, setRoots] = useState<Root[]>([]);
8697
const [env, setEnv] = useState<Record<string, string>>({});
8798

@@ -380,7 +391,7 @@ const App = () => {
380391

381392
const connectMcpServer = async () => {
382393
try {
383-
const client = new Client(
394+
const client = new Client<Request, Notification, Result>(
384395
{
385396
name: "mcp-inspector",
386397
version: "0.0.1",
@@ -408,8 +419,6 @@ const App = () => {
408419
}
409420

410421
const clientTransport = new SSEClientTransport(backendUrl);
411-
await client.connect(clientTransport);
412-
413422
client.setNotificationHandler(
414423
ProgressNotificationSchema,
415424
(notification) => {
@@ -420,6 +429,18 @@ const App = () => {
420429
},
421430
);
422431

432+
client.setNotificationHandler(
433+
StdErrNotificationSchema,
434+
(notification) => {
435+
setStdErrNotifications((prevErrorNotifications) => [
436+
...prevErrorNotifications,
437+
notification,
438+
]);
439+
},
440+
);
441+
442+
await client.connect(clientTransport);
443+
423444
client.setRequestHandler(CreateMessageRequestSchema, (request) => {
424445
return new Promise<CreateMessageResult>((resolve, reject) => {
425446
setPendingSampleRequests((prev) => [
@@ -456,6 +477,7 @@ const App = () => {
456477
env={env}
457478
setEnv={setEnv}
458479
onConnect={connectMcpServer}
480+
stdErrNotifications={stdErrNotifications}
459481
/>
460482
<div className="flex-1 flex flex-col overflow-hidden">
461483
<div className="flex-1 overflow-auto">

client/src/components/Sidebar.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
SelectTrigger,
1111
SelectValue,
1212
} from "@/components/ui/select";
13+
import { StdErrNotification } from "@/lib/notificationTypes";
1314

1415
interface SidebarProps {
1516
connectionStatus: "disconnected" | "connected" | "error";
@@ -24,6 +25,7 @@ interface SidebarProps {
2425
env: Record<string, string>;
2526
setEnv: (env: Record<string, string>) => void;
2627
onConnect: () => void;
28+
stdErrNotifications: StdErrNotification[];
2729
}
2830

2931
const Sidebar = ({
@@ -39,6 +41,7 @@ const Sidebar = ({
3941
env,
4042
setEnv,
4143
onConnect,
44+
stdErrNotifications,
4245
}: SidebarProps) => {
4346
const [showEnvVars, setShowEnvVars] = useState(false);
4447

@@ -187,6 +190,25 @@ const Sidebar = ({
187190
: "Disconnected"}
188191
</span>
189192
</div>
193+
{stdErrNotifications.length > 0 && (
194+
<>
195+
<div className="mt-4 border-t border-gray-200 pt-4">
196+
<h3 className="text-sm font-medium">
197+
Error output from MCP server
198+
</h3>
199+
<div className="mt-2 max-h-80 overflow-y-auto">
200+
{stdErrNotifications.map((notification, index) => (
201+
<div
202+
key={index}
203+
className="text-sm text-red-500 font-mono py-2 border-b border-gray-200 last:border-b-0"
204+
>
205+
{notification.params.content}
206+
</div>
207+
))}
208+
</div>
209+
</div>
210+
</>
211+
)}
190212
</div>
191213
</div>
192214
</div>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
NotificationSchema as BaseNotificationSchema,
3+
ClientNotificationSchema,
4+
} from "@modelcontextprotocol/sdk/types.js";
5+
import { z } from "zod";
6+
7+
export const StdErrNotificationSchema = BaseNotificationSchema.extend({
8+
method: z.literal("notifications/stderr"),
9+
params: z.object({
10+
content: z.string(),
11+
}),
12+
});
13+
14+
export const NotificationSchema = ClientNotificationSchema.or(
15+
StdErrNotificationSchema,
16+
);
17+
18+
export type StdErrNotification = z.infer<typeof StdErrNotificationSchema>;
19+
export type Notification = z.infer<typeof NotificationSchema>;

package-lock.json

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

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@modelcontextprotocol/inspector",
3-
"version": "0.1.7",
3+
"version": "0.2.0",
44
"description": "Model Context Protocol inspector",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -29,11 +29,12 @@
2929
"start-client": "cd client && npm run preview",
3030
"start": "./bin/cli.js",
3131
"prepare": "npm run build",
32-
"prettier-fix": "prettier --write ."
32+
"prettier-fix": "prettier --write .",
33+
"publish-all": "npm publish --workspaces --access public && npm publish --access public"
3334
},
3435
"dependencies": {
35-
"@modelcontextprotocol/inspector-client": "0.1.0",
36-
"@modelcontextprotocol/inspector-server": "0.1.0",
36+
"@modelcontextprotocol/inspector-client": "0.2.0",
37+
"@modelcontextprotocol/inspector-server": "0.2.0",
3738
"concurrently": "^9.0.1"
3839
},
3940
"devDependencies": {

server/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-server",
3-
"version": "0.1.7",
3+
"version": "0.2.0",
44
"description": "Server-side application for the Model Context Protocol inspector",
55
"license": "MIT",
66
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -27,7 +27,7 @@
2727
"typescript": "^5.6.2"
2828
},
2929
"dependencies": {
30-
"@modelcontextprotocol/sdk": "0.5.0",
30+
"@modelcontextprotocol/sdk": "0.7.0",
3131
"cors": "^2.8.5",
3232
"eventsource": "^2.0.2",
3333
"express": "^4.21.0",

server/src/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env node
22

3-
import { parseArgs } from "node:util";
43
import cors from "cors";
54
import EventSource from "eventsource";
5+
import { parseArgs } from "node:util";
66

77
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
88
import {
@@ -42,7 +42,12 @@ const createTransport = async (query: express.Request["query"]) => {
4242
console.log(
4343
`Stdio transport: command=${command}, args=${args}, env=${JSON.stringify(env)}`,
4444
);
45-
const transport = new StdioClientTransport({ command, args, env });
45+
const transport = new StdioClientTransport({
46+
command,
47+
args,
48+
env,
49+
stderr: "pipe",
50+
});
4651
await transport.start();
4752
console.log("Spawned stdio transport");
4853
return transport;
@@ -75,6 +80,18 @@ app.get("/sse", async (req, res) => {
7580

7681
await webAppTransport.start();
7782

83+
if (backingServerTransport instanceof StdioClientTransport) {
84+
backingServerTransport.stderr!.on("data", (chunk) => {
85+
webAppTransport.send({
86+
jsonrpc: "2.0",
87+
method: "notifications/stderr",
88+
params: {
89+
content: chunk.toString(),
90+
},
91+
});
92+
});
93+
}
94+
7895
mcpProxy({
7996
transportToClient: webAppTransport,
8097
transportToServer: backingServerTransport,
@@ -121,4 +138,4 @@ app.get("/config", (req, res) => {
121138
});
122139

123140
const PORT = process.env.PORT || 3000;
124-
app.listen(PORT, () => {});
141+
app.listen(PORT, () => { });

0 commit comments

Comments
 (0)