Skip to content

Commit 6d16f21

Browse files
authored
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
1 parent f8e9614 commit 6d16f21

File tree

48 files changed

+1097
-365
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1097
-365
lines changed

apps/docs/content/docs/en/tools/jira.mdx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Retrieve detailed information about a specific Jira issue
4444
| --------- | ---- | -------- | ----------- |
4545
| `domain` | string | Yes | Your Jira domain \(e.g., yourcompany.atlassian.net\) |
4646
| `issueKey` | string | Yes | Jira issue key to retrieve \(e.g., PROJ-123\) |
47+
| `includeAttachments` | boolean | No | Download attachment file contents and include them as files in the output |
4748
| `cloudId` | string | No | Jira Cloud ID for the instance. If not provided, it will be fetched using the domain. |
4849

4950
#### Output
@@ -65,6 +66,7 @@ Retrieve detailed information about a specific Jira issue
6566
|`key` | string | Status category key \(e.g., new, indeterminate, done\) |
6667
|`name` | string | Status category name \(e.g., To Do, In Progress, Done\) |
6768
|`colorName` | string | Status category color \(e.g., blue-gray, yellow, green\) |
69+
| `statusName` | string | Issue status name \(e.g., Open, In Progress, Done\) |
6870
| `issuetype` | object | Issue type |
6971
|`id` | string | Issue type ID |
7072
|`name` | string | Issue type name \(e.g., Task, Bug, Story, Epic\) |
@@ -88,6 +90,7 @@ Retrieve detailed information about a specific Jira issue
8890
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
8991
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
9092
|`timeZone` | string | User timezone |
93+
| `assigneeName` | string | Assignee display name or account ID |
9194
| `reporter` | object | Reporter user |
9295
|`accountId` | string | Atlassian account ID of the user |
9396
|`displayName` | string | Display name of the user |
@@ -173,6 +176,7 @@ Retrieve detailed information about a specific Jira issue
173176
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
174177
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
175178
|`timeZone` | string | User timezone |
179+
|`authorName` | string | Comment author display name |
176180
|`updateAuthor` | object | User who last updated the comment |
177181
|`accountId` | string | Atlassian account ID of the user |
178182
|`displayName` | string | Display name of the user |
@@ -196,6 +200,7 @@ Retrieve detailed information about a specific Jira issue
196200
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
197201
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
198202
|`timeZone` | string | User timezone |
203+
|`authorName` | string | Worklog author display name |
199204
|`updateAuthor` | object | User who last updated the worklog |
200205
|`accountId` | string | Atlassian account ID of the user |
201206
|`displayName` | string | Display name of the user |
@@ -225,9 +230,11 @@ Retrieve detailed information about a specific Jira issue
225230
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
226231
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
227232
|`timeZone` | string | User timezone |
233+
|`authorName` | string | Attachment author display name |
228234
|`created` | string | ISO 8601 timestamp when the attachment was created |
229235
| `issueKey` | string | Issue key \(e.g., PROJ-123\) |
230236
| `issue` | json | Complete raw Jira issue object from the API |
237+
| `files` | file[] | Downloaded attachment files \(only when includeAttachments is true\) |
231238

232239
### `jira_update`
233240

@@ -258,6 +265,7 @@ Update a Jira issue
258265
| Parameter | Type | Description |
259266
| --------- | ---- | ----------- |
260267
| `ts` | string | ISO 8601 timestamp of the operation |
268+
| `success` | boolean | Operation success status |
261269
| `issueKey` | string | Updated issue key \(e.g., PROJ-123\) |
262270
| `summary` | string | Issue summary after update |
263271

@@ -296,6 +304,7 @@ Create a new Jira issue
296304
| `issueKey` | string | Created issue key \(e.g., PROJ-123\) |
297305
| `self` | string | REST API URL for the created issue |
298306
| `summary` | string | Issue summary |
307+
| `success` | boolean | Whether the issue was created successfully |
299308
| `url` | string | URL to the created issue in Jira |
300309
| `assigneeId` | string | Account ID of the assigned user \(null if no assignee was set\) |
301310

@@ -358,6 +367,7 @@ Delete a Jira issue
358367
| Parameter | Type | Description |
359368
| --------- | ---- | ----------- |
360369
| `ts` | string | ISO 8601 timestamp of the operation |
370+
| `success` | boolean | Operation success status |
361371
| `issueKey` | string | Deleted issue key |
362372

363373
### `jira_assign_issue`
@@ -378,6 +388,7 @@ Assign a Jira issue to a user
378388
| Parameter | Type | Description |
379389
| --------- | ---- | ----------- |
380390
| `ts` | string | ISO 8601 timestamp of the operation |
391+
| `success` | boolean | Operation success status |
381392
| `issueKey` | string | Issue key that was assigned |
382393
| `assigneeId` | string | Account ID of the assignee \(use "-1" for auto-assign, null to unassign\) |
383394

@@ -401,6 +412,7 @@ Move a Jira issue between workflow statuses (e.g., To Do -> In Progress)
401412
| Parameter | Type | Description |
402413
| --------- | ---- | ----------- |
403414
| `ts` | string | ISO 8601 timestamp of the operation |
415+
| `success` | boolean | Operation success status |
404416
| `issueKey` | string | Issue key that was transitioned |
405417
| `transitionId` | string | Applied transition ID |
406418
| `transitionName` | string | Applied transition name |
@@ -443,6 +455,7 @@ Search for Jira issues using JQL (Jira Query Language)
443455
|`key` | string | Status category key \(e.g., new, indeterminate, done\) |
444456
|`name` | string | Status category name \(e.g., To Do, In Progress, Done\) |
445457
|`colorName` | string | Status category color \(e.g., blue-gray, yellow, green\) |
458+
|`statusName` | string | Issue status name \(e.g., Open, In Progress, Done\) |
446459
|`issuetype` | object | Issue type |
447460
|`id` | string | Issue type ID |
448461
|`name` | string | Issue type name \(e.g., Task, Bug, Story, Epic\) |
@@ -466,6 +479,7 @@ Search for Jira issues using JQL (Jira Query Language)
466479
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
467480
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
468481
|`timeZone` | string | User timezone |
482+
|`assigneeName` | string | Assignee display name or account ID |
469483
|`reporter` | object | Reporter user |
470484
|`accountId` | string | Atlassian account ID of the user |
471485
|`displayName` | string | Display name of the user |
@@ -509,6 +523,7 @@ Add a comment to a Jira issue
509523
| Parameter | Type | Description |
510524
| --------- | ---- | ----------- |
511525
| `ts` | string | ISO 8601 timestamp of the operation |
526+
| `success` | boolean | Operation success status |
512527
| `issueKey` | string | Issue key the comment was added to |
513528
| `commentId` | string | Created comment ID |
514529
| `body` | string | Comment text content |
@@ -558,6 +573,7 @@ Get all comments from a Jira issue
558573
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
559574
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
560575
|`timeZone` | string | User timezone |
576+
|`authorName` | string | Comment author display name |
561577
|`updateAuthor` | object | User who last updated the comment |
562578
|`accountId` | string | Atlassian account ID of the user |
563579
|`displayName` | string | Display name of the user |
@@ -592,6 +608,7 @@ Update an existing comment on a Jira issue
592608
| Parameter | Type | Description |
593609
| --------- | ---- | ----------- |
594610
| `ts` | string | ISO 8601 timestamp of the operation |
611+
| `success` | boolean | Operation success status |
595612
| `issueKey` | string | Issue key |
596613
| `commentId` | string | Updated comment ID |
597614
| `body` | string | Updated comment text |
@@ -624,6 +641,7 @@ Delete a comment from a Jira issue
624641
| Parameter | Type | Description |
625642
| --------- | ---- | ----------- |
626643
| `ts` | string | ISO 8601 timestamp of the operation |
644+
| `success` | boolean | Operation success status |
627645
| `issueKey` | string | Issue key |
628646
| `commentId` | string | Deleted comment ID |
629647

@@ -637,6 +655,7 @@ Get all attachments from a Jira issue
637655
| --------- | ---- | -------- | ----------- |
638656
| `domain` | string | Yes | Your Jira domain \(e.g., yourcompany.atlassian.net\) |
639657
| `issueKey` | string | Yes | Jira issue key to get attachments from \(e.g., PROJ-123\) |
658+
| `includeAttachments` | boolean | No | Download attachment file contents and include them as files in the output |
640659
| `cloudId` | string | No | Jira Cloud ID for the instance. If not provided, it will be fetched using the domain. |
641660

642661
#### Output
@@ -660,7 +679,9 @@ Get all attachments from a Jira issue
660679
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
661680
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
662681
|`timeZone` | string | User timezone |
682+
|`authorName` | string | Attachment author display name |
663683
|`created` | string | ISO 8601 timestamp when the attachment was created |
684+
| `files` | file[] | Downloaded attachment files \(only when includeAttachments is true\) |
664685

665686
### `jira_add_attachment`
666687

@@ -688,10 +709,7 @@ Add attachments to a Jira issue
688709
|`size` | number | File size in bytes |
689710
|`content` | string | URL to download the attachment |
690711
| `attachmentIds` | array | Array of attachment IDs |
691-
| `files` | array | Uploaded file metadata |
692-
|`name` | string | File name |
693-
|`mimeType` | string | MIME type |
694-
|`size` | number | File size in bytes |
712+
| `files` | file[] | Uploaded attachment files |
695713

696714
### `jira_delete_attachment`
697715

@@ -710,6 +728,7 @@ Delete an attachment from a Jira issue
710728
| Parameter | Type | Description |
711729
| --------- | ---- | ----------- |
712730
| `ts` | string | ISO 8601 timestamp of the operation |
731+
| `success` | boolean | Operation success status |
713732
| `attachmentId` | string | Deleted attachment ID |
714733

715734
### `jira_add_worklog`
@@ -733,6 +752,7 @@ Add a time tracking worklog entry to a Jira issue
733752
| Parameter | Type | Description |
734753
| --------- | ---- | ----------- |
735754
| `ts` | string | ISO 8601 timestamp of the operation |
755+
| `success` | boolean | Operation success status |
736756
| `issueKey` | string | Issue key the worklog was added to |
737757
| `worklogId` | string | Created worklog ID |
738758
| `timeSpent` | string | Time spent in human-readable format \(e.g., 3h 20m\) |
@@ -781,6 +801,7 @@ Get all worklog entries from a Jira issue
781801
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
782802
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
783803
|`timeZone` | string | User timezone |
804+
|`authorName` | string | Worklog author display name |
784805
|`updateAuthor` | object | User who last updated the worklog |
785806
|`accountId` | string | Atlassian account ID of the user |
786807
|`displayName` | string | Display name of the user |
@@ -818,6 +839,7 @@ Update an existing worklog entry on a Jira issue
818839
| Parameter | Type | Description |
819840
| --------- | ---- | ----------- |
820841
| `ts` | string | ISO 8601 timestamp of the operation |
842+
| `success` | boolean | Operation success status |
821843
| `issueKey` | string | Issue key |
822844
| `worklogId` | string | Updated worklog ID |
823845
| `timeSpent` | string | Human-readable time spent \(e.g., "3h 20m"\) |
@@ -861,6 +883,7 @@ Delete a worklog entry from a Jira issue
861883
| Parameter | Type | Description |
862884
| --------- | ---- | ----------- |
863885
| `ts` | string | ISO 8601 timestamp of the operation |
886+
| `success` | boolean | Operation success status |
864887
| `issueKey` | string | Issue key |
865888
| `worklogId` | string | Deleted worklog ID |
866889

@@ -884,6 +907,7 @@ Create a link relationship between two Jira issues
884907
| Parameter | Type | Description |
885908
| --------- | ---- | ----------- |
886909
| `ts` | string | ISO 8601 timestamp of the operation |
910+
| `success` | boolean | Operation success status |
887911
| `inwardIssue` | string | Inward issue key |
888912
| `outwardIssue` | string | Outward issue key |
889913
| `linkType` | string | Type of issue link |
@@ -906,6 +930,7 @@ Delete a link between two Jira issues
906930
| Parameter | Type | Description |
907931
| --------- | ---- | ----------- |
908932
| `ts` | string | ISO 8601 timestamp of the operation |
933+
| `success` | boolean | Operation success status |
909934
| `linkId` | string | Deleted link ID |
910935

911936
### `jira_add_watcher`
@@ -926,6 +951,7 @@ Add a watcher to a Jira issue to receive notifications about updates
926951
| Parameter | Type | Description |
927952
| --------- | ---- | ----------- |
928953
| `ts` | string | ISO 8601 timestamp of the operation |
954+
| `success` | boolean | Operation success status |
929955
| `issueKey` | string | Issue key |
930956
| `watcherAccountId` | string | Added watcher account ID |
931957

@@ -947,6 +973,7 @@ Remove a watcher from a Jira issue
947973
| Parameter | Type | Description |
948974
| --------- | ---- | ----------- |
949975
| `ts` | string | ISO 8601 timestamp of the operation |
976+
| `success` | boolean | Operation success status |
950977
| `issueKey` | string | Issue key |
951978
| `watcherAccountId` | string | Removed watcher account ID |
952979

@@ -977,6 +1004,8 @@ Get Jira users. If an account ID is provided, returns a single user. Otherwise,
9771004
|`accountType` | string | Type of account \(e.g., atlassian, app, customer\) |
9781005
|`avatarUrl` | string | URL to the user avatar \(48x48\) |
9791006
|`timeZone` | string | User timezone |
1007+
|`avatarUrls` | json | User avatar URLs in multiple sizes \(16x16, 24x24, 32x32, 48x48\) |
1008+
|`self` | string | REST API URL for this user |
9801009
| `total` | number | Total number of users returned |
9811010
| `startAt` | number | Pagination start index |
9821011
| `maxResults` | number | Maximum results per page |

apps/sim/app/api/mcp/workflow-servers/[id]/tools/route.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { NextRequest } from 'next/server'
66
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
77
import { mcpPubSub } from '@/lib/mcp/pubsub'
88
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
9+
import { generateParameterSchemaForWorkflow } from '@/lib/mcp/workflow-mcp-sync'
910
import { sanitizeToolName } from '@/lib/mcp/workflow-tool-schema'
1011
import { hasValidStartBlock } from '@/lib/workflows/triggers/trigger-utils.server'
1112

@@ -170,6 +171,11 @@ export const POST = withMcpAuth<RouteParams>('write')(
170171
workflowRecord.description ||
171172
`Execute ${workflowRecord.name} workflow`
172173

174+
const parameterSchema =
175+
body.parameterSchema && Object.keys(body.parameterSchema).length > 0
176+
? body.parameterSchema
177+
: await generateParameterSchemaForWorkflow(body.workflowId)
178+
173179
const toolId = crypto.randomUUID()
174180
const [tool] = await db
175181
.insert(workflowMcpTool)
@@ -179,7 +185,7 @@ export const POST = withMcpAuth<RouteParams>('write')(
179185
workflowId: body.workflowId,
180186
toolName,
181187
toolDescription,
182-
parameterSchema: body.parameterSchema || {},
188+
parameterSchema,
183189
createdAt: new Date(),
184190
updatedAt: new Date(),
185191
})

apps/sim/app/api/mcp/workflow-servers/route.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { NextRequest } from 'next/server'
66
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
77
import { mcpPubSub } from '@/lib/mcp/pubsub'
88
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
9+
import { generateParameterSchemaForWorkflow } from '@/lib/mcp/workflow-mcp-sync'
910
import { sanitizeToolName } from '@/lib/mcp/workflow-tool-schema'
1011
import { hasValidStartBlock } from '@/lib/workflows/triggers/trigger-utils.server'
1112

@@ -156,14 +157,16 @@ export const POST = withMcpAuth('write')(
156157
const toolDescription =
157158
workflowRecord.description || `Execute ${workflowRecord.name} workflow`
158159

160+
const parameterSchema = await generateParameterSchemaForWorkflow(workflowRecord.id)
161+
159162
const toolId = crypto.randomUUID()
160163
await db.insert(workflowMcpTool).values({
161164
id: toolId,
162165
serverId,
163166
workflowId: workflowRecord.id,
164167
toolName,
165168
toolDescription,
166-
parameterSchema: {},
169+
parameterSchema,
167170
createdAt: new Date(),
168171
updatedAt: new Date(),
169172
})

apps/sim/app/api/organizations/[id]/invitations/[invitationId]/route.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,46 @@ export async function PUT(
446446
})
447447
.where(eq(workspaceInvitation.id, wsInvitation.id))
448448

449-
await tx.insert(permissions).values({
450-
id: randomUUID(),
451-
entityType: 'workspace',
452-
entityId: wsInvitation.workspaceId,
453-
userId: session.user.id,
454-
permissionType: wsInvitation.permissions || 'read',
455-
createdAt: new Date(),
456-
updatedAt: new Date(),
457-
})
449+
const existingPermission = await tx
450+
.select({ id: permissions.id, permissionType: permissions.permissionType })
451+
.from(permissions)
452+
.where(
453+
and(
454+
eq(permissions.entityId, wsInvitation.workspaceId),
455+
eq(permissions.entityType, 'workspace'),
456+
eq(permissions.userId, session.user.id)
457+
)
458+
)
459+
.then((rows) => rows[0])
460+
461+
if (existingPermission) {
462+
const PERMISSION_RANK = { read: 0, write: 1, admin: 2 } as const
463+
type PermissionLevel = keyof typeof PERMISSION_RANK
464+
const existingRank =
465+
PERMISSION_RANK[existingPermission.permissionType as PermissionLevel] ?? 0
466+
const newPermission = (wsInvitation.permissions || 'read') as PermissionLevel
467+
const newRank = PERMISSION_RANK[newPermission] ?? 0
468+
469+
if (newRank > existingRank) {
470+
await tx
471+
.update(permissions)
472+
.set({
473+
permissionType: newPermission,
474+
updatedAt: new Date(),
475+
})
476+
.where(eq(permissions.id, existingPermission.id))
477+
}
478+
} else {
479+
await tx.insert(permissions).values({
480+
id: randomUUID(),
481+
entityType: 'workspace',
482+
entityId: wsInvitation.workspaceId,
483+
userId: session.user.id,
484+
permissionType: wsInvitation.permissions || 'read',
485+
createdAt: new Date(),
486+
updatedAt: new Date(),
487+
})
488+
}
458489
}
459490
} else if (status === 'cancelled') {
460491
await tx

apps/sim/app/api/tools/jira/add-attachment/route.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,9 @@ export async function POST(request: NextRequest) {
4747
(await getJiraCloudId(validatedData.domain, validatedData.accessToken))
4848

4949
const formData = new FormData()
50-
const filesOutput: Array<{ name: string; mimeType: string; data: string; size: number }> = []
5150

5251
for (const file of userFiles) {
5352
const buffer = await downloadFileFromStorage(file, requestId, logger)
54-
filesOutput.push({
55-
name: file.name,
56-
mimeType: file.type || 'application/octet-stream',
57-
data: buffer.toString('base64'),
58-
size: buffer.length,
59-
})
6053
const blob = new Blob([new Uint8Array(buffer)], {
6154
type: file.type || 'application/octet-stream',
6255
})
@@ -109,7 +102,7 @@ export async function POST(request: NextRequest) {
109102
issueKey: validatedData.issueKey,
110103
attachments,
111104
attachmentIds,
112-
files: filesOutput,
105+
files: userFiles,
113106
},
114107
})
115108
} catch (error) {

0 commit comments

Comments
 (0)