)
diff --git a/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.test.tsx b/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.test.tsx
new file mode 100644
index 00000000000..4494b011528
--- /dev/null
+++ b/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.test.tsx
@@ -0,0 +1,32 @@
+import { screen } from '@testing-library/react'
+import { describe, expect, it } from 'vitest'
+
+import { InterstitialTerminalScreen } from './InterstitialTerminalScreen'
+import { customRender } from '@/tests/lib/custom-render'
+
+const baseCopy = {
+ title: 'Key stored',
+ subtitle: 'RESEND_API_KEY is saved for billing-staging.',
+ calloutTitle: 'Next step',
+ calloutBody: 'Head back to your agent and let it know you finished.',
+ footer: 'You can close this tab.',
+}
+
+describe('InterstitialTerminalScreen', () => {
+ it('links to the project Edge Functions secrets page when a project ref is given', () => {
+ customRender()
+
+ expect(screen.getByRole('link', { name: 'Go to Edge Functions secrets' })).toHaveAttribute(
+ 'href',
+ '/project/abcdefghijklmnopqrst/functions/secrets'
+ )
+ })
+
+ it('omits the Edge Functions secrets link when there is no project to point at', () => {
+ customRender()
+
+ expect(
+ screen.queryByRole('link', { name: 'Go to Edge Functions secrets' })
+ ).not.toBeInTheDocument()
+ })
+})
diff --git a/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.tsx b/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.tsx
index 93f1d1255a8..801f3cdfbdc 100644
--- a/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.tsx
+++ b/apps/studio/components/interfaces/MCP/InterstitialTerminalScreen.tsx
@@ -1,3 +1,4 @@
+import { Button, Separator } from 'ui'
import { Admonition } from 'ui-patterns/Admonition'
import { InterstitialFooter, InterstitialShell } from './InterstitialShell'
@@ -8,6 +9,7 @@ export type InterstitialTerminalCopy = {
calloutTitle: string
calloutBody: string
footer: string
+ projectRef?: string
}
export const InterstitialTerminalScreen = ({
@@ -16,9 +18,19 @@ export const InterstitialTerminalScreen = ({
calloutTitle,
calloutBody,
footer,
+ projectRef,
}: InterstitialTerminalCopy) => (
+
+ {projectRef && (
+
+ )}
+
+
+
{footer}
)
diff --git a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.constants.ts b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.constants.ts
index bea5ba8befb..7f7ff933493 100644
--- a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.constants.ts
+++ b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.constants.ts
@@ -2,8 +2,6 @@ export const MCP_SECRETS_ROUTE = '/mcp/secrets'
export const MCP_SECRETS_FLAG = 'McpElicitURLMode'
-export const UNKNOWN_CLIENT_LABEL = 'your AI client'
-
export const SECRETS_TOOL_NAME = 'create_edge_function_secret'
export const MAX_SECRET_NAME_LENGTH = 256
diff --git a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.test.ts b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.test.ts
index 7ba13370581..4753302dfbb 100644
--- a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.test.ts
+++ b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.test.ts
@@ -35,9 +35,7 @@ describe('getSecretsCopy', () => {
it('names the generic client, because v1 never learns which one sent the user', () => {
const copy = getSecretsCopy({ status: 'stored', request, timedOut: false })
- expect(copy.calloutBody).toBe(
- `Go back to your AI client and choose "I've completed it" to finish the tool call.`
- )
+ expect(copy.calloutBody).toBe(`Head back to your agent and let it know you're finished.`)
})
it('sends the user back to the agent instead of the client on timeout', () => {
diff --git a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.ts b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.ts
index 796fa0434b2..008c5229472 100644
--- a/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.ts
+++ b/apps/studio/components/interfaces/MCP/Secrets/McpSecrets.utils.ts
@@ -3,7 +3,6 @@ import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc'
import type { InterstitialTerminalCopy } from '../InterstitialTerminalScreen'
-import { UNKNOWN_CLIENT_LABEL } from './McpSecrets.constants'
import type {
SecretProviderHint,
SecretRequest,
@@ -14,7 +13,7 @@ import type {
dayjs.extend(relativeTime)
dayjs.extend(utc)
-const RETURN_TO_CLIENT_STEP = `Go back to ${UNKNOWN_CLIENT_LABEL} and choose "I've completed it" to finish the tool call.`
+const RETURN_TO_CLIENT_STEP = `Head back to your agent and let it know you're finished.`
const CLOSE_TAB_FOOTER = 'You can close this tab.'
@@ -35,6 +34,7 @@ export function getSecretsCopy(state: SecretsOutcomeState): InterstitialTerminal
calloutBody:
'Ask your agent to store the key again. It will find the saved key and finish without sending you back here.',
footer: UNVERIFIED_KEY_FOOTER,
+ projectRef: state.request.ref,
}
}
@@ -44,6 +44,7 @@ export function getSecretsCopy(state: SecretsOutcomeState): InterstitialTerminal
calloutTitle: 'Next step',
calloutBody: RETURN_TO_CLIENT_STEP,
footer: UNVERIFIED_KEY_FOOTER,
+ projectRef: state.request.ref,
}
}
@@ -54,6 +55,7 @@ export function getSecretsCopy(state: SecretsOutcomeState): InterstitialTerminal
calloutTitle: 'Next step',
calloutBody: RETURN_TO_CLIENT_STEP,
footer: CLOSE_TAB_FOOTER,
+ projectRef: state.request.ref,
}
case 'expired':
diff --git a/apps/studio/components/interfaces/MCP/Secrets/McpSecretsForm.tsx b/apps/studio/components/interfaces/MCP/Secrets/McpSecretsForm.tsx
index 834a506c478..18fc2b19471 100644
--- a/apps/studio/components/interfaces/MCP/Secrets/McpSecretsForm.tsx
+++ b/apps/studio/components/interfaces/MCP/Secrets/McpSecretsForm.tsx
@@ -18,7 +18,7 @@ import { Admonition } from 'ui-patterns/Admonition'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import z from 'zod'
-import { InterstitialShell } from '../InterstitialShell'
+import { InterstitialFooter, InterstitialShell } from '../InterstitialShell'
import type { SecretRequest } from './McpSecrets.types'
import {
getOverwriteWarning,
@@ -163,7 +163,7 @@ export const McpSecretsForm = ({
{providerHint && (
<>
-
+
{`Don't have your key? Create one in the `}
{providerHint.dashboardUrl ? (
+
>
)}
diff --git a/apps/studio/components/interfaces/MCP/Secrets/McpSecretsWrongAccount.tsx b/apps/studio/components/interfaces/MCP/Secrets/McpSecretsWrongAccount.tsx
index 3fec66f87bd..215251db82a 100644
--- a/apps/studio/components/interfaces/MCP/Secrets/McpSecretsWrongAccount.tsx
+++ b/apps/studio/components/interfaces/MCP/Secrets/McpSecretsWrongAccount.tsx
@@ -27,7 +27,7 @@ export const McpSecretsWrongAccount = ({
-
+
After switching, ask your agent to run the tool again. Nothing has been stored.