Compare commits

..

32 Commits

Author SHA1 Message Date
Cliff Hall
24e8861a88 Merge pull request #383 from olaservo/bump-to-version-0-12-0
Bump version to 0.12.0
2025-05-08 16:41:44 -04:00
Ola Hungerford
2731b5f7fa Update package-lock.json 2025-05-08 13:31:20 -07:00
Ola Hungerford
7083c7c9f2 Update package-lock.json 2025-05-08 13:30:52 -07:00
Cliff Hall
6223839251 Merge branch 'main' into bump-to-version-0-12-0 2025-05-08 16:00:17 -04:00
Cliff Hall
e33a6b806d Merge pull request #370 from santthosh/main
Fix to the Authorization header bug for Streamable-HTTP
2025-05-08 13:03:26 -04:00
Cliff Hall
fe9ab40994 Merge branch 'main' into main 2025-05-08 12:39:48 -04:00
Ola Hungerford
f7b936e102 Bump version to 0.12.0 2025-05-07 05:28:24 -07:00
Ola Hungerford
3e41520688 Merge pull request #371 from kentcdodds/patch-2
feat(client): Add PingTab when no server capabilities
2025-05-06 21:04:47 -07:00
Santthosh
a57e707a0b Merge branch 'main' into main 2025-05-06 09:51:45 -07:00
Cliff Hall
73a8e2dee6 Merge pull request #377 from kavinkumar807/Streamable-HTTP-invalid-protocol-version
fix: sdk version upgrade
2025-05-05 17:40:20 -04:00
Cliff Hall
f05c27f6ab Merge pull request #372 from olaservo/add-npm-clean-script
Add npm clean script to simplify resetting dependencies
2025-05-05 15:23:15 -04:00
Cliff Hall
2609996ce6 Merge branch 'main' into add-npm-clean-script 2025-05-05 15:15:34 -04:00
kavinkumarbaskar
b00b271d65 fix: upgrade package json in cli, client, and server 2025-05-06 00:16:06 +05:30
kavinkumarbaskar
7a1fb0cfd9 fix: sdk version upgrade 2025-05-05 23:00:26 +05:30
Kent C. Dodds
63cb034943 chore(format): Format App.tsx 2025-05-05 11:20:55 -06:00
Kent C. Dodds
04e24916b1 Merge branch 'main' into patch-2 2025-05-03 22:06:25 -06:00
Ola Hungerford
c9d2f0761e Don't install rimraf 2025-05-03 20:01:33 -07:00
Ola Hungerford
f19b382e72 Merge pull request #366 from cliffhall/consolidate-hooks
Consolidate hooks
2025-05-03 15:39:31 -07:00
Santthosh
9998298dfe Merge branch 'modelcontextprotocol:main' into main 2025-05-02 18:06:34 -07:00
Santthosh
5393f2e04c Merge pull request #1 from cliffhall/fix-auth-header-streamable
Fix transport options creation
2025-05-02 18:06:21 -07:00
cliffhall
f9cbfbe822 Create the appropriate TransportOptions object for the selected transport
* In useConnection.ts

  - In the case for "stdio", let the transportOptions be the same as "sse"
 because it will use that transport to the proxy regardless
2025-05-02 17:50:00 -04:00
cliffhall
b7ec3829d4 Use transport-specific options 2025-05-02 17:35:33 -04:00
Ola Hungerford
8b38d6b18f Check in latest package-lock.json 2025-05-02 08:19:40 -07:00
Ola Hungerford
ae87292d7c Update commands to include all build directories and remove unnecessary servers/node_modules 2025-05-02 08:17:45 -07:00
Cliff Hall
3b090d02e4 Merge pull request #367 from cliffhall/cache-bust-inspector-client
Fix the inspector caching problem
2025-05-01 11:49:20 -04:00
Ola Hungerford
358f276b9b Check in package-lock.json 2025-05-01 08:44:24 -07:00
Ola Hungerford
70016bf3b6 Merge branch 'main' into add-npm-clean-script 2025-05-01 08:29:26 -07:00
Ola Hungerford
4d98b4a8bd Add clean script and rimraf 2025-05-01 08:28:48 -07:00
Kent C. Dodds
5ad2c3c146 feat(client): Add PingTab when no server capabilities
The TypeScript SDK (and presumably others) quite possibly support at least pings out of the box so including the ping tab even if a server doesn't have capabilities seems to make sense.
2025-05-01 09:12:29 -06:00
Santthosh Selvadurai
dd6f5287ca Fix to the Authorization header bug for Streamable-HTTP
Reference issue [https://github.com/modelcontextprotocol/inspector/issues/369]
2025-04-30 22:21:59 -07:00
cliffhall
59cc89dbe9 Fix the inspector caching problem
* I've noticed that on a new version of the inspector, I have to go to the browser's devtools panel and clear site data then reload the page.
* The assets are hashed and immutable, so caching should be allowed for them
* The index.html file is the problem, because if cached, it will point to old assets, and therefore needs to have caching turned forf
* This PR adds appropriate headers to the index.html and assets that are served.
2025-04-30 17:31:58 -04:00
cliffhall
79a09f8316 Consolidate hooks
* Hooks are in multiple places in the codebase and some camelCase, some snake-case. This PR relocates them all to the lib/hooks folder and normalizes camelCase naming. Settled on src/client/lib/hooks for the location since most of them were already there.

  - Refactor/move useTheme.ts from client/src/lib to client/src/lib/hooks
  - Refactor/move useToast.ts from client/src/hooks/ to client/src/lib/hooks/useToast.ts
  - Removed client/src/hooks
2025-04-30 17:09:22 -04:00
17 changed files with 2668 additions and 358 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/inspector-cli",
"version": "0.11.0",
"version": "0.12.0",
"description": "CLI for the Model Context Protocol inspector",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -21,7 +21,7 @@
},
"devDependencies": {},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2",
"@modelcontextprotocol/sdk": "^1.11.0",
"commander": "^13.1.0",
"spawn-rx": "^5.1.2"
}

View File

@@ -9,10 +9,34 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
const distPath = join(__dirname, "../dist");
const server = http.createServer((request, response) => {
return handler(request, response, {
const handlerOptions = {
public: distPath,
rewrites: [{ source: "/**", destination: "/index.html" }],
});
headers: [
{
// Ensure index.html is never cached
source: "index.html",
headers: [
{
key: "Cache-Control",
value: "no-cache, no-store, max-age=0",
},
],
},
{
// Allow long-term caching for hashed assets
source: "assets/**",
headers: [
{
key: "Cache-Control",
value: "public, max-age=31536000, immutable",
},
],
},
],
};
return handler(request, response, handlerOptions);
});
const port = process.env.PORT || 6274;

View File

@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/inspector-client",
"version": "0.11.0",
"version": "0.12.0",
"description": "Client-side application for the Model Context Protocol inspector",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -23,7 +23,7 @@
"test:watch": "jest --config jest.config.cjs --watch"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2",
"@modelcontextprotocol/sdk": "^1.11.0",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.3",
"@radix-ui/react-icons": "^1.3.0",

View File

@@ -575,11 +575,24 @@ const App = () => {
{!serverCapabilities?.resources &&
!serverCapabilities?.prompts &&
!serverCapabilities?.tools ? (
<div className="flex items-center justify-center p-4">
<p className="text-lg text-gray-500">
The connected server does not support any MCP capabilities
</p>
</div>
<>
<div className="flex items-center justify-center p-4">
<p className="text-lg text-gray-500">
The connected server does not support any MCP
capabilities
</p>
</div>
<PingTab
onPingClick={() => {
void sendMCPRequest(
{
method: "ping" as const,
},
EmptyResultSchema,
);
}}
/>
</>
) : (
<>
<ResourcesTab

View File

@@ -3,7 +3,7 @@ import type { JsonValue } from "@/utils/jsonUtils";
import clsx from "clsx";
import { Copy, CheckCheck } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { useToast } from "@/lib/hooks/useToast";
import { getDataType, tryParseJson } from "@/utils/jsonUtils";
interface JsonViewProps {

View File

@@ -2,7 +2,7 @@ import { useEffect, useRef } from "react";
import { InspectorOAuthClientProvider } from "../lib/auth";
import { SESSION_KEYS } from "../lib/constants";
import { auth } from "@modelcontextprotocol/sdk/client/auth.js";
import { useToast } from "@/hooks/use-toast.ts";
import { useToast } from "@/lib/hooks/useToast";
import {
generateOAuthErrorDescription,
parseOAuthCallbackParams,

View File

@@ -7,7 +7,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js";
import { PendingRequest } from "./SamplingTab";
import DynamicJsonForm from "./DynamicJsonForm";
import { useToast } from "@/hooks/use-toast";
import { useToast } from "@/lib/hooks/useToast";
import { JsonSchemaType, JsonValue } from "@/utils/jsonUtils";
export type SamplingRequestProps = {

View File

@@ -29,7 +29,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js";
import { InspectorConfig } from "@/lib/configurationTypes";
import { ConnectionStatus } from "@/lib/constants";
import useTheme from "../lib/useTheme";
import useTheme from "../lib/hooks/useTheme";
import { version } from "../../../package.json";
import {
Tooltip,

View File

@@ -7,7 +7,7 @@ import { InspectorConfig } from "@/lib/configurationTypes";
import { TooltipProvider } from "@/components/ui/tooltip";
// Mock theme hook
jest.mock("../../lib/useTheme", () => ({
jest.mock("../../lib/hooks/useTheme", () => ({
__esModule: true,
default: () => ["light", jest.fn()],
}));

View File

@@ -1,4 +1,4 @@
import { useToast } from "@/hooks/use-toast";
import { useToast } from "@/lib/hooks/useToast";
import {
Toast,
ToastClose,

View File

@@ -37,7 +37,7 @@ jest.mock("@modelcontextprotocol/sdk/client/auth.js", () => ({
}));
// Mock the toast hook
jest.mock("@/hooks/use-toast", () => ({
jest.mock("@/lib/hooks/useToast", () => ({
useToast: () => ({
toast: jest.fn(),
}),

View File

@@ -2,8 +2,12 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import {
SSEClientTransport,
SseError,
SSEClientTransportOptions,
} from "@modelcontextprotocol/sdk/client/sse.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import {
StreamableHTTPClientTransport,
StreamableHTTPClientTransportOptions,
} from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import {
ClientNotification,
ClientRequest,
@@ -27,7 +31,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js";
import { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
import { useState } from "react";
import { useToast } from "@/hooks/use-toast";
import { useToast } from "@/lib/hooks/useToast";
import { z } from "zod";
import { ConnectionStatus } from "../constants";
import { Notification, StdErrNotificationSchema } from "../notificationTypes";
@@ -279,29 +283,6 @@ export function useConnection({
setConnectionStatus("error-connecting-to-proxy");
return;
}
let mcpProxyServerUrl;
switch (transportType) {
case "stdio":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/stdio`);
mcpProxyServerUrl.searchParams.append("command", command);
mcpProxyServerUrl.searchParams.append("args", args);
mcpProxyServerUrl.searchParams.append("env", JSON.stringify(env));
break;
case "sse":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`);
mcpProxyServerUrl.searchParams.append("url", sseUrl);
break;
case "streamable-http":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/mcp`);
mcpProxyServerUrl.searchParams.append("url", sseUrl);
break;
}
(mcpProxyServerUrl as URL).searchParams.append(
"transportType",
transportType,
);
try {
// Inject auth manually instead of using SSEClientTransport, because we're
@@ -320,21 +301,82 @@ export function useConnection({
}
// Create appropriate transport
const transportOptions = {
eventSourceInit: {
fetch: (
url: string | URL | globalThis.Request,
init: RequestInit | undefined,
) => fetch(url, { ...init, headers }),
},
requestInit: {
headers,
},
};
let transportOptions:
| StreamableHTTPClientTransportOptions
| SSEClientTransportOptions;
let mcpProxyServerUrl;
switch (transportType) {
case "stdio":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/stdio`);
mcpProxyServerUrl.searchParams.append("command", command);
mcpProxyServerUrl.searchParams.append("args", args);
mcpProxyServerUrl.searchParams.append("env", JSON.stringify(env));
transportOptions = {
authProvider: serverAuthProvider,
eventSourceInit: {
fetch: (
url: string | URL | globalThis.Request,
init: RequestInit | undefined,
) => fetch(url, { ...init, headers }),
},
requestInit: {
headers,
},
};
break;
case "sse":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/sse`);
mcpProxyServerUrl.searchParams.append("url", sseUrl);
transportOptions = {
authProvider: serverAuthProvider,
eventSourceInit: {
fetch: (
url: string | URL | globalThis.Request,
init: RequestInit | undefined,
) => fetch(url, { ...init, headers }),
},
requestInit: {
headers,
},
};
break;
case "streamable-http":
mcpProxyServerUrl = new URL(`${getMCPProxyAddress(config)}/mcp`);
mcpProxyServerUrl.searchParams.append("url", sseUrl);
transportOptions = {
authProvider: serverAuthProvider,
eventSourceInit: {
fetch: (
url: string | URL | globalThis.Request,
init: RequestInit | undefined,
) => fetch(url, { ...init, headers }),
},
requestInit: {
headers,
},
// TODO these should be configurable...
reconnectionOptions: {
maxReconnectionDelay: 30000,
initialReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 1.5,
maxRetries: 2,
},
};
break;
}
(mcpProxyServerUrl as URL).searchParams.append(
"transportType",
transportType,
);
const clientTransport =
transportType === "streamable-http"
? new StreamableHTTPClientTransport(mcpProxyServerUrl as URL, {
sessionId: undefined,
...transportOptions,
})
: new SSEClientTransport(mcpProxyServerUrl as URL, transportOptions);

2823
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/inspector",
"version": "0.11.0",
"version": "0.12.0",
"description": "Model Context Protocol inspector",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -26,6 +26,7 @@
"build-server": "cd server && npm run build",
"build-client": "cd client && npm run build",
"build-cli": "cd cli && npm run build",
"clean": "rimraf ./node_modules ./client/node_modules ./cli/node_modules ./build ./client/dist ./server/build ./cli/build ./package-lock.json && npm install",
"dev": "concurrently \"cd client && npm run dev\" \"cd server && npm run dev\"",
"dev:windows": "concurrently \"cd client && npm run dev\" \"cd server && npm run dev:windows\"",
"start": "node client/bin/start.js",
@@ -39,10 +40,10 @@
"publish-all": "npm publish --workspaces --access public && npm publish --access public"
},
"dependencies": {
"@modelcontextprotocol/inspector-cli": "^0.11.0",
"@modelcontextprotocol/inspector-client": "^0.11.0",
"@modelcontextprotocol/inspector-server": "^0.11.0",
"@modelcontextprotocol/sdk": "^1.10.2",
"@modelcontextprotocol/inspector-cli": "^0.12.0",
"@modelcontextprotocol/inspector-client": "^0.12.0",
"@modelcontextprotocol/inspector-server": "^0.12.0",
"@modelcontextprotocol/sdk": "^1.11.0",
"concurrently": "^9.0.1",
"shell-quote": "^1.8.2",
"spawn-rx": "^5.1.2",
@@ -55,6 +56,7 @@
"@types/shell-quote": "^1.7.5",
"jest-fixed-jsdom": "^0.0.9",
"prettier": "3.3.3",
"rimraf": "^6.0.1",
"typescript": "^5.4.2"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@modelcontextprotocol/inspector-server",
"version": "0.11.0",
"version": "0.12.0",
"description": "Server-side application for the Model Context Protocol inspector",
"license": "MIT",
"author": "Anthropic, PBC (https://anthropic.com)",
@@ -27,7 +27,7 @@
"typescript": "^5.6.2"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.10.2",
"@modelcontextprotocol/sdk": "^1.11.0",
"cors": "^2.8.5",
"express": "^5.1.0",
"ws": "^8.18.0",