feat(client): make all config initialize-able via search params
This commit is contained in:
@@ -101,6 +101,12 @@ http://localhost:6274/?transport=streamable-http&serverUrl=http://localhost:8787
|
|||||||
http://localhost:6274/?transport=stdio&serverCommand=npx&serverArgs=arg1%20arg2
|
http://localhost:6274/?transport=stdio&serverCommand=npx&serverArgs=arg1%20arg2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also set initial config settings via query params, for example:
|
||||||
|
|
||||||
|
```
|
||||||
|
http://localhost:6274/?MCP_SERVER_REQUEST_TIMEOUT=10000&MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS=false&MCP_PROXY_FULL_ADDRESS=http://10.1.1.22:5577
|
||||||
|
```
|
||||||
|
|
||||||
Note that if both the query param and the corresponding localStorage item are set, the query param will take precedence.
|
Note that if both the query param and the corresponding localStorage item are set, the query param will take precedence.
|
||||||
|
|
||||||
### From this repository
|
### From this repository
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import RootsTab from "./components/RootsTab";
|
|||||||
import SamplingTab, { PendingRequest } from "./components/SamplingTab";
|
import SamplingTab, { PendingRequest } from "./components/SamplingTab";
|
||||||
import Sidebar from "./components/Sidebar";
|
import Sidebar from "./components/Sidebar";
|
||||||
import ToolsTab from "./components/ToolsTab";
|
import ToolsTab from "./components/ToolsTab";
|
||||||
import { DEFAULT_INSPECTOR_CONFIG } from "./lib/constants";
|
|
||||||
import { InspectorConfig } from "./lib/configurationTypes";
|
import { InspectorConfig } from "./lib/configurationTypes";
|
||||||
import {
|
import {
|
||||||
getMCPProxyAddress,
|
getMCPProxyAddress,
|
||||||
@@ -57,6 +56,7 @@ import {
|
|||||||
getInitialTransportType,
|
getInitialTransportType,
|
||||||
getInitialCommand,
|
getInitialCommand,
|
||||||
getInitialArgs,
|
getInitialArgs,
|
||||||
|
initializeInspectorConfig,
|
||||||
} from "./utils/configUtils";
|
} from "./utils/configUtils";
|
||||||
|
|
||||||
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
|
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
|
||||||
@@ -92,27 +92,9 @@ const App = () => {
|
|||||||
const [roots, setRoots] = useState<Root[]>([]);
|
const [roots, setRoots] = useState<Root[]>([]);
|
||||||
const [env, setEnv] = useState<Record<string, string>>({});
|
const [env, setEnv] = useState<Record<string, string>>({});
|
||||||
|
|
||||||
const [config, setConfig] = useState<InspectorConfig>(() => {
|
const [config, setConfig] = useState<InspectorConfig>(() =>
|
||||||
const savedConfig = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
|
initializeInspectorConfig(CONFIG_LOCAL_STORAGE_KEY),
|
||||||
if (savedConfig) {
|
);
|
||||||
// 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;
|
|
||||||
});
|
|
||||||
const [bearerToken, setBearerToken] = useState<string>(() => {
|
const [bearerToken, setBearerToken] = useState<string>(() => {
|
||||||
return localStorage.getItem("lastBearerToken") || "";
|
return localStorage.getItem("lastBearerToken") || "";
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { InspectorConfig } from "@/lib/configurationTypes";
|
import { InspectorConfig } from "@/lib/configurationTypes";
|
||||||
import { DEFAULT_MCP_PROXY_LISTEN_PORT } from "@/lib/constants";
|
import {
|
||||||
|
DEFAULT_MCP_PROXY_LISTEN_PORT,
|
||||||
|
DEFAULT_INSPECTOR_CONFIG,
|
||||||
|
} from "@/lib/constants";
|
||||||
|
|
||||||
export const getMCPProxyAddress = (config: InspectorConfig): string => {
|
export const getMCPProxyAddress = (config: InspectorConfig): string => {
|
||||||
const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value as string;
|
const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value as string;
|
||||||
@@ -67,3 +70,57 @@ export const getInitialArgs = (): string => {
|
|||||||
if (param) return param;
|
if (param) return param;
|
||||||
return localStorage.getItem("lastArgs") || "";
|
return localStorage.getItem("lastArgs") || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returns a map of config key -> value from query params if present
|
||||||
|
export const getConfigOverridesFromQueryParams = (
|
||||||
|
defaultConfig: InspectorConfig,
|
||||||
|
): Partial<InspectorConfig> => {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
const overrides: Partial<InspectorConfig> = {};
|
||||||
|
for (const key of Object.keys(defaultConfig)) {
|
||||||
|
const param = url.searchParams.get(key);
|
||||||
|
if (param !== null) {
|
||||||
|
// Try to coerce to correct type based on default value
|
||||||
|
const defaultValue = defaultConfig[key as keyof InspectorConfig].value;
|
||||||
|
let value: string | number | boolean = param;
|
||||||
|
if (typeof defaultValue === "number") {
|
||||||
|
value = Number(param);
|
||||||
|
} else if (typeof defaultValue === "boolean") {
|
||||||
|
value = param === "true";
|
||||||
|
}
|
||||||
|
overrides[key as keyof InspectorConfig] = {
|
||||||
|
...defaultConfig[key as keyof InspectorConfig],
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overrides;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initializeInspectorConfig = (
|
||||||
|
localStorageKey: string,
|
||||||
|
): InspectorConfig => {
|
||||||
|
const savedConfig = localStorage.getItem(localStorageKey);
|
||||||
|
let baseConfig: InspectorConfig;
|
||||||
|
if (savedConfig) {
|
||||||
|
// 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)
|
||||||
|
for (const [key, value] of Object.entries(mergedConfig)) {
|
||||||
|
mergedConfig[key as keyof InspectorConfig] = {
|
||||||
|
...value,
|
||||||
|
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
baseConfig = mergedConfig;
|
||||||
|
} else {
|
||||||
|
baseConfig = DEFAULT_INSPECTOR_CONFIG;
|
||||||
|
}
|
||||||
|
// Apply query param overrides
|
||||||
|
const overrides = getConfigOverridesFromQueryParams(DEFAULT_INSPECTOR_CONFIG);
|
||||||
|
return { ...baseConfig, ...overrides };
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user