Merge branch 'main' into fix_readme_missing_character
This commit is contained in:
@@ -40,7 +40,7 @@ For more details on ways to use the inspector, see the [Inspector section of the
|
|||||||
|
|
||||||
### Authentication
|
### Authentication
|
||||||
|
|
||||||
The inspector supports bearer token authentication for SSE connections. Enter your token in the UI when connecting to an MCP server, and it will be sent in the Authorization header.
|
The inspector supports bearer token authentication for SSE connections. Enter your token in the UI when connecting to an MCP server, and it will be sent in the Authorization header. You can override the header name using the input field in the sidebar.
|
||||||
|
|
||||||
### Security Considerations
|
### Security Considerations
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector-client",
|
"name": "@modelcontextprotocol/inspector-client",
|
||||||
"version": "0.8.2",
|
"version": "0.9.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)",
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ const App = () => {
|
|||||||
return localStorage.getItem("lastBearerToken") || "";
|
return localStorage.getItem("lastBearerToken") || "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [headerName, setHeaderName] = useState<string>(() => {
|
||||||
|
return localStorage.getItem("lastHeaderName") || "";
|
||||||
|
});
|
||||||
|
|
||||||
const [pendingSampleRequests, setPendingSampleRequests] = useState<
|
const [pendingSampleRequests, setPendingSampleRequests] = useState<
|
||||||
Array<
|
Array<
|
||||||
PendingRequest & {
|
PendingRequest & {
|
||||||
@@ -169,6 +173,7 @@ const App = () => {
|
|||||||
sseUrl,
|
sseUrl,
|
||||||
env,
|
env,
|
||||||
bearerToken,
|
bearerToken,
|
||||||
|
headerName,
|
||||||
config,
|
config,
|
||||||
onNotification: (notification) => {
|
onNotification: (notification) => {
|
||||||
setNotifications((prev) => [...prev, notification as ServerNotification]);
|
setNotifications((prev) => [...prev, notification as ServerNotification]);
|
||||||
@@ -208,6 +213,10 @@ const App = () => {
|
|||||||
localStorage.setItem("lastBearerToken", bearerToken);
|
localStorage.setItem("lastBearerToken", bearerToken);
|
||||||
}, [bearerToken]);
|
}, [bearerToken]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem("lastHeaderName", headerName);
|
||||||
|
}, [headerName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
|
localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
|
||||||
}, [config]);
|
}, [config]);
|
||||||
@@ -467,6 +476,10 @@ const App = () => {
|
|||||||
setLogLevel(level);
|
setLogLevel(level);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearStdErrNotifications = () => {
|
||||||
|
setStdErrNotifications([]);
|
||||||
|
};
|
||||||
|
|
||||||
if (window.location.pathname === "/oauth/callback") {
|
if (window.location.pathname === "/oauth/callback") {
|
||||||
const OAuthCallback = React.lazy(
|
const OAuthCallback = React.lazy(
|
||||||
() => import("./components/OAuthCallback"),
|
() => import("./components/OAuthCallback"),
|
||||||
@@ -496,12 +509,15 @@ const App = () => {
|
|||||||
setConfig={setConfig}
|
setConfig={setConfig}
|
||||||
bearerToken={bearerToken}
|
bearerToken={bearerToken}
|
||||||
setBearerToken={setBearerToken}
|
setBearerToken={setBearerToken}
|
||||||
|
headerName={headerName}
|
||||||
|
setHeaderName={setHeaderName}
|
||||||
onConnect={connectMcpServer}
|
onConnect={connectMcpServer}
|
||||||
onDisconnect={disconnectMcpServer}
|
onDisconnect={disconnectMcpServer}
|
||||||
stdErrNotifications={stdErrNotifications}
|
stdErrNotifications={stdErrNotifications}
|
||||||
logLevel={logLevel}
|
logLevel={logLevel}
|
||||||
sendLogLevelRequest={sendLogLevelRequest}
|
sendLogLevelRequest={sendLogLevelRequest}
|
||||||
loggingSupported={!!serverCapabilities?.logging || false}
|
loggingSupported={!!serverCapabilities?.logging || false}
|
||||||
|
clearStdErrNotifications={clearStdErrNotifications}
|
||||||
/>
|
/>
|
||||||
<div className="flex-1 flex flex-col overflow-hidden">
|
<div className="flex-1 flex flex-col overflow-hidden">
|
||||||
<div className="flex-1 overflow-auto">
|
<div className="flex-1 overflow-auto">
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ const JsonNode = memo(
|
|||||||
)}
|
)}
|
||||||
<pre
|
<pre
|
||||||
className={clsx(
|
className={clsx(
|
||||||
typeStyleMap.string,
|
isError ? typeStyleMap.error : typeStyleMap.string,
|
||||||
"break-all whitespace-pre-wrap",
|
"break-all whitespace-pre-wrap",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -51,9 +51,12 @@ interface SidebarProps {
|
|||||||
setEnv: (env: Record<string, string>) => void;
|
setEnv: (env: Record<string, string>) => void;
|
||||||
bearerToken: string;
|
bearerToken: string;
|
||||||
setBearerToken: (token: string) => void;
|
setBearerToken: (token: string) => void;
|
||||||
|
headerName?: string;
|
||||||
|
setHeaderName?: (name: string) => void;
|
||||||
onConnect: () => void;
|
onConnect: () => void;
|
||||||
onDisconnect: () => void;
|
onDisconnect: () => void;
|
||||||
stdErrNotifications: StdErrNotification[];
|
stdErrNotifications: StdErrNotification[];
|
||||||
|
clearStdErrNotifications: () => void;
|
||||||
logLevel: LoggingLevel;
|
logLevel: LoggingLevel;
|
||||||
sendLogLevelRequest: (level: LoggingLevel) => void;
|
sendLogLevelRequest: (level: LoggingLevel) => void;
|
||||||
loggingSupported: boolean;
|
loggingSupported: boolean;
|
||||||
@@ -75,9 +78,12 @@ const Sidebar = ({
|
|||||||
setEnv,
|
setEnv,
|
||||||
bearerToken,
|
bearerToken,
|
||||||
setBearerToken,
|
setBearerToken,
|
||||||
|
headerName,
|
||||||
|
setHeaderName,
|
||||||
onConnect,
|
onConnect,
|
||||||
onDisconnect,
|
onDisconnect,
|
||||||
stdErrNotifications,
|
stdErrNotifications,
|
||||||
|
clearStdErrNotifications,
|
||||||
logLevel,
|
logLevel,
|
||||||
sendLogLevelRequest,
|
sendLogLevelRequest,
|
||||||
loggingSupported,
|
loggingSupported,
|
||||||
@@ -174,6 +180,7 @@ const Sidebar = ({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => setShowBearerToken(!showBearerToken)}
|
onClick={() => setShowBearerToken(!showBearerToken)}
|
||||||
className="flex items-center w-full"
|
className="flex items-center w-full"
|
||||||
|
data-testid="auth-button"
|
||||||
aria-expanded={showBearerToken}
|
aria-expanded={showBearerToken}
|
||||||
>
|
>
|
||||||
{showBearerToken ? (
|
{showBearerToken ? (
|
||||||
@@ -185,6 +192,16 @@ const Sidebar = ({
|
|||||||
</Button>
|
</Button>
|
||||||
{showBearerToken && (
|
{showBearerToken && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
<label className="text-sm font-medium">Header Name</label>
|
||||||
|
<Input
|
||||||
|
placeholder="Authorization"
|
||||||
|
onChange={(e) =>
|
||||||
|
setHeaderName && setHeaderName(e.target.value)
|
||||||
|
}
|
||||||
|
data-testid="header-input"
|
||||||
|
className="font-mono"
|
||||||
|
value={headerName}
|
||||||
|
/>
|
||||||
<label
|
<label
|
||||||
className="text-sm font-medium"
|
className="text-sm font-medium"
|
||||||
htmlFor="bearer-token-input"
|
htmlFor="bearer-token-input"
|
||||||
@@ -196,6 +213,7 @@ const Sidebar = ({
|
|||||||
placeholder="Bearer Token"
|
placeholder="Bearer Token"
|
||||||
value={bearerToken}
|
value={bearerToken}
|
||||||
onChange={(e) => setBearerToken(e.target.value)}
|
onChange={(e) => setBearerToken(e.target.value)}
|
||||||
|
data-testid="bearer-token-input"
|
||||||
className="font-mono"
|
className="font-mono"
|
||||||
type="password"
|
type="password"
|
||||||
/>
|
/>
|
||||||
@@ -514,9 +532,19 @@ const Sidebar = ({
|
|||||||
{stdErrNotifications.length > 0 && (
|
{stdErrNotifications.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<div className="mt-4 border-t border-gray-200 pt-4">
|
<div className="mt-4 border-t border-gray-200 pt-4">
|
||||||
<h3 className="text-sm font-medium">
|
<div className="flex justify-between items-center">
|
||||||
Error output from MCP server
|
<h3 className="text-sm font-medium">
|
||||||
</h3>
|
Error output from MCP server
|
||||||
|
</h3>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={clearStdErrNotifications}
|
||||||
|
className="h-8 px-2"
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<div className="mt-2 max-h-80 overflow-y-auto">
|
<div className="mt-2 max-h-80 overflow-y-auto">
|
||||||
{stdErrNotifications.map((notification, index) => (
|
{stdErrNotifications.map((notification, index) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { render, screen, fireEvent } from "@testing-library/react";
|
import { render, screen, fireEvent } from "@testing-library/react";
|
||||||
|
import "@testing-library/jest-dom";
|
||||||
import { describe, it, beforeEach, jest } from "@jest/globals";
|
import { describe, it, beforeEach, jest } from "@jest/globals";
|
||||||
import Sidebar from "../Sidebar";
|
import Sidebar from "../Sidebar";
|
||||||
import { DEFAULT_INSPECTOR_CONFIG } from "@/lib/constants";
|
import { DEFAULT_INSPECTOR_CONFIG } from "@/lib/constants";
|
||||||
@@ -29,6 +30,7 @@ describe("Sidebar Environment Variables", () => {
|
|||||||
onConnect: jest.fn(),
|
onConnect: jest.fn(),
|
||||||
onDisconnect: jest.fn(),
|
onDisconnect: jest.fn(),
|
||||||
stdErrNotifications: [],
|
stdErrNotifications: [],
|
||||||
|
clearStdErrNotifications: jest.fn(),
|
||||||
logLevel: "info" as const,
|
logLevel: "info" as const,
|
||||||
sendLogLevelRequest: jest.fn(),
|
sendLogLevelRequest: jest.fn(),
|
||||||
loggingSupported: true,
|
loggingSupported: true,
|
||||||
@@ -108,6 +110,157 @@ describe("Sidebar Environment Variables", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Authentication", () => {
|
||||||
|
const openAuthSection = () => {
|
||||||
|
const button = screen.getByTestId("auth-button");
|
||||||
|
fireEvent.click(button);
|
||||||
|
};
|
||||||
|
|
||||||
|
it("should update bearer token", () => {
|
||||||
|
const setBearerToken = jest.fn();
|
||||||
|
renderSidebar({
|
||||||
|
bearerToken: "",
|
||||||
|
setBearerToken,
|
||||||
|
transportType: "sse", // Set transport type to SSE
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
const tokenInput = screen.getByTestId("bearer-token-input");
|
||||||
|
fireEvent.change(tokenInput, { target: { value: "new_token" } });
|
||||||
|
|
||||||
|
expect(setBearerToken).toHaveBeenCalledWith("new_token");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should update header name", () => {
|
||||||
|
const setHeaderName = jest.fn();
|
||||||
|
renderSidebar({
|
||||||
|
headerName: "Authorization",
|
||||||
|
setHeaderName,
|
||||||
|
transportType: "sse",
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
const headerInput = screen.getByTestId("header-input");
|
||||||
|
fireEvent.change(headerInput, { target: { value: "X-Custom-Auth" } });
|
||||||
|
|
||||||
|
expect(setHeaderName).toHaveBeenCalledWith("X-Custom-Auth");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should clear bearer token", () => {
|
||||||
|
const setBearerToken = jest.fn();
|
||||||
|
renderSidebar({
|
||||||
|
bearerToken: "existing_token",
|
||||||
|
setBearerToken,
|
||||||
|
transportType: "sse", // Set transport type to SSE
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
const tokenInput = screen.getByTestId("bearer-token-input");
|
||||||
|
fireEvent.change(tokenInput, { target: { value: "" } });
|
||||||
|
|
||||||
|
expect(setBearerToken).toHaveBeenCalledWith("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should properly render bearer token input", () => {
|
||||||
|
const { rerender } = renderSidebar({
|
||||||
|
bearerToken: "existing_token",
|
||||||
|
transportType: "sse", // Set transport type to SSE
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
// Token input should be a password field
|
||||||
|
const tokenInput = screen.getByTestId("bearer-token-input");
|
||||||
|
expect(tokenInput).toHaveProperty("type", "password");
|
||||||
|
|
||||||
|
// Update the token
|
||||||
|
fireEvent.change(tokenInput, { target: { value: "new_token" } });
|
||||||
|
|
||||||
|
// Rerender with updated token
|
||||||
|
rerender(
|
||||||
|
<TooltipProvider>
|
||||||
|
<Sidebar
|
||||||
|
{...defaultProps}
|
||||||
|
bearerToken="new_token"
|
||||||
|
transportType="sse"
|
||||||
|
/>
|
||||||
|
</TooltipProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Token input should still exist after update
|
||||||
|
expect(screen.getByTestId("bearer-token-input")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should maintain token visibility state after update", () => {
|
||||||
|
const { rerender } = renderSidebar({
|
||||||
|
bearerToken: "existing_token",
|
||||||
|
transportType: "sse", // Set transport type to SSE
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
// Token input should be a password field
|
||||||
|
const tokenInput = screen.getByTestId("bearer-token-input");
|
||||||
|
expect(tokenInput).toHaveProperty("type", "password");
|
||||||
|
|
||||||
|
// Update the token
|
||||||
|
fireEvent.change(tokenInput, { target: { value: "new_token" } });
|
||||||
|
|
||||||
|
// Rerender with updated token
|
||||||
|
rerender(
|
||||||
|
<TooltipProvider>
|
||||||
|
<Sidebar
|
||||||
|
{...defaultProps}
|
||||||
|
bearerToken="new_token"
|
||||||
|
transportType="sse"
|
||||||
|
/>
|
||||||
|
</TooltipProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Token input should still exist after update
|
||||||
|
expect(screen.getByTestId("bearer-token-input")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should maintain header name when toggling auth section", () => {
|
||||||
|
renderSidebar({
|
||||||
|
headerName: "X-API-Key",
|
||||||
|
transportType: "sse",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Open auth section
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
// Verify header name is displayed
|
||||||
|
const headerInput = screen.getByTestId("header-input");
|
||||||
|
expect(headerInput).toHaveValue("X-API-Key");
|
||||||
|
|
||||||
|
// Close auth section
|
||||||
|
const authButton = screen.getByTestId("auth-button");
|
||||||
|
fireEvent.click(authButton);
|
||||||
|
|
||||||
|
// Reopen auth section
|
||||||
|
fireEvent.click(authButton);
|
||||||
|
|
||||||
|
// Verify header name is still preserved
|
||||||
|
expect(screen.getByTestId("header-input")).toHaveValue("X-API-Key");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should display default header name when not specified", () => {
|
||||||
|
renderSidebar({
|
||||||
|
headerName: undefined,
|
||||||
|
transportType: "sse",
|
||||||
|
});
|
||||||
|
|
||||||
|
openAuthSection();
|
||||||
|
|
||||||
|
const headerInput = screen.getByTestId("header-input");
|
||||||
|
expect(headerInput).toHaveAttribute("placeholder", "Authorization");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("Key Editing", () => {
|
describe("Key Editing", () => {
|
||||||
it("should maintain order when editing first key", () => {
|
it("should maintain order when editing first key", () => {
|
||||||
const setEnv = jest.fn();
|
const setEnv = jest.fn();
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ interface UseConnectionOptions {
|
|||||||
sseUrl: string;
|
sseUrl: string;
|
||||||
env: Record<string, string>;
|
env: Record<string, string>;
|
||||||
bearerToken?: string;
|
bearerToken?: string;
|
||||||
|
headerName?: string;
|
||||||
config: InspectorConfig;
|
config: InspectorConfig;
|
||||||
onNotification?: (notification: Notification) => void;
|
onNotification?: (notification: Notification) => void;
|
||||||
onStdErrNotification?: (notification: Notification) => void;
|
onStdErrNotification?: (notification: Notification) => void;
|
||||||
@@ -64,6 +65,7 @@ export function useConnection({
|
|||||||
sseUrl,
|
sseUrl,
|
||||||
env,
|
env,
|
||||||
bearerToken,
|
bearerToken,
|
||||||
|
headerName,
|
||||||
config,
|
config,
|
||||||
onNotification,
|
onNotification,
|
||||||
onStdErrNotification,
|
onStdErrNotification,
|
||||||
@@ -293,7 +295,8 @@ export function useConnection({
|
|||||||
// Use manually provided bearer token if available, otherwise use OAuth tokens
|
// Use manually provided bearer token if available, otherwise use OAuth tokens
|
||||||
const token = bearerToken || (await authProvider.tokens())?.access_token;
|
const token = bearerToken || (await authProvider.tokens())?.access_token;
|
||||||
if (token) {
|
if (token) {
|
||||||
headers["Authorization"] = `Bearer ${token}`;
|
const authHeaderName = headerName || "Authorization";
|
||||||
|
headers[authHeaderName] = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const clientTransport = new SSEClientTransport(mcpProxyServerUrl, {
|
const clientTransport = new SSEClientTransport(mcpProxyServerUrl, {
|
||||||
|
|||||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.8.2",
|
"version": "0.9.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.8.2",
|
"version": "0.9.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"client",
|
"client",
|
||||||
"server"
|
"server"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/inspector-client": "^0.8.2",
|
"@modelcontextprotocol/inspector-client": "^0.9.0",
|
||||||
"@modelcontextprotocol/inspector-server": "^0.8.2",
|
"@modelcontextprotocol/inspector-server": "^0.9.0",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"shell-quote": "^1.8.2",
|
"shell-quote": "^1.8.2",
|
||||||
"spawn-rx": "^5.1.2",
|
"spawn-rx": "^5.1.2",
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
},
|
},
|
||||||
"client": {
|
"client": {
|
||||||
"name": "@modelcontextprotocol/inspector-client",
|
"name": "@modelcontextprotocol/inspector-client",
|
||||||
"version": "0.8.2",
|
"version": "0.9.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.9.0",
|
"@modelcontextprotocol/sdk": "^1.9.0",
|
||||||
@@ -9500,7 +9500,7 @@
|
|||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"name": "@modelcontextprotocol/inspector-server",
|
"name": "@modelcontextprotocol/inspector-server",
|
||||||
"version": "0.8.2",
|
"version": "0.9.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.9.0",
|
"@modelcontextprotocol/sdk": "^1.9.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector",
|
"name": "@modelcontextprotocol/inspector",
|
||||||
"version": "0.8.2",
|
"version": "0.9.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)",
|
||||||
@@ -36,8 +36,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.8.2",
|
"@modelcontextprotocol/inspector-client": "^0.9.0",
|
||||||
"@modelcontextprotocol/inspector-server": "^0.8.2",
|
"@modelcontextprotocol/inspector-server": "^0.9.0",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
"shell-quote": "^1.8.2",
|
"shell-quote": "^1.8.2",
|
||||||
"spawn-rx": "^5.1.2",
|
"spawn-rx": "^5.1.2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@modelcontextprotocol/inspector-server",
|
"name": "@modelcontextprotocol/inspector-server",
|
||||||
"version": "0.8.2",
|
"version": "0.9.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)",
|
||||||
|
|||||||
Reference in New Issue
Block a user