Skip to content

Commit 2915ccc

Browse files
committed
feat(client): make all config initialize-able via search params
1 parent 3c5c384 commit 2915ccc

File tree

3 files changed

+68
-23
lines changed

3 files changed

+68
-23
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ http://localhost:6274/?transport=streamable-http&serverUrl=http://localhost:8787
101101
http://localhost:6274/?transport=stdio&serverCommand=npx&serverArgs=arg1%20arg2
102102
```
103103

104+
You can also set initial config settings via query params, for example:
105+
106+
```
107+
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
108+
```
109+
104110
Note that if both the query param and the corresponding localStorage item are set, the query param will take precedence.
105111

106112
### From this repository

client/src/App.tsx

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ import RootsTab from "./components/RootsTab";
4949
import SamplingTab, { PendingRequest } from "./components/SamplingTab";
5050
import Sidebar from "./components/Sidebar";
5151
import ToolsTab from "./components/ToolsTab";
52-
import { DEFAULT_INSPECTOR_CONFIG } from "./lib/constants";
5352
import { InspectorConfig } from "./lib/configurationTypes";
5453
import {
5554
getMCPProxyAddress,
5655
getInitialSseUrl,
5756
getInitialTransportType,
5857
getInitialCommand,
5958
getInitialArgs,
59+
initializeInspectorConfig,
6060
} from "./utils/configUtils";
6161

6262
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
@@ -92,27 +92,9 @@ const App = () => {
9292
const [roots, setRoots] = useState<Root[]>([]);
9393
const [env, setEnv] = useState<Record<string, string>>({});
9494

95-
const [config, setConfig] = useState<InspectorConfig>(() => {
96-
const savedConfig = localStorage.getItem(CONFIG_LOCAL_STORAGE_KEY);
97-
if (savedConfig) {
98-
// merge default config with saved config
99-
const mergedConfig = {
100-
...DEFAULT_INSPECTOR_CONFIG,
101-
...JSON.parse(savedConfig),
102-
} as InspectorConfig;
103-
104-
// update description of keys to match the new description (in case of any updates to the default config description)
105-
Object.entries(mergedConfig).forEach(([key, value]) => {
106-
mergedConfig[key as keyof InspectorConfig] = {
107-
...value,
108-
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
109-
};
110-
});
111-
112-
return mergedConfig;
113-
}
114-
return DEFAULT_INSPECTOR_CONFIG;
115-
});
95+
const [config, setConfig] = useState<InspectorConfig>(() =>
96+
initializeInspectorConfig(CONFIG_LOCAL_STORAGE_KEY),
97+
);
11698
const [bearerToken, setBearerToken] = useState<string>(() => {
11799
return localStorage.getItem("lastBearerToken") || "";
118100
});

client/src/utils/configUtils.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { InspectorConfig } from "@/lib/configurationTypes";
2-
import { DEFAULT_MCP_PROXY_LISTEN_PORT } from "@/lib/constants";
2+
import {
3+
DEFAULT_MCP_PROXY_LISTEN_PORT,
4+
DEFAULT_INSPECTOR_CONFIG,
5+
} from "@/lib/constants";
36

47
export const getMCPProxyAddress = (config: InspectorConfig): string => {
58
const proxyFullAddress = config.MCP_PROXY_FULL_ADDRESS.value as string;
@@ -67,3 +70,57 @@ export const getInitialArgs = (): string => {
6770
if (param) return param;
6871
return localStorage.getItem("lastArgs") || "";
6972
};
73+
74+
// Returns a map of config key -> value from query params if present
75+
export const getConfigOverridesFromQueryParams = (
76+
defaultConfig: InspectorConfig,
77+
): Partial<InspectorConfig> => {
78+
const url = new URL(window.location.href);
79+
const overrides: Partial<InspectorConfig> = {};
80+
for (const key of Object.keys(defaultConfig)) {
81+
const param = url.searchParams.get(key);
82+
if (param !== null) {
83+
// Try to coerce to correct type based on default value
84+
const defaultValue = defaultConfig[key as keyof InspectorConfig].value;
85+
let value: string | number | boolean = param;
86+
if (typeof defaultValue === "number") {
87+
value = Number(param);
88+
} else if (typeof defaultValue === "boolean") {
89+
value = param === "true";
90+
}
91+
overrides[key as keyof InspectorConfig] = {
92+
...defaultConfig[key as keyof InspectorConfig],
93+
value,
94+
};
95+
}
96+
}
97+
return overrides;
98+
};
99+
100+
export const initializeInspectorConfig = (
101+
localStorageKey: string,
102+
): InspectorConfig => {
103+
const savedConfig = localStorage.getItem(localStorageKey);
104+
let baseConfig: InspectorConfig;
105+
if (savedConfig) {
106+
// merge default config with saved config
107+
const mergedConfig = {
108+
...DEFAULT_INSPECTOR_CONFIG,
109+
...JSON.parse(savedConfig),
110+
} as InspectorConfig;
111+
112+
// update description of keys to match the new description (in case of any updates to the default config description)
113+
for (const [key, value] of Object.entries(mergedConfig)) {
114+
mergedConfig[key as keyof InspectorConfig] = {
115+
...value,
116+
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
117+
};
118+
}
119+
baseConfig = mergedConfig;
120+
} else {
121+
baseConfig = DEFAULT_INSPECTOR_CONFIG;
122+
}
123+
// Apply query param overrides
124+
const overrides = getConfigOverridesFromQueryParams(DEFAULT_INSPECTOR_CONFIG);
125+
return { ...baseConfig, ...overrides };
126+
};

0 commit comments

Comments
 (0)