Skip to content

Commit 89234f9

Browse files
author
Sudarshan
committed
Add Unstructured Transform MCP template
1 parent 65b1ca1 commit 89234f9

3 files changed

Lines changed: 103 additions & 2 deletions

File tree

apps/docs/content/docs/en/agents/mcp.mdx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,19 @@ Authorization: Bearer {{MCP_API_TOKEN}}
7272

7373
When you type `{{` in the URL or header fields, a dropdown appears showing available workspace environment variables.
7474

75+
### Starter Configurations
76+
77+
The add modal includes starter templates for common MCP servers.
78+
79+
For [Unstructured Transform](https://docs.unstructured.io/transform/quickstart), first add a workspace environment variable named `UNSTRUCTURED_API_KEY`, then choose the Unstructured Transform template. It pre-fills:
80+
81+
```
82+
URL: https://mcp.transform.unstructured.io
83+
Authorization: Bearer {{UNSTRUCTURED_API_KEY}}
84+
```
85+
86+
If your self-hosted deployment sets `ALLOWED_MCP_DOMAINS`, include `mcp.transform.unstructured.io` before saving the server.
87+
7588
### Testing and Validation
7689

7790
Click **Test Connection** before saving to verify the server is reachable and discover available tools. The test response shows the number of tools found and the protocol version.
@@ -169,4 +182,4 @@ import { FAQ } from '@/components/ui/faq'
169182
{ question: "How do I update MCP tool schemas after a server changes its available tools?", answer: "Click the Refresh button on the MCP server in your workspace settings. This fetches the latest tool schemas from the server and automatically updates any agent blocks that use those tools with the new parameter definitions." },
170183
{ question: "Can permission groups restrict access to MCP tools?", answer: "Yes. On Enterprise-entitled workspaces, any workspace admin can create a permission group that disables MCP tools for its members using the disableMcpTools option. When this is enabled, affected users will not be able to add or use MCP tools in workflows that belong to that workspace." },
171184
{ question: "What happens if an MCP server goes offline during workflow execution?", answer: "If the MCP server is unreachable during execution, the tool call will fail and return an error. In an Agent block, the AI may attempt to handle the failure gracefully. In a standalone MCP Tool block, the workflow step will fail. Check MCP server logs and verify the server is running and accessible to troubleshoot connectivity issues." },
172-
]} />
185+
]} />

apps/sim/app/workspace/[workspaceId]/settings/components/mcp/components/mcp-server-form-modal/mcp-server-form-modal.tsx

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@ import {
1616
} from '@sim/emcn'
1717
import { createLogger } from '@sim/logger'
1818
import { getErrorMessage } from '@sim/utils/errors'
19-
import { ChevronDown, ChevronRight } from 'lucide-react'
19+
import { ChevronDown, ChevronRight, Plus } from 'lucide-react'
2020
import type { McpAuthType, McpTransport } from '@/lib/mcp/types'
2121
import {
2222
checkEnvVarTrigger,
2323
EnvVarDropdown,
2424
} from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/env-var-dropdown'
2525
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
2626
import { useMcpServerTest } from '@/hooks/queries/mcp'
27+
import {
28+
buildHeadersFromTemplate,
29+
MCP_SERVER_TEMPLATES,
30+
type McpServerTemplate,
31+
} from './mcp-server-templates'
2732

2833
const logger = createLogger('McpServerFormModal')
2934

@@ -300,6 +305,41 @@ function updateHeadersArray(
300305
return updated.filter((h, i) => i === lastIndex || h.key !== '' || h.value !== '')
301306
}
302307

308+
interface TemplatePickerProps {
309+
onSelect: (template: McpServerTemplate) => void
310+
}
311+
312+
function TemplatePicker({ onSelect }: TemplatePickerProps) {
313+
if (MCP_SERVER_TEMPLATES.length === 0) return null
314+
315+
return (
316+
<ChipModalField type='custom' title='Starter templates'>
317+
<div className='flex flex-col gap-2'>
318+
{MCP_SERVER_TEMPLATES.map((template) => (
319+
<button
320+
key={template.id}
321+
type='button'
322+
onClick={() => onSelect(template)}
323+
className='group flex w-full items-center justify-between gap-3 rounded-md border border-[var(--border-1)] bg-[var(--surface-3)] px-2.5 py-2 text-left transition-colors hover-hover:bg-[var(--surface-4)]'
324+
>
325+
<span className='flex min-w-0 flex-col gap-0.5'>
326+
<span className='truncate font-medium text-[var(--text-primary)] text-sm'>
327+
{template.name}
328+
</span>
329+
<span className='line-clamp-2 text-[var(--text-muted)] text-xs leading-relaxed'>
330+
{template.description}
331+
</span>
332+
</span>
333+
<span className='flex size-6 flex-shrink-0 items-center justify-center rounded-md border border-[var(--border-1)] text-[var(--text-muted)] transition-colors group-hover:text-[var(--text-primary)]'>
334+
<Plus className='size-[14px]' />
335+
</span>
336+
</button>
337+
))}
338+
</div>
339+
</ChipModalField>
340+
)
341+
}
342+
303343
export function McpServerFormModal({
304344
open,
305345
onOpenChange,
@@ -415,6 +455,23 @@ export function McpServerFormModal({
415455
resetEnvVarState()
416456
}
417457

458+
const handleTemplateSelect = (template: McpServerTemplate) => {
459+
if (testResult) clearTestResult()
460+
if (submitError) setSubmitError(null)
461+
resetEnvVarState()
462+
setFormMode('form')
463+
setFormData((prev) => ({
464+
...prev,
465+
name: template.name,
466+
transport: template.transport,
467+
url: template.url,
468+
timeout: template.timeout,
469+
headers: buildHeadersFromTemplate(template),
470+
}))
471+
setUrlScrollLeft(0)
472+
setHeaderScrollLeft({})
473+
}
474+
418475
const handleHeaderScroll = (key: string, sl: number) => {
419476
setHeaderScrollLeft((prev) => ({ ...prev, [key]: sl }))
420477
}
@@ -668,6 +725,7 @@ export function McpServerFormModal({
668725
/>
669726
) : (
670727
<>
728+
{mode === 'add' && <TemplatePicker onSelect={handleTemplateSelect} />}
671729
<input
672730
type='text'
673731
name='fakeusernameremembered'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { McpTransport } from '@/lib/mcp/types'
2+
3+
export interface McpServerTemplate {
4+
id: string
5+
name: string
6+
description: string
7+
transport: McpTransport
8+
url: string
9+
headers: readonly {
10+
key: string
11+
value: string
12+
}[]
13+
timeout: number
14+
}
15+
16+
export const MCP_SERVER_TEMPLATES = [
17+
{
18+
id: 'unstructured-transform',
19+
name: 'Unstructured Transform',
20+
description: 'Process PDFs, images, Office files, and other documents through Transform.',
21+
transport: 'streamable-http',
22+
url: 'https://mcp.transform.unstructured.io',
23+
headers: [{ key: 'Authorization', value: 'Bearer {{UNSTRUCTURED_API_KEY}}' }],
24+
timeout: 30000,
25+
},
26+
] as const satisfies readonly McpServerTemplate[]
27+
28+
export function buildHeadersFromTemplate(template: McpServerTemplate) {
29+
return [...template.headers.map((header) => ({ ...header })), { key: '', value: '' }]
30+
}

0 commit comments

Comments
 (0)