Skip to content

Commit ab062d8

Browse files
refactor: implement split storage for inspector config
- Add is_session_item field to ConfigItem type to control storage location - Store auth tokens in sessionStorage (cleared on browser close) - Store other settings in localStorage (persist between sessions) - Maintain backward compatibility with existing config structure This provides better security for auth tokens while preserving user preferences across browser sessions.
1 parent 32e6bdd commit ab062d8

File tree

4 files changed

+67
-20
lines changed

4 files changed

+67
-20
lines changed

client/src/App.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import {
6868
getInitialCommand,
6969
getInitialArgs,
7070
initializeInspectorConfig,
71+
saveInspectorConfig,
7172
} from "./utils/configUtils";
7273

7374
const CONFIG_LOCAL_STORAGE_KEY = "inspectorConfig_v1";
@@ -226,7 +227,7 @@ const App = () => {
226227
}, [headerName]);
227228

228229
useEffect(() => {
229-
localStorage.setItem(CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config));
230+
saveInspectorConfig(CONFIG_LOCAL_STORAGE_KEY, config);
230231
}, [config]);
231232

232233
// Auto-connect to previously saved serverURL after OAuth callback

client/src/lib/configurationTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export type ConfigItem = {
22
label: string;
33
description: string;
44
value: string | number | boolean;
5+
is_session_item: boolean;
56
};
67

78
/**

client/src/lib/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,33 @@ export const DEFAULT_INSPECTOR_CONFIG: InspectorConfig = {
3636
label: "Request Timeout",
3737
description: "Timeout for requests to the MCP server (ms)",
3838
value: 10000,
39+
is_session_item: false,
3940
},
4041
MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS: {
4142
label: "Reset Timeout on Progress",
4243
description: "Reset timeout on progress notifications",
4344
value: true,
45+
is_session_item: false,
4446
},
4547
MCP_REQUEST_MAX_TOTAL_TIMEOUT: {
4648
label: "Maximum Total Timeout",
4749
description:
4850
"Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications)",
4951
value: 60000,
52+
is_session_item: false,
5053
},
5154
MCP_PROXY_FULL_ADDRESS: {
5255
label: "Inspector Proxy Address",
5356
description:
5457
"Set this if you are running the MCP Inspector Proxy on a non-default address. Example: http://10.1.1.22:5577",
5558
value: "",
59+
is_session_item: false,
5660
},
5761
MCP_PROXY_AUTH_TOKEN: {
5862
label: "Proxy Session Token",
5963
description:
6064
"Session token for authenticating with the MCP Proxy Server (displayed in proxy console on startup)",
6165
value: "",
66+
is_session_item: true,
6267
},
6368
} as const;

client/src/utils/configUtils.ts

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -104,27 +104,67 @@ export const getConfigOverridesFromQueryParams = (
104104
export const initializeInspectorConfig = (
105105
localStorageKey: string,
106106
): InspectorConfig => {
107-
const savedConfig = localStorage.getItem(localStorageKey);
108-
let baseConfig: InspectorConfig;
109-
if (savedConfig) {
110-
// merge default config with saved config
111-
const mergedConfig = {
112-
...DEFAULT_INSPECTOR_CONFIG,
113-
...JSON.parse(savedConfig),
114-
} as InspectorConfig;
115-
116-
// update description of keys to match the new description (in case of any updates to the default config description)
117-
for (const [key, value] of Object.entries(mergedConfig)) {
118-
mergedConfig[key as keyof InspectorConfig] = {
119-
...value,
120-
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
121-
};
122-
}
123-
baseConfig = mergedConfig;
124-
} else {
125-
baseConfig = DEFAULT_INSPECTOR_CONFIG;
107+
// Read persistent config from localStorage
108+
const savedPersistentConfig = localStorage.getItem(localStorageKey);
109+
// Read ephemeral config from sessionStorage
110+
const savedEphemeralConfig = sessionStorage.getItem(
111+
`${localStorageKey}_ephemeral`,
112+
);
113+
114+
// Start with default config
115+
let baseConfig = { ...DEFAULT_INSPECTOR_CONFIG };
116+
117+
// Apply saved persistent config
118+
if (savedPersistentConfig) {
119+
const parsedPersistentConfig = JSON.parse(savedPersistentConfig);
120+
baseConfig = { ...baseConfig, ...parsedPersistentConfig };
126121
}
122+
123+
// Apply saved ephemeral config
124+
if (savedEphemeralConfig) {
125+
const parsedEphemeralConfig = JSON.parse(savedEphemeralConfig);
126+
baseConfig = { ...baseConfig, ...parsedEphemeralConfig };
127+
}
128+
129+
// Ensure all config items have the latest labels/descriptions from defaults
130+
for (const [key, value] of Object.entries(baseConfig)) {
131+
baseConfig[key as keyof InspectorConfig] = {
132+
...value,
133+
label: DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].label,
134+
description:
135+
DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].description,
136+
is_session_item:
137+
DEFAULT_INSPECTOR_CONFIG[key as keyof InspectorConfig].is_session_item,
138+
};
139+
}
140+
127141
// Apply query param overrides
128142
const overrides = getConfigOverridesFromQueryParams(DEFAULT_INSPECTOR_CONFIG);
129143
return { ...baseConfig, ...overrides };
130144
};
145+
146+
export const saveInspectorConfig = (
147+
localStorageKey: string,
148+
config: InspectorConfig,
149+
): void => {
150+
const persistentConfig: Partial<InspectorConfig> = {};
151+
const ephemeralConfig: Partial<InspectorConfig> = {};
152+
153+
// Split config based on is_session_item flag
154+
for (const [key, value] of Object.entries(config)) {
155+
if (value.is_session_item) {
156+
ephemeralConfig[key as keyof InspectorConfig] = value;
157+
} else {
158+
persistentConfig[key as keyof InspectorConfig] = value;
159+
}
160+
}
161+
162+
// Save persistent config to localStorage
163+
localStorage.setItem(localStorageKey, JSON.stringify(persistentConfig));
164+
165+
// Save ephemeral config to sessionStorage
166+
sessionStorage.setItem(
167+
`${localStorageKey}_ephemeral`,
168+
JSON.stringify(ephemeralConfig),
169+
);
170+
};

0 commit comments

Comments
 (0)