Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
9321743
added a workflow as mcp
Dec 17, 2025
a15ac73
fixed the issue of UI rendering for deleted mcp servers
Dec 17, 2025
57f3697
fixing lint issues
Dec 17, 2025
85af046
using mcn components
Dec 17, 2025
2259bfc
fixing merge conflicts
Dec 18, 2025
1f22d7a
fix
Dec 18, 2025
cfbe4a4
fix lint errors
Dec 18, 2025
f2450d3
refactored code to use hasstartblock from the tirgger utils
Dec 18, 2025
896e967
removing unecessary auth
Dec 18, 2025
6c10f31
using official mcp sdk and added description fields
Dec 18, 2025
fe4f895
using normalised input schema function
Dec 18, 2025
9743a2f
Merge branch 'staging' into feat/workflow-as-mcp
Dec 18, 2025
4bb9a8d
ui fixes part 1
Sg312 Dec 19, 2025
b94c716
remove migration before merge
icecrasher321 Dec 20, 2025
e48aab1
Merge branch 'staging' into feat/workflow-as-mcp
icecrasher321 Dec 20, 2025
6771195
fix merge conflicts
icecrasher321 Dec 20, 2025
8b4f2a0
remove migration to prep merge
icecrasher321 Dec 21, 2025
a40243f
Merge branch 'staging' into feat/workflow-as-mcp
icecrasher321 Dec 21, 2025
e90fdb4
re-add migration
icecrasher321 Dec 21, 2025
cfdbcee
cleanup code to use mcp sdk types
icecrasher321 Dec 21, 2025
6856b26
fix discovery calls
icecrasher321 Dec 21, 2025
46f6383
Merge branch 'staging' into feat/workflow-as-mcp
icecrasher321 Dec 21, 2025
8489dd5
add migration
icecrasher321 Dec 21, 2025
da144ab
ui improvements
icecrasher321 Dec 21, 2025
b2153cd
fix lint
icecrasher321 Dec 21, 2025
ab44c11
fix types
icecrasher321 Dec 21, 2025
6dac845
fix lint
icecrasher321 Dec 21, 2025
24d58ea
fix spacing
icecrasher321 Dec 21, 2025
feacd08
remove migration to prep merge
icecrasher321 Dec 26, 2025
90e0b93
Merge branch 'staging' into feat/workflow-as-mcp
icecrasher321 Dec 26, 2025
fe3ed9f
add migration back
icecrasher321 Dec 26, 2025
c50b067
Merge branch 'staging' into feat/workflow-as-mcp
icecrasher321 Dec 26, 2025
fc77143
fix imports
icecrasher321 Dec 26, 2025
1998efa
Merge staging into feat/workflow-as-mcp
icecrasher321 Dec 27, 2025
1c97aab
Merge staging into feat/workflow-as-mcp
icecrasher321 Dec 29, 2025
404b46f
fix tool refresh ux
icecrasher321 Dec 29, 2025
08909ec
fix test failures
icecrasher321 Dec 29, 2025
216fb42
fix tests
icecrasher321 Dec 29, 2025
0346aac
cleanup code
icecrasher321 Dec 30, 2025
d6a0036
styling improvements, ability to edit mcp server description, etc
waleedlatif1 Dec 30, 2025
599a5db
fixed ui in light mode api keys modal
waleedlatif1 Dec 30, 2025
0badbdd
update docs
icecrasher321 Dec 30, 2025
725cdac
Merge branch 'feat/workflow-as-mcp' of github.com:simstudioai/sim int…
icecrasher321 Dec 30, 2025
6b6b57b
deprecated unused input components, shifted to emcn
waleedlatif1 Dec 30, 2025
62bc844
updated playground, simplified components
waleedlatif1 Dec 31, 2025
ae74f83
Merge branch 'staging' into feat/workflow-as-mcp
waleedlatif1 Dec 31, 2025
6a5ffa2
move images and videos
waleedlatif1 Dec 31, 2025
98b9845
updated more docs images
waleedlatif1 Dec 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions apps/docs/content/docs/en/mcp/deploy-workflows.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
title: Deploy Workflows as MCP
description: Expose your workflows as MCP tools for external AI assistants and applications
---

import { Video } from '@/components/ui/video'
import { Callout } from 'fumadocs-ui/components/callout'

Deploy your workflows as MCP tools to make them accessible to external AI assistants like Claude Desktop, Cursor, and other MCP-compatible clients. This turns your workflows into callable tools that can be invoked from anywhere.

## Creating and Managing MCP Servers

MCP servers group your workflow tools together. Create and manage them in workspace settings:

<div className="mx-auto w-full overflow-hidden rounded-lg">
<Video src="mcp/mcp-server.mp4" width={700} height={450} />
</div>

1. Navigate to **Settings → MCP Servers**
2. Click **Create Server**
3. Enter a name and optional description
4. Copy the server URL for use in your MCP clients
5. View and manage all tools added to the server

## Adding a Workflow as a Tool

Once your workflow is deployed, you can expose it as an MCP tool:

<div className="mx-auto w-full overflow-hidden rounded-lg">
<Video src="mcp/mcp-deploy-tool.mp4" width={700} height={450} />
</div>

1. Open your deployed workflow
2. Click **Deploy** and go to the **MCP** tab
3. Configure the tool name and description
4. Add descriptions for each parameter (helps AI understand inputs)
5. Select which MCP servers to add it to

<Callout type="info">
The workflow must be deployed before it can be added as an MCP tool.
</Callout>

## Tool Configuration

### Tool Name
Use lowercase letters, numbers, and underscores. The name should be descriptive and follow MCP naming conventions (e.g., `search_documents`, `send_email`).

### Description
Write a clear description of what the tool does. This helps AI assistants understand when to use the tool.

### Parameters
Your workflow's input format fields become tool parameters. Add descriptions to each parameter to help AI assistants provide correct values.

## Connecting MCP Clients

Use the server URL from settings to connect external applications:

### Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
"mcpServers": {
"my-sim-workflows": {
"command": "npx",
"args": ["-y", "mcp-remote", "YOUR_SERVER_URL"]
}
}
}
```

### Cursor
Add the server URL in Cursor's MCP settings using the same mcp-remote pattern.

<Callout type="warn">
Include your API key header (`X-API-Key`) for authenticated access when using mcp-remote or other HTTP-based MCP transports.
</Callout>

## Server Management

From the server detail view in **Settings → MCP Servers**, you can:

- **View tools**: See all workflows added to a server
- **Copy URL**: Get the server URL for MCP clients
- **Add workflows**: Add more deployed workflows as tools
- **Remove tools**: Remove workflows from the server
- **Delete server**: Remove the entire server and all its tools

## How It Works

When an MCP client calls your tool:

1. The request is received at your MCP server URL
2. Sim validates the request and maps parameters to workflow inputs
3. The deployed workflow executes with the provided inputs
4. Results are returned to the MCP client

Workflows execute using the same deployment version as API calls, ensuring consistent behavior.

## Permission Requirements

| Action | Required Permission |
|--------|-------------------|
| Create MCP servers | **Admin** |
| Add workflows to servers | **Write** or **Admin** |
| View MCP servers | **Read**, **Write**, or **Admin** |
| Delete MCP servers | **Admin** |

18 changes: 9 additions & 9 deletions apps/docs/content/docs/en/mcp/index.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
title: MCP (Model Context Protocol)
title: Using MCP Tools
description: Connect external tools and services using the Model Context Protocol
---

import { Image } from '@/components/ui/image'
import { Video } from '@/components/ui/video'
import { Callout } from 'fumadocs-ui/components/callout'

The Model Context Protocol ([MCP](https://modelcontextprotocol.com/)) allows you to connect external tools and services using a standardized protocol, enabling you to integrate APIs and services directly into your workflows. With MCP, you can extend Sim's capabilities by adding custom integrations that work seamlessly with your agents and workflows.
Expand All @@ -20,14 +22,8 @@ MCP is an open standard that enables AI assistants to securely connect to extern

MCP servers provide collections of tools that your agents can use. Configure them in workspace settings:

<div className="flex justify-center">
<Image
src="/static/blocks/mcp-1.png"
alt="Configuring MCP Server in Settings"
width={700}
height={450}
className="my-6"
/>
<div className="mx-auto w-full overflow-hidden rounded-lg">
<Video src="mcp/settings-mcp-tools.mp4" width={700} height={450} />
</div>

1. Navigate to your workspace settings
Expand All @@ -40,6 +36,10 @@ MCP servers provide collections of tools that your agents can use. Configure the
You can also configure MCP servers directly from the toolbar in an Agent block for quick setup.
</Callout>

### Refresh Tools

Click **Refresh** on a server to fetch the latest tool schemas and automatically update any agent blocks using those tools with the new parameter definitions.

## Using MCP Tools in Agents

Once MCP servers are configured, their tools become available within your agent blocks:
Expand Down
5 changes: 5 additions & 0 deletions apps/docs/content/docs/en/mcp/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "MCP",
"pages": ["index", "deploy-workflows"],
"defaultOpen": false
}
Binary file modified apps/docs/public/static/blocks/triggers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/docs/public/static/environment/environment-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/docs/public/static/environment/environment-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/docs/public/static/environment/environment-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/docs/public/static/knowledgebase/knowledgebase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/sim/app/(landing)/careers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useRef, useState } from 'react'
import { createLogger } from '@sim/logger'
import { X } from 'lucide-react'
import { Textarea } from '@/components/emcn'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
Expand All @@ -13,7 +14,6 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import { isHosted } from '@/lib/core/config/feature-flags'
import { cn } from '@/lib/core/utils/cn'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/(landing)/studio/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Metadata } from 'next'
import Image from 'next/image'
import Link from 'next/link'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/emcn'
import { FAQ } from '@/lib/blog/faq'
import { getAllPostMeta, getPostBySlug, getRelatedPosts } from '@/lib/blog/registry'
import { buildArticleJsonLd, buildBreadcrumbJsonLd, buildPostMetadata } from '@/lib/blog/seo'
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/(landing)/studio/post-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Image from 'next/image'
import Link from 'next/link'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/emcn'

interface Author {
id: string
Expand Down
88 changes: 88 additions & 0 deletions apps/sim/app/api/mcp/discover/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { db } from '@sim/db'
import { permissions, workflowMcpServer, workspace } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { getBaseUrl } from '@/lib/core/utils/urls'

const logger = createLogger('McpDiscoverAPI')

export const dynamic = 'force-dynamic'

/**
* Discover all MCP servers available to the authenticated user.
*/
export async function GET(request: NextRequest) {
try {
const auth = await checkHybridAuth(request, { requireWorkflowId: false })

if (!auth.success || !auth.userId) {
return NextResponse.json(
{ success: false, error: 'Authentication required. Provide X-API-Key header.' },
{ status: 401 }
)
}

const userId = auth.userId

const userWorkspacePermissions = await db
.select({ entityId: permissions.entityId })
.from(permissions)
.where(and(eq(permissions.userId, userId), eq(permissions.entityType, 'workspace')))

const workspaceIds = userWorkspacePermissions.map((w) => w.entityId)

if (workspaceIds.length === 0) {
return NextResponse.json({ success: true, servers: [] })
}

const servers = await db
.select({
id: workflowMcpServer.id,
name: workflowMcpServer.name,
description: workflowMcpServer.description,
workspaceId: workflowMcpServer.workspaceId,
workspaceName: workspace.name,
createdAt: workflowMcpServer.createdAt,
toolCount: sql<number>`(
SELECT COUNT(*)::int
FROM "workflow_mcp_tool"
WHERE "workflow_mcp_tool"."server_id" = "workflow_mcp_server"."id"
)`.as('tool_count'),
})
.from(workflowMcpServer)
.leftJoin(workspace, eq(workflowMcpServer.workspaceId, workspace.id))
.where(sql`${workflowMcpServer.workspaceId} IN ${workspaceIds}`)
.orderBy(workflowMcpServer.name)

const baseUrl = getBaseUrl()

const formattedServers = servers.map((server) => ({
id: server.id,
name: server.name,
description: server.description,
workspace: { id: server.workspaceId, name: server.workspaceName },
toolCount: server.toolCount || 0,
createdAt: server.createdAt,
url: `${baseUrl}/api/mcp/serve/${server.id}`,
}))

logger.info(`User ${userId} discovered ${formattedServers.length} MCP servers`)

return NextResponse.json({
success: true,
servers: formattedServers,
authentication: {
method: 'API Key',
header: 'X-API-Key',
},
})
} catch (error) {
logger.error('Error discovering MCP servers:', error)
return NextResponse.json(
{ success: false, error: 'Failed to discover MCP servers' },
{ status: 500 }
)
}
}
Loading