mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-11 15:14:53 -05:00
improvement(mcp): improved mcp sse events notifs, update jira to handle files, fix UI issues in settings modal, fix org and workspace invitations when bundled (#3182)
* improvement(mcp): improved mcp sse events notifs, update jira to handle files, fix UI issues in settings modal, fix org and workspace invitations when bundled * added back useMcpToolsEvents for event-driven discovery * ack PR comments * updated placeholder * updated colors, error throwing in mcp modal * ack comments * updated error msg
This commit is contained in:
@@ -6,6 +6,7 @@ import type { NextRequest } from 'next/server'
|
||||
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
|
||||
import { mcpPubSub } from '@/lib/mcp/pubsub'
|
||||
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
|
||||
import { generateParameterSchemaForWorkflow } from '@/lib/mcp/workflow-mcp-sync'
|
||||
import { sanitizeToolName } from '@/lib/mcp/workflow-tool-schema'
|
||||
import { hasValidStartBlock } from '@/lib/workflows/triggers/trigger-utils.server'
|
||||
|
||||
@@ -170,6 +171,11 @@ export const POST = withMcpAuth<RouteParams>('write')(
|
||||
workflowRecord.description ||
|
||||
`Execute ${workflowRecord.name} workflow`
|
||||
|
||||
const parameterSchema =
|
||||
body.parameterSchema && Object.keys(body.parameterSchema).length > 0
|
||||
? body.parameterSchema
|
||||
: await generateParameterSchemaForWorkflow(body.workflowId)
|
||||
|
||||
const toolId = crypto.randomUUID()
|
||||
const [tool] = await db
|
||||
.insert(workflowMcpTool)
|
||||
@@ -179,7 +185,7 @@ export const POST = withMcpAuth<RouteParams>('write')(
|
||||
workflowId: body.workflowId,
|
||||
toolName,
|
||||
toolDescription,
|
||||
parameterSchema: body.parameterSchema || {},
|
||||
parameterSchema,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { NextRequest } from 'next/server'
|
||||
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
|
||||
import { mcpPubSub } from '@/lib/mcp/pubsub'
|
||||
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
|
||||
import { generateParameterSchemaForWorkflow } from '@/lib/mcp/workflow-mcp-sync'
|
||||
import { sanitizeToolName } from '@/lib/mcp/workflow-tool-schema'
|
||||
import { hasValidStartBlock } from '@/lib/workflows/triggers/trigger-utils.server'
|
||||
|
||||
@@ -156,6 +157,8 @@ export const POST = withMcpAuth('write')(
|
||||
const toolDescription =
|
||||
workflowRecord.description || `Execute ${workflowRecord.name} workflow`
|
||||
|
||||
const parameterSchema = await generateParameterSchemaForWorkflow(workflowRecord.id)
|
||||
|
||||
const toolId = crypto.randomUUID()
|
||||
await db.insert(workflowMcpTool).values({
|
||||
id: toolId,
|
||||
@@ -163,7 +166,7 @@ export const POST = withMcpAuth('write')(
|
||||
workflowId: workflowRecord.id,
|
||||
toolName,
|
||||
toolDescription,
|
||||
parameterSchema: {},
|
||||
parameterSchema,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
|
||||
@@ -446,15 +446,46 @@ export async function PUT(
|
||||
})
|
||||
.where(eq(workspaceInvitation.id, wsInvitation.id))
|
||||
|
||||
await tx.insert(permissions).values({
|
||||
id: randomUUID(),
|
||||
entityType: 'workspace',
|
||||
entityId: wsInvitation.workspaceId,
|
||||
userId: session.user.id,
|
||||
permissionType: wsInvitation.permissions || 'read',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
const existingPermission = await tx
|
||||
.select({ id: permissions.id, permissionType: permissions.permissionType })
|
||||
.from(permissions)
|
||||
.where(
|
||||
and(
|
||||
eq(permissions.entityId, wsInvitation.workspaceId),
|
||||
eq(permissions.entityType, 'workspace'),
|
||||
eq(permissions.userId, session.user.id)
|
||||
)
|
||||
)
|
||||
.then((rows) => rows[0])
|
||||
|
||||
if (existingPermission) {
|
||||
const PERMISSION_RANK = { read: 0, write: 1, admin: 2 } as const
|
||||
type PermissionLevel = keyof typeof PERMISSION_RANK
|
||||
const existingRank =
|
||||
PERMISSION_RANK[existingPermission.permissionType as PermissionLevel] ?? 0
|
||||
const newPermission = (wsInvitation.permissions || 'read') as PermissionLevel
|
||||
const newRank = PERMISSION_RANK[newPermission] ?? 0
|
||||
|
||||
if (newRank > existingRank) {
|
||||
await tx
|
||||
.update(permissions)
|
||||
.set({
|
||||
permissionType: newPermission,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(permissions.id, existingPermission.id))
|
||||
}
|
||||
} else {
|
||||
await tx.insert(permissions).values({
|
||||
id: randomUUID(),
|
||||
entityType: 'workspace',
|
||||
entityId: wsInvitation.workspaceId,
|
||||
userId: session.user.id,
|
||||
permissionType: wsInvitation.permissions || 'read',
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if (status === 'cancelled') {
|
||||
await tx
|
||||
|
||||
@@ -47,16 +47,9 @@ export async function POST(request: NextRequest) {
|
||||
(await getJiraCloudId(validatedData.domain, validatedData.accessToken))
|
||||
|
||||
const formData = new FormData()
|
||||
const filesOutput: Array<{ name: string; mimeType: string; data: string; size: number }> = []
|
||||
|
||||
for (const file of userFiles) {
|
||||
const buffer = await downloadFileFromStorage(file, requestId, logger)
|
||||
filesOutput.push({
|
||||
name: file.name,
|
||||
mimeType: file.type || 'application/octet-stream',
|
||||
data: buffer.toString('base64'),
|
||||
size: buffer.length,
|
||||
})
|
||||
const blob = new Blob([new Uint8Array(buffer)], {
|
||||
type: file.type || 'application/octet-stream',
|
||||
})
|
||||
@@ -109,7 +102,7 @@ export async function POST(request: NextRequest) {
|
||||
issueKey: validatedData.issueKey,
|
||||
attachments,
|
||||
attachmentIds,
|
||||
files: filesOutput,
|
||||
files: userFiles,
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user