Skip to content

Commit 3f72125

Browse files
feat(mcp): require connection test before saving tools
Add validation to require successful connection test before saving MCP tools, matching the models workflow.
1 parent 1bb01f9 commit 3f72125

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

apps/frontend/src/app/(protected)/mcp/components/MCPConnectionDialog.tsx

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export function MCPConnectionDialog({
118118
is_authenticated: string;
119119
message: string;
120120
} | null>(null);
121+
const [connectionTested, setConnectionTested] = useState(false);
121122

122123
const isEditMode = mode === 'edit';
123124

@@ -167,6 +168,7 @@ export function MCPConnectionDialog({
167168
setLoading(false);
168169
setShowAdvancedConfig(!!tool.tool_metadata);
169170
setTestResult(null);
171+
setConnectionTested(true); // Skip test requirement in edit mode
170172
} else if (provider) {
171173
// Create mode: reset to defaults
172174
setName('');
@@ -179,10 +181,24 @@ export function MCPConnectionDialog({
179181
setLoading(false);
180182
setShowAdvancedConfig(isCustomProvider);
181183
setTestResult(null);
184+
setConnectionTested(false);
182185
}
183186
}
184187
}, [open, provider, tool, isEditMode, isCustomProvider]);
185188

189+
// Reset connection test status when critical fields change
190+
useEffect(() => {
191+
if (!isEditMode) {
192+
// In create mode, always reset when fields change
193+
setConnectionTested(false);
194+
setTestResult(null);
195+
} else if (authToken && authToken !== '************') {
196+
// In edit mode, reset only if auth token was actually changed
197+
setConnectionTested(false);
198+
setTestResult(null);
199+
}
200+
}, [name, authToken, toolMetadata, provider, isEditMode]);
201+
186202
const validateToolMetadata = (
187203
jsonString: string
188204
): Record<string, any> | null => {
@@ -298,13 +314,21 @@ export function MCPConnectionDialog({
298314
// Test the connection
299315
const result = await servicesClient.testMCPConnection(testRequest);
300316
setTestResult(result);
317+
318+
// Mark as tested if successful
319+
if (result.is_authenticated === 'Yes') {
320+
setConnectionTested(true);
321+
} else {
322+
setConnectionTested(false);
323+
}
301324
} catch (err) {
302325
setError(
303326
err instanceof Error
304327
? err.message
305328
: 'Failed to test connection. Please try again.'
306329
);
307330
setTestResult(null);
331+
setConnectionTested(false);
308332
} finally {
309333
setTestingConnection(false);
310334
}
@@ -371,7 +395,19 @@ export function MCPConnectionDialog({
371395
setLoading(false);
372396
}
373397
} else {
374-
// Create mode: validate required fields
398+
// Create mode: require connection test
399+
if (!connectionTested) {
400+
setError('Please test the connection before saving the tool.');
401+
return;
402+
}
403+
404+
// Validate that test was successful
405+
if (!testResult || testResult.is_authenticated !== 'Yes') {
406+
setError('Connection test must be successful before saving.');
407+
return;
408+
}
409+
410+
// Validate required fields
375411
if (!provider || !name || (requiresToken && !authToken)) {
376412
setError('Please fill in all required fields.');
377413
return;
@@ -723,6 +759,27 @@ export function MCPConnectionDialog({
723759
</Stack>
724760
</DialogContent>
725761

762+
{/* Connection Test Required Message */}
763+
{!isEditMode && !connectionTested && !testResult && (
764+
<Box sx={{ px: 3, pb: 1 }}>
765+
<Alert severity="info">
766+
Please test the connection before saving the tool configuration.
767+
</Alert>
768+
</Box>
769+
)}
770+
{isEditMode &&
771+
requiresToken &&
772+
authToken !== '************' &&
773+
!connectionTested &&
774+
!testResult && (
775+
<Box sx={{ px: 3, pb: 1 }}>
776+
<Alert severity="info">
777+
Please test the connection with the new credentials before
778+
updating.
779+
</Alert>
780+
</Box>
781+
)}
782+
726783
<DialogActions
727784
sx={{ px: 3, py: 2, borderTop: '1px solid', borderColor: 'divider' }}
728785
>
@@ -736,6 +793,11 @@ export function MCPConnectionDialog({
736793
!name ||
737794
(!isEditMode && requiresToken && !authToken) ||
738795
(!isEditMode && isCustomProvider && !toolMetadata.trim()) ||
796+
(!isEditMode && !connectionTested) ||
797+
(isEditMode &&
798+
requiresToken &&
799+
authToken !== '************' &&
800+
!connectionTested) || // Require test if token changed in edit mode
739801
loading ||
740802
!!jsonError
741803
}

0 commit comments

Comments
 (0)