Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
576ff0043a | ||
|
|
18dc4d0a99 | ||
|
|
f04b161411 | ||
|
|
bd6a63603a | ||
|
|
b845444fab | ||
|
|
ace94c4d37 | ||
|
|
50640bc9cc | ||
|
|
cc17ba8d56 | ||
|
|
764f02310d | ||
|
|
945299181d | ||
|
|
79344bd495 | ||
|
|
295ccac27e | ||
|
|
f3f424f21e | ||
|
|
6b6eeb8dcd |
@@ -26,6 +26,8 @@ The inspector runs both a client UI (default port 5173) and an MCP proxy server
|
|||||||
CLIENT_PORT=8080 SERVER_PORT=9000 npx @modelcontextprotocol/inspector build/index.js
|
CLIENT_PORT=8080 SERVER_PORT=9000 npx @modelcontextprotocol/inspector build/index.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For more details on ways to use the inspector, see the [Inspector section of the MCP docs site](https://modelcontextprotocol.io/docs/tools/inspector).
|
||||||
|
|
||||||
### From this repository
|
### From this repository
|
||||||
|
|
||||||
If you're working on the inspector itself:
|
If you're working on the inspector itself:
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ async function main() {
|
|||||||
[
|
[
|
||||||
inspectorServerPath,
|
inspectorServerPath,
|
||||||
...(command ? [`--env`, command] : []),
|
...(command ? [`--env`, command] : []),
|
||||||
...(mcpServerArgs ? ["--args", mcpServerArgs.join(" ")] : []),
|
...(mcpServerArgs ? [`--args=${mcpServerArgs.join(" ")}`] : []),
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
env: { ...process.env, PORT: SERVER_PORT },
|
env: { ...process.env, PORT: SERVER_PORT },
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector-client",
|
"name": "@modelcontextprotocol/inspector-client",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"description": "Client-side application for the Model Context Protocol inspector",
|
"description": "Client-side application for the Model Context Protocol inspector",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.0.1",
|
"@modelcontextprotocol/sdk": "^1.0.3",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@radix-ui/react-select": "^2.1.2",
|
"@radix-ui/react-select": "^2.1.2",
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ const DEFAULT_REQUEST_TIMEOUT_MSEC = 10000;
|
|||||||
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const PROXY_PORT = params.get("proxyPort") ?? "3000";
|
const PROXY_PORT = params.get("proxyPort") ?? "3000";
|
||||||
|
const REQUEST_TIMEOUT = parseInt(params.get("timeout") ?? "") || DEFAULT_REQUEST_TIMEOUT_MSEC;
|
||||||
const PROXY_SERVER_URL = `http://localhost:${PROXY_PORT}`;
|
const PROXY_SERVER_URL = `http://localhost:${PROXY_PORT}`;
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
@@ -243,7 +244,7 @@ const App = () => {
|
|||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
abortController.abort("Request timed out");
|
abortController.abort("Request timed out");
|
||||||
}, DEFAULT_REQUEST_TIMEOUT_MSEC);
|
}, REQUEST_TIMEOUT);
|
||||||
|
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
@@ -525,10 +526,18 @@ const App = () => {
|
|||||||
clearError("resources");
|
clearError("resources");
|
||||||
listResources();
|
listResources();
|
||||||
}}
|
}}
|
||||||
|
clearResources={() => {
|
||||||
|
setResources([]);
|
||||||
|
setNextResourceCursor(undefined);
|
||||||
|
}}
|
||||||
listResourceTemplates={() => {
|
listResourceTemplates={() => {
|
||||||
clearError("resources");
|
clearError("resources");
|
||||||
listResourceTemplates();
|
listResourceTemplates();
|
||||||
}}
|
}}
|
||||||
|
clearResourceTemplates={() => {
|
||||||
|
setResourceTemplates([]);
|
||||||
|
setNextResourceTemplateCursor(undefined);
|
||||||
|
}}
|
||||||
readResource={(uri) => {
|
readResource={(uri) => {
|
||||||
clearError("resources");
|
clearError("resources");
|
||||||
readResource(uri);
|
readResource(uri);
|
||||||
@@ -549,6 +558,10 @@ const App = () => {
|
|||||||
clearError("prompts");
|
clearError("prompts");
|
||||||
listPrompts();
|
listPrompts();
|
||||||
}}
|
}}
|
||||||
|
clearPrompts={() => {
|
||||||
|
setPrompts([]);
|
||||||
|
setNextPromptCursor(undefined);
|
||||||
|
}}
|
||||||
getPrompt={(name, args) => {
|
getPrompt={(name, args) => {
|
||||||
clearError("prompts");
|
clearError("prompts");
|
||||||
getPrompt(name, args);
|
getPrompt(name, args);
|
||||||
@@ -568,6 +581,10 @@ const App = () => {
|
|||||||
clearError("tools");
|
clearError("tools");
|
||||||
listTools();
|
listTools();
|
||||||
}}
|
}}
|
||||||
|
clearTools={() => {
|
||||||
|
setTools([]);
|
||||||
|
setNextToolCursor(undefined);
|
||||||
|
}}
|
||||||
callTool={(name, params) => {
|
callTool={(name, params) => {
|
||||||
clearError("tools");
|
clearError("tools");
|
||||||
callTool(name, params);
|
callTool(name, params);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Button } from "./ui/button";
|
|||||||
type ListPaneProps<T> = {
|
type ListPaneProps<T> = {
|
||||||
items: T[];
|
items: T[];
|
||||||
listItems: () => void;
|
listItems: () => void;
|
||||||
|
clearItems: () => void;
|
||||||
setSelectedItem: (item: T) => void;
|
setSelectedItem: (item: T) => void;
|
||||||
renderItem: (item: T) => React.ReactNode;
|
renderItem: (item: T) => React.ReactNode;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -13,6 +14,7 @@ type ListPaneProps<T> = {
|
|||||||
const ListPane = <T extends object>({
|
const ListPane = <T extends object>({
|
||||||
items,
|
items,
|
||||||
listItems,
|
listItems,
|
||||||
|
clearItems,
|
||||||
setSelectedItem,
|
setSelectedItem,
|
||||||
renderItem,
|
renderItem,
|
||||||
title,
|
title,
|
||||||
@@ -32,6 +34,14 @@ const ListPane = <T extends object>({
|
|||||||
>
|
>
|
||||||
{buttonText}
|
{buttonText}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className="w-full mb-4"
|
||||||
|
onClick={clearItems}
|
||||||
|
disabled={items.length === 0}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
<div className="space-y-2 overflow-y-auto max-h-96">
|
<div className="space-y-2 overflow-y-auto max-h-96">
|
||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export type Prompt = {
|
|||||||
const PromptsTab = ({
|
const PromptsTab = ({
|
||||||
prompts,
|
prompts,
|
||||||
listPrompts,
|
listPrompts,
|
||||||
|
clearPrompts,
|
||||||
getPrompt,
|
getPrompt,
|
||||||
selectedPrompt,
|
selectedPrompt,
|
||||||
setSelectedPrompt,
|
setSelectedPrompt,
|
||||||
@@ -31,6 +32,7 @@ const PromptsTab = ({
|
|||||||
}: {
|
}: {
|
||||||
prompts: Prompt[];
|
prompts: Prompt[];
|
||||||
listPrompts: () => void;
|
listPrompts: () => void;
|
||||||
|
clearPrompts: () => void;
|
||||||
getPrompt: (name: string, args: Record<string, string>) => void;
|
getPrompt: (name: string, args: Record<string, string>) => void;
|
||||||
selectedPrompt: Prompt | null;
|
selectedPrompt: Prompt | null;
|
||||||
setSelectedPrompt: (prompt: Prompt) => void;
|
setSelectedPrompt: (prompt: Prompt) => void;
|
||||||
@@ -55,6 +57,7 @@ const PromptsTab = ({
|
|||||||
<ListPane
|
<ListPane
|
||||||
items={prompts}
|
items={prompts}
|
||||||
listItems={listPrompts}
|
listItems={listPrompts}
|
||||||
|
clearItems={clearPrompts}
|
||||||
setSelectedItem={(prompt) => {
|
setSelectedItem={(prompt) => {
|
||||||
setSelectedPrompt(prompt);
|
setSelectedPrompt(prompt);
|
||||||
setPromptArgs({});
|
setPromptArgs({});
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ const ResourcesTab = ({
|
|||||||
resources,
|
resources,
|
||||||
resourceTemplates,
|
resourceTemplates,
|
||||||
listResources,
|
listResources,
|
||||||
|
clearResources,
|
||||||
listResourceTemplates,
|
listResourceTemplates,
|
||||||
|
clearResourceTemplates,
|
||||||
readResource,
|
readResource,
|
||||||
selectedResource,
|
selectedResource,
|
||||||
setSelectedResource,
|
setSelectedResource,
|
||||||
@@ -28,7 +30,9 @@ const ResourcesTab = ({
|
|||||||
resources: Resource[];
|
resources: Resource[];
|
||||||
resourceTemplates: ResourceTemplate[];
|
resourceTemplates: ResourceTemplate[];
|
||||||
listResources: () => void;
|
listResources: () => void;
|
||||||
|
clearResources: () => void;
|
||||||
listResourceTemplates: () => void;
|
listResourceTemplates: () => void;
|
||||||
|
clearResourceTemplates: () => void;
|
||||||
readResource: (uri: string) => void;
|
readResource: (uri: string) => void;
|
||||||
selectedResource: Resource | null;
|
selectedResource: Resource | null;
|
||||||
setSelectedResource: (resource: Resource | null) => void;
|
setSelectedResource: (resource: Resource | null) => void;
|
||||||
@@ -68,6 +72,7 @@ const ResourcesTab = ({
|
|||||||
<ListPane
|
<ListPane
|
||||||
items={resources}
|
items={resources}
|
||||||
listItems={listResources}
|
listItems={listResources}
|
||||||
|
clearItems={clearResources}
|
||||||
setSelectedItem={(resource) => {
|
setSelectedItem={(resource) => {
|
||||||
setSelectedResource(resource);
|
setSelectedResource(resource);
|
||||||
readResource(resource.uri);
|
readResource(resource.uri);
|
||||||
@@ -90,6 +95,7 @@ const ResourcesTab = ({
|
|||||||
<ListPane
|
<ListPane
|
||||||
items={resourceTemplates}
|
items={resourceTemplates}
|
||||||
listItems={listResourceTemplates}
|
listItems={listResourceTemplates}
|
||||||
|
clearItems={clearResourceTemplates}
|
||||||
setSelectedItem={(template) => {
|
setSelectedItem={(template) => {
|
||||||
setSelectedTemplate(template);
|
setSelectedTemplate(template);
|
||||||
setSelectedResource(null);
|
setSelectedResource(null);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js"
|
|||||||
const ToolsTab = ({
|
const ToolsTab = ({
|
||||||
tools,
|
tools,
|
||||||
listTools,
|
listTools,
|
||||||
|
clearTools,
|
||||||
callTool,
|
callTool,
|
||||||
selectedTool,
|
selectedTool,
|
||||||
setSelectedTool,
|
setSelectedTool,
|
||||||
@@ -27,6 +28,7 @@ const ToolsTab = ({
|
|||||||
}: {
|
}: {
|
||||||
tools: Tool[];
|
tools: Tool[];
|
||||||
listTools: () => void;
|
listTools: () => void;
|
||||||
|
clearTools: () => void;
|
||||||
callTool: (name: string, params: Record<string, unknown>) => void;
|
callTool: (name: string, params: Record<string, unknown>) => void;
|
||||||
selectedTool: Tool | null;
|
selectedTool: Tool | null;
|
||||||
setSelectedTool: (tool: Tool) => void;
|
setSelectedTool: (tool: Tool) => void;
|
||||||
@@ -50,7 +52,7 @@ const ToolsTab = ({
|
|||||||
</pre>
|
</pre>
|
||||||
<h4 className="font-semibold mb-2">Errors:</h4>
|
<h4 className="font-semibold mb-2">Errors:</h4>
|
||||||
{parsedResult.error.errors.map((error, idx) => (
|
{parsedResult.error.errors.map((error, idx) => (
|
||||||
<pre
|
<pre
|
||||||
key={idx}
|
key={idx}
|
||||||
className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64"
|
className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64"
|
||||||
>
|
>
|
||||||
@@ -108,6 +110,7 @@ const ToolsTab = ({
|
|||||||
<ListPane
|
<ListPane
|
||||||
items={tools}
|
items={tools}
|
||||||
listItems={listTools}
|
listItems={listTools}
|
||||||
|
clearItems={clearTools}
|
||||||
setSelectedItem={setSelectedTool}
|
setSelectedItem={setSelectedTool}
|
||||||
renderItem={(tool) => (
|
renderItem={(tool) => (
|
||||||
<>
|
<>
|
||||||
|
|||||||
23
package-lock.json
generated
23
package-lock.json
generated
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"client",
|
"client",
|
||||||
"server"
|
"server"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/inspector-client": "0.2.4",
|
"@modelcontextprotocol/inspector-client": "0.3.0",
|
||||||
"@modelcontextprotocol/inspector-server": "0.2.4",
|
"@modelcontextprotocol/inspector-server": "0.3.0",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"spawn-rx": "^5.1.0",
|
"spawn-rx": "^5.1.0",
|
||||||
"ts-node": "^10.9.2"
|
"ts-node": "^10.9.2"
|
||||||
@@ -29,10 +29,10 @@
|
|||||||
},
|
},
|
||||||
"client": {
|
"client": {
|
||||||
"name": "@modelcontextprotocol/inspector-client",
|
"name": "@modelcontextprotocol/inspector-client",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.0.1",
|
"@modelcontextprotocol/sdk": "^1.0.3",
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@radix-ui/react-select": "^2.1.2",
|
"@radix-ui/react-select": "^2.1.2",
|
||||||
@@ -1203,10 +1203,9 @@
|
|||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
"node_modules/@modelcontextprotocol/sdk": {
|
"node_modules/@modelcontextprotocol/sdk": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.3.tgz",
|
||||||
"integrity": "sha512-slLdFaxQJ9AlRg+hw28iiTtGvShAOgOKXcD0F91nUcRYiOMuS9ZBYjcdNZRXW9G5JQ511GRTdUy1zQVZDpJ+4w==",
|
"integrity": "sha512-2as3cX/VJ0YBHGmdv3GFyTpoM8q2gqE98zh3Vf1NwnsSY0h3mvoO07MUzfygCKkWsFjcZm4otIiqD6Xh7kiSBQ==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"content-type": "^1.0.5",
|
"content-type": "^1.0.5",
|
||||||
"raw-body": "^3.0.0",
|
"raw-body": "^3.0.0",
|
||||||
@@ -6926,10 +6925,10 @@
|
|||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"name": "@modelcontextprotocol/inspector-server",
|
"name": "@modelcontextprotocol/inspector-server",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.0.1",
|
"@modelcontextprotocol/sdk": "^1.0.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"eventsource": "^2.0.2",
|
"eventsource": "^2.0.2",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"description": "Model Context Protocol inspector",
|
"description": "Model Context Protocol inspector",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
"publish-all": "npm publish --workspaces --access public && npm publish --access public"
|
"publish-all": "npm publish --workspaces --access public && npm publish --access public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/inspector-client": "0.2.4",
|
"@modelcontextprotocol/inspector-client": "0.3.0",
|
||||||
"@modelcontextprotocol/inspector-server": "0.2.4",
|
"@modelcontextprotocol/inspector-server": "0.3.0",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"spawn-rx": "^5.1.0",
|
"spawn-rx": "^5.1.0",
|
||||||
"ts-node": "^10.9.2"
|
"ts-node": "^10.9.2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector-server",
|
"name": "@modelcontextprotocol/inspector-server",
|
||||||
"version": "0.2.4",
|
"version": "0.3.0",
|
||||||
"description": "Server-side application for the Model Context Protocol inspector",
|
"description": "Server-side application for the Model Context Protocol inspector",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Anthropic, PBC (https://anthropic.com)",
|
"author": "Anthropic, PBC (https://anthropic.com)",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"typescript": "^5.6.2"
|
"typescript": "^5.6.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.0.1",
|
"@modelcontextprotocol/sdk": "^1.0.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"eventsource": "^2.0.2",
|
"eventsource": "^2.0.2",
|
||||||
"express": "^4.21.0",
|
"express": "^4.21.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user