Skip to content

Commit ef7b8dc

Browse files
committed
fix(mcp): clarify OAuth authorization status
1 parent 9043b7e commit ef7b8dc

5 files changed

Lines changed: 75 additions & 8 deletions

File tree

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/mcp.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,12 @@ function ServerListItem({
8585
onViewDetails,
8686
}: ServerListItemProps) {
8787
const transportLabel = formatTransportLabel(server.transport || 'http')
88-
const toolsLabel = getServerToolsLabel(tools, server.connectionStatus, server.lastError)
88+
const toolsLabel = getServerToolsLabel(
89+
tools,
90+
server.connectionStatus,
91+
server.lastError,
92+
server.authType
93+
)
8994
const hasConnectionIssue =
9095
server.connectionStatus === 'error' || server.connectionStatus === 'disconnected'
9196

@@ -380,6 +385,8 @@ export function MCP() {
380385
const refreshAction = getRefreshActionState({
381386
mutationStatus: isCurrentRefresh ? refreshServerMutation.status : 'idle',
382387
connectionStatus: isCurrentRefresh ? refreshServerMutation.data?.status : undefined,
388+
authType: server.authType,
389+
error: isCurrentRefresh ? refreshServerMutation.data?.error : undefined,
383390
workflowsUpdated: isCurrentRefresh ? refreshServerMutation.data?.workflowsUpdated : undefined,
384391
})
385392

@@ -427,7 +434,12 @@ export function MCP() {
427434
<div className='flex flex-col gap-2'>
428435
<span className='text-[var(--text-muted)] text-caption'>Status</span>
429436
<p className='text-[var(--text-error)] text-sm'>
430-
{getServerToolsLabel([], server.connectionStatus, server.lastError)}
437+
{getServerToolsLabel(
438+
[],
439+
server.connectionStatus,
440+
server.lastError,
441+
server.authType
442+
)}
431443
</p>
432444
</div>
433445
)}

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/refresh-action-state.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,37 @@ describe('getRefreshActionState', () => {
3131
})
3232
})
3333

34+
it('shows Authorization required when an OAuth refresh finishes disconnected', () => {
35+
expect(
36+
getRefreshActionState({
37+
mutationStatus: 'success',
38+
connectionStatus: 'disconnected',
39+
authType: 'oauth',
40+
workflowsUpdated: 0,
41+
})
42+
).toEqual({
43+
text: 'Authorization required',
44+
textTone: 'error',
45+
disabled: false,
46+
})
47+
})
48+
49+
it('keeps Failed when a disconnected OAuth refresh has a concrete error', () => {
50+
expect(
51+
getRefreshActionState({
52+
mutationStatus: 'success',
53+
connectionStatus: 'disconnected',
54+
authType: 'oauth',
55+
error: 'The MCP server took too long to respond and timed out',
56+
workflowsUpdated: 0,
57+
})
58+
).toEqual({
59+
text: 'Failed',
60+
textTone: 'error',
61+
disabled: false,
62+
})
63+
})
64+
3465
it('preserves successful refresh feedback', () => {
3566
expect(
3667
getRefreshActionState({

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/refresh-action-state.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import type { MutationStatus } from '@tanstack/react-query'
2-
import type { RefreshMcpServerResult } from '@/lib/api/contracts/mcp'
2+
import type { McpServer, RefreshMcpServerResult } from '@/lib/api/contracts/mcp'
33
import type { SettingsAction } from '@/app/workspace/[workspaceId]/settings/components/settings-header/settings-header'
44

55
interface RefreshActionStateInput {
66
mutationStatus: MutationStatus
77
connectionStatus?: RefreshMcpServerResult['status']
8+
authType?: McpServer['authType']
9+
error?: RefreshMcpServerResult['error']
810
workflowsUpdated?: number
911
}
1012

@@ -13,12 +15,23 @@ type RefreshActionState = Pick<SettingsAction, 'text' | 'textTone' | 'disabled'>
1315
export function getRefreshActionState({
1416
mutationStatus,
1517
connectionStatus,
18+
authType,
19+
error,
1620
workflowsUpdated,
1721
}: RefreshActionStateInput): RefreshActionState {
1822
if (mutationStatus === 'pending') {
1923
return { text: 'Refreshing...', textTone: undefined, disabled: true }
2024
}
2125

26+
if (
27+
mutationStatus === 'success' &&
28+
connectionStatus === 'disconnected' &&
29+
authType === 'oauth' &&
30+
!error?.trim()
31+
) {
32+
return { text: 'Authorization required', textTone: 'error', disabled: false }
33+
}
34+
2235
if (
2336
mutationStatus === 'error' ||
2437
(mutationStatus === 'success' && connectionStatus !== 'connected')

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/server-tools-label.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,20 @@ describe('getServerToolsLabel', () => {
1212
expect(getServerToolsLabel([], 'error', null)).toBe('Unable to connect')
1313
})
1414

15-
it('shows a disconnected state when OAuth was not completed', () => {
16-
expect(getServerToolsLabel([], 'disconnected', null)).toBe('Not Connected')
15+
it('shows that OAuth authorization is required when OAuth was not completed', () => {
16+
expect(getServerToolsLabel([], 'disconnected', null, 'oauth')).toBe(
17+
'OAuth authorization required'
18+
)
19+
})
20+
21+
it('keeps the generic disconnected state for non-OAuth servers', () => {
22+
expect(getServerToolsLabel([], 'disconnected', null, 'headers')).toBe('Not Connected')
1723
})
1824

1925
it('shows the persisted error for disconnected connections', () => {
20-
expect(getServerToolsLabel([], 'disconnected', 'Request timed out')).toBe('Request timed out')
26+
expect(getServerToolsLabel([], 'disconnected', 'Request timed out', 'oauth')).toBe(
27+
'Request timed out'
28+
)
2129
})
2230

2331
it('continues showing discovered tools for healthy connections', () => {

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/server-tools-label.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ interface NamedTool {
77
export function getServerToolsLabel(
88
tools: NamedTool[],
99
connectionStatus?: McpServer['connectionStatus'],
10-
lastError?: McpServer['lastError']
10+
lastError?: McpServer['lastError'],
11+
authType?: McpServer['authType']
1112
): string {
1213
if (connectionStatus === 'error') {
1314
return lastError?.trim() || 'Unable to connect'
1415
}
1516

1617
if (connectionStatus === 'disconnected') {
17-
return lastError?.trim() || 'Not Connected'
18+
return (
19+
lastError?.trim() || (authType === 'oauth' ? 'OAuth authorization required' : 'Not Connected')
20+
)
1821
}
1922

2023
const count = tools.length

0 commit comments

Comments
 (0)