Merge remote-tracking branch 'theirs/main' into max/improved-oauth-callback
This commit is contained in:
@@ -51,10 +51,7 @@ import Sidebar from "./components/Sidebar";
|
||||
import ToolsTab from "./components/ToolsTab";
|
||||
import { DEFAULT_INSPECTOR_CONFIG } from "./lib/constants";
|
||||
import { InspectorConfig } from "./lib/configurationTypes";
|
||||
import {
|
||||
getMCPProxyAddress,
|
||||
getMCPServerRequestTimeout,
|
||||
} from "./utils/configUtils";
|
||||
import { getMCPProxyAddress } from "./utils/configUtils";
|
||||
|
||||
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
|
||||
|
||||
@@ -100,10 +97,21 @@ const App = () => {
|
||||
const [config, setConfig] = useState<InspectorConfig>(() => {
|
||||
const savedConfig = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
|
||||
if (savedConfig) {
|
||||
return {
|
||||
// merge default config with saved config
|
||||
const mergedConfig = {
|
||||
...DEFAULT_INSPECTOR_CONFIG,
|
||||
...JSON.parse(savedConfig),
|
||||
} as InspectorConfig;
|
||||
|
||||
// update description of keys to match the new description (in case of any updates to the default config description)
|
||||
Object.entries(mergedConfig).forEach(([key, value]) => {
|
||||
mergedConfig[key as keyof InspectorConfig] = {
|
||||
...value,
|
||||
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
|
||||
};
|
||||
});
|
||||
|
||||
return mergedConfig;
|
||||
}
|
||||
return DEFAULT_INSPECTOR_CONFIG;
|
||||
});
|
||||
@@ -111,6 +119,10 @@ const App = () => {
|
||||
return localStorage.getItem("lastBearerToken") || "";
|
||||
});
|
||||
|
||||
const [headerName, setHeaderName] = useState<string>(() => {
|
||||
return localStorage.getItem("lastHeaderName") || "";
|
||||
});
|
||||
|
||||
const [pendingSampleRequests, setPendingSampleRequests] = useState<
|
||||
Array<
|
||||
PendingRequest & {
|
||||
@@ -150,7 +162,7 @@ const App = () => {
|
||||
serverCapabilities,
|
||||
mcpClient,
|
||||
requestHistory,
|
||||
makeRequest: makeConnectionRequest,
|
||||
makeRequest,
|
||||
sendNotification,
|
||||
handleCompletion,
|
||||
completionsSupported,
|
||||
@@ -163,8 +175,8 @@ const App = () => {
|
||||
sseUrl,
|
||||
env,
|
||||
bearerToken,
|
||||
proxyServerUrl: getMCPProxyAddress(config),
|
||||
requestTimeout: getMCPServerRequestTimeout(config),
|
||||
headerName,
|
||||
config,
|
||||
onNotification: (notification) => {
|
||||
setNotifications((prev) => [...prev, notification as ServerNotification]);
|
||||
},
|
||||
@@ -203,6 +215,10 @@ const App = () => {
|
||||
localStorage.setItem("lastBearerToken", bearerToken);
|
||||
}, [bearerToken]);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem("lastHeaderName", headerName);
|
||||
}, [headerName]);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
|
||||
}, [config]);
|
||||
@@ -265,13 +281,13 @@ const App = () => {
|
||||
setErrors((prev) => ({ ...prev, [tabKey]: null }));
|
||||
};
|
||||
|
||||
const makeRequest = async <T extends z.ZodType>(
|
||||
const sendMCPRequest = async <T extends z.ZodType>(
|
||||
request: ClientRequest,
|
||||
schema: T,
|
||||
tabKey?: keyof typeof errors,
|
||||
) => {
|
||||
try {
|
||||
const response = await makeConnectionRequest(request, schema);
|
||||
const response = await makeRequest(request, schema);
|
||||
if (tabKey !== undefined) {
|
||||
clearError(tabKey);
|
||||
}
|
||||
@@ -289,7 +305,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const listResources = async () => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "resources/list" as const,
|
||||
params: nextResourceCursor ? { cursor: nextResourceCursor } : {},
|
||||
@@ -302,7 +318,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const listResourceTemplates = async () => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "resources/templates/list" as const,
|
||||
params: nextResourceTemplateCursor
|
||||
@@ -319,7 +335,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const readResource = async (uri: string) => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "resources/read" as const,
|
||||
params: { uri },
|
||||
@@ -332,7 +348,7 @@ const App = () => {
|
||||
|
||||
const subscribeToResource = async (uri: string) => {
|
||||
if (!resourceSubscriptions.has(uri)) {
|
||||
await makeRequest(
|
||||
await sendMCPRequest(
|
||||
{
|
||||
method: "resources/subscribe" as const,
|
||||
params: { uri },
|
||||
@@ -348,7 +364,7 @@ const App = () => {
|
||||
|
||||
const unsubscribeFromResource = async (uri: string) => {
|
||||
if (resourceSubscriptions.has(uri)) {
|
||||
await makeRequest(
|
||||
await sendMCPRequest(
|
||||
{
|
||||
method: "resources/unsubscribe" as const,
|
||||
params: { uri },
|
||||
@@ -363,7 +379,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const listPrompts = async () => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "prompts/list" as const,
|
||||
params: nextPromptCursor ? { cursor: nextPromptCursor } : {},
|
||||
@@ -376,7 +392,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const getPrompt = async (name: string, args: Record<string, string> = {}) => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "prompts/get" as const,
|
||||
params: { name, arguments: args },
|
||||
@@ -388,7 +404,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const listTools = async () => {
|
||||
const response = await makeRequest(
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "tools/list" as const,
|
||||
params: nextToolCursor ? { cursor: nextToolCursor } : {},
|
||||
@@ -401,21 +417,34 @@ const App = () => {
|
||||
};
|
||||
|
||||
const callTool = async (name: string, params: Record<string, unknown>) => {
|
||||
const response = await makeRequest(
|
||||
{
|
||||
method: "tools/call" as const,
|
||||
params: {
|
||||
name,
|
||||
arguments: params,
|
||||
_meta: {
|
||||
progressToken: progressTokenRef.current++,
|
||||
try {
|
||||
const response = await sendMCPRequest(
|
||||
{
|
||||
method: "tools/call" as const,
|
||||
params: {
|
||||
name,
|
||||
arguments: params,
|
||||
_meta: {
|
||||
progressToken: progressTokenRef.current++,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
CompatibilityCallToolResultSchema,
|
||||
"tools",
|
||||
);
|
||||
setToolResult(response);
|
||||
CompatibilityCallToolResultSchema,
|
||||
"tools",
|
||||
);
|
||||
setToolResult(response);
|
||||
} catch (e) {
|
||||
const toolResult: CompatibilityCallToolResult = {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: (e as Error).message ?? String(e),
|
||||
},
|
||||
],
|
||||
isError: true,
|
||||
};
|
||||
setToolResult(toolResult);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRootsChange = async () => {
|
||||
@@ -423,7 +452,7 @@ const App = () => {
|
||||
};
|
||||
|
||||
const sendLogLevelRequest = async (level: LoggingLevel) => {
|
||||
await makeRequest(
|
||||
await sendMCPRequest(
|
||||
{
|
||||
method: "logging/setLevel" as const,
|
||||
params: { level },
|
||||
@@ -433,6 +462,10 @@ const App = () => {
|
||||
setLogLevel(level);
|
||||
};
|
||||
|
||||
const clearStdErrNotifications = () => {
|
||||
setStdErrNotifications([]);
|
||||
};
|
||||
|
||||
if (window.location.pathname === "/oauth/callback") {
|
||||
const OAuthCallback = React.lazy(
|
||||
() => import("./components/OAuthCallback"),
|
||||
@@ -462,12 +495,15 @@ const App = () => {
|
||||
setConfig={setConfig}
|
||||
bearerToken={bearerToken}
|
||||
setBearerToken={setBearerToken}
|
||||
headerName={headerName}
|
||||
setHeaderName={setHeaderName}
|
||||
onConnect={connectMcpServer}
|
||||
onDisconnect={disconnectMcpServer}
|
||||
stdErrNotifications={stdErrNotifications}
|
||||
logLevel={logLevel}
|
||||
sendLogLevelRequest={sendLogLevelRequest}
|
||||
loggingSupported={!!serverCapabilities?.logging || false}
|
||||
clearStdErrNotifications={clearStdErrNotifications}
|
||||
/>
|
||||
<div className="flex-1 flex flex-col overflow-hidden">
|
||||
<div className="flex-1 overflow-auto">
|
||||
@@ -623,9 +659,10 @@ const App = () => {
|
||||
setTools([]);
|
||||
setNextToolCursor(undefined);
|
||||
}}
|
||||
callTool={(name, params) => {
|
||||
callTool={async (name, params) => {
|
||||
clearError("tools");
|
||||
callTool(name, params);
|
||||
setToolResult(null);
|
||||
await callTool(name, params);
|
||||
}}
|
||||
selectedTool={selectedTool}
|
||||
setSelectedTool={(tool) => {
|
||||
@@ -640,7 +677,7 @@ const App = () => {
|
||||
<ConsoleTab />
|
||||
<PingTab
|
||||
onPingClick={() => {
|
||||
void makeRequest(
|
||||
void sendMCPRequest(
|
||||
{
|
||||
method: "ping" as const,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user