mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-07 22:24:06 -05:00
feat(workflow-as-mcp): added ability to deploy workflows as mcp servers and mcp tools (#2415)
* added a workflow as mcp * fixed the issue of UI rendering for deleted mcp servers * fixing lint issues * using mcn components * fixing merge conflicts * fix * fix lint errors * refactored code to use hasstartblock from the tirgger utils * removing unecessary auth * using official mcp sdk and added description fields * using normalised input schema function * ui fixes part 1 * remove migration before merge * fix merge conflicts * remove migration to prep merge * re-add migration * cleanup code to use mcp sdk types * fix discovery calls * add migration * ui improvements * fix lint * fix types * fix lint * fix spacing * remove migration to prep merge * add migration back * fix imports * fix tool refresh ux * fix test failures * fix tests * cleanup code * styling improvements, ability to edit mcp server description, etc * fixed ui in light mode api keys modal * update docs * deprecated unused input components, shifted to emcn * updated playground, simplified components * move images and videos * updated more docs images --------- Co-authored-by: priyanshu.solanki <priyanshu.solanki@saviynt.com> Co-authored-by: Siddharth Ganesan <siddharthganesan@gmail.com> Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai> Co-authored-by: waleed <walif6@gmail.com>
This commit is contained in:
committed by
GitHub
parent
34bc115468
commit
c77268c13d
30
packages/db/migrations/0134_parallel_galactus.sql
Normal file
30
packages/db/migrations/0134_parallel_galactus.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
CREATE TABLE "workflow_mcp_server" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"workspace_id" text NOT NULL,
|
||||
"created_by" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"description" text,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE "workflow_mcp_tool" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"server_id" text NOT NULL,
|
||||
"workflow_id" text NOT NULL,
|
||||
"tool_name" text NOT NULL,
|
||||
"tool_description" text,
|
||||
"parameter_schema" json DEFAULT '{}' NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "workflow_mcp_server" ADD CONSTRAINT "workflow_mcp_server_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "workflow_mcp_server" ADD CONSTRAINT "workflow_mcp_server_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "workflow_mcp_tool" ADD CONSTRAINT "workflow_mcp_tool_server_id_workflow_mcp_server_id_fk" FOREIGN KEY ("server_id") REFERENCES "public"."workflow_mcp_server"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "workflow_mcp_tool" ADD CONSTRAINT "workflow_mcp_tool_workflow_id_workflow_id_fk" FOREIGN KEY ("workflow_id") REFERENCES "public"."workflow"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "workflow_mcp_server_workspace_id_idx" ON "workflow_mcp_server" USING btree ("workspace_id");--> statement-breakpoint
|
||||
CREATE INDEX "workflow_mcp_server_created_by_idx" ON "workflow_mcp_server" USING btree ("created_by");--> statement-breakpoint
|
||||
CREATE INDEX "workflow_mcp_tool_server_id_idx" ON "workflow_mcp_tool" USING btree ("server_id");--> statement-breakpoint
|
||||
CREATE INDEX "workflow_mcp_tool_workflow_id_idx" ON "workflow_mcp_tool" USING btree ("workflow_id");--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "workflow_mcp_tool_server_workflow_unique" ON "workflow_mcp_tool" USING btree ("server_id","workflow_id");
|
||||
8813
packages/db/migrations/meta/0134_snapshot.json
Normal file
8813
packages/db/migrations/meta/0134_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -932,6 +932,13 @@
|
||||
"when": 1766607372265,
|
||||
"tag": "0133_smiling_cargill",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 134,
|
||||
"version": "7",
|
||||
"when": 1766779827389,
|
||||
"tag": "0134_parallel_galactus",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1688,7 +1688,61 @@ export const ssoProvider = pgTable(
|
||||
})
|
||||
)
|
||||
|
||||
// Usage logging for tracking individual billable operations
|
||||
/**
|
||||
* Workflow MCP Servers - User-created MCP servers that expose workflows as tools.
|
||||
* These servers are accessible by external MCP clients via API key authentication.
|
||||
*/
|
||||
export const workflowMcpServer = pgTable(
|
||||
'workflow_mcp_server',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
workspaceId: text('workspace_id')
|
||||
.notNull()
|
||||
.references(() => workspace.id, { onDelete: 'cascade' }),
|
||||
createdBy: text('created_by')
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
name: text('name').notNull(),
|
||||
description: text('description'),
|
||||
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at').notNull().defaultNow(),
|
||||
},
|
||||
(table) => ({
|
||||
workspaceIdIdx: index('workflow_mcp_server_workspace_id_idx').on(table.workspaceId),
|
||||
createdByIdx: index('workflow_mcp_server_created_by_idx').on(table.createdBy),
|
||||
})
|
||||
)
|
||||
|
||||
/**
|
||||
* Workflow MCP Tools - Workflows registered as tools within a Workflow MCP Server.
|
||||
* Each tool maps to a deployed workflow's execute endpoint.
|
||||
*/
|
||||
export const workflowMcpTool = pgTable(
|
||||
'workflow_mcp_tool',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
serverId: text('server_id')
|
||||
.notNull()
|
||||
.references(() => workflowMcpServer.id, { onDelete: 'cascade' }),
|
||||
workflowId: text('workflow_id')
|
||||
.notNull()
|
||||
.references(() => workflow.id, { onDelete: 'cascade' }),
|
||||
toolName: text('tool_name').notNull(),
|
||||
toolDescription: text('tool_description'),
|
||||
parameterSchema: json('parameter_schema').notNull().default('{}'),
|
||||
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||
updatedAt: timestamp('updated_at').notNull().defaultNow(),
|
||||
},
|
||||
(table) => ({
|
||||
serverIdIdx: index('workflow_mcp_tool_server_id_idx').on(table.serverId),
|
||||
workflowIdIdx: index('workflow_mcp_tool_workflow_id_idx').on(table.workflowId),
|
||||
serverWorkflowUnique: uniqueIndex('workflow_mcp_tool_server_workflow_unique').on(
|
||||
table.serverId,
|
||||
table.workflowId
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
export const usageLogCategoryEnum = pgEnum('usage_log_category', ['model', 'fixed'])
|
||||
export const usageLogSourceEnum = pgEnum('usage_log_source', ['workflow', 'wand', 'copilot'])
|
||||
|
||||
@@ -1700,38 +1754,26 @@ export const usageLog = pgTable(
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: 'cascade' }),
|
||||
|
||||
// Charge category: 'model' (token-based) or 'fixed' (flat fee)
|
||||
category: usageLogCategoryEnum('category').notNull(),
|
||||
|
||||
// What generated this charge: 'workflow', 'wand', 'copilot'
|
||||
source: usageLogSourceEnum('source').notNull(),
|
||||
|
||||
// For model charges: model name (e.g., 'gpt-4o', 'claude-4.5-opus')
|
||||
// For fixed charges: charge type (e.g., 'execution_fee', 'search_query')
|
||||
description: text('description').notNull(),
|
||||
|
||||
// Category-specific metadata (e.g., tokens for 'model' category)
|
||||
metadata: jsonb('metadata'),
|
||||
|
||||
// Cost in USD
|
||||
cost: decimal('cost').notNull(),
|
||||
|
||||
// Optional context references
|
||||
workspaceId: text('workspace_id').references(() => workspace.id, { onDelete: 'set null' }),
|
||||
workflowId: text('workflow_id').references(() => workflow.id, { onDelete: 'set null' }),
|
||||
executionId: text('execution_id'),
|
||||
|
||||
// Timestamp
|
||||
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||
},
|
||||
(table) => ({
|
||||
// Index for querying user's usage history (most common query)
|
||||
userCreatedAtIdx: index('usage_log_user_created_at_idx').on(table.userId, table.createdAt),
|
||||
// Index for filtering by source
|
||||
sourceIdx: index('usage_log_source_idx').on(table.source),
|
||||
// Index for workspace-specific queries
|
||||
workspaceIdIdx: index('usage_log_workspace_id_idx').on(table.workspaceId),
|
||||
// Index for workflow-specific queries
|
||||
workflowIdIdx: index('usage_log_workflow_id_idx').on(table.workflowId),
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user