@superinterface/server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +36 -0
  2. package/eslint.config.mjs +31 -0
  3. package/next.config.ts +7 -0
  4. package/package.json +176 -0
  5. package/prisma/Account.prisma +18 -0
  6. package/prisma/ApiKey.prisma +13 -0
  7. package/prisma/Assistant.prisma +32 -0
  8. package/prisma/AssistantHandler.prisma +12 -0
  9. package/prisma/Avatar.prisma +10 -0
  10. package/prisma/ClientToolHandler.prisma +13 -0
  11. package/prisma/CodeInterpreterTool.prisma +7 -0
  12. package/prisma/ComputerUseTool.prisma +12 -0
  13. package/prisma/CreateTaskHandler.prisma +10 -0
  14. package/prisma/DeleteTaskHandler.prisma +10 -0
  15. package/prisma/FileSearchTool.prisma +9 -0
  16. package/prisma/FirecrawlHandler.prisma +13 -0
  17. package/prisma/Function.prisma +13 -0
  18. package/prisma/Handler.prisma +19 -0
  19. package/prisma/HttpTransport.prisma +12 -0
  20. package/prisma/IconAvatar.prisma +8 -0
  21. package/prisma/ImageAvatar.prisma +8 -0
  22. package/prisma/ImageGenerationTool.prisma +11 -0
  23. package/prisma/InitialMessage.prisma +17 -0
  24. package/prisma/Invitation.prisma +15 -0
  25. package/prisma/ListTasksHandler.prisma +10 -0
  26. package/prisma/Log.prisma +21 -0
  27. package/prisma/McpServer.prisma +14 -0
  28. package/prisma/Message.prisma +30 -0
  29. package/prisma/ModelProvider.prisma +15 -0
  30. package/prisma/Organization.prisma +10 -0
  31. package/prisma/OrganizationApiKey.prisma +12 -0
  32. package/prisma/OrganizationInvitation.prisma +15 -0
  33. package/prisma/OrganizationUserRole.prisma +14 -0
  34. package/prisma/ReplicateHandler.prisma +14 -0
  35. package/prisma/RequestHandler.prisma +15 -0
  36. package/prisma/Run.prisma +36 -0
  37. package/prisma/RunStep.prisma +30 -0
  38. package/prisma/Session.prisma +7 -0
  39. package/prisma/SseTransport.prisma +12 -0
  40. package/prisma/StdioTransport.prisma +11 -0
  41. package/prisma/Task.prisma +15 -0
  42. package/prisma/Thread.prisma +20 -0
  43. package/prisma/Tool.prisma +13 -0
  44. package/prisma/UpdateTaskHandler.prisma +10 -0
  45. package/prisma/User.prisma +16 -0
  46. package/prisma/UserRole.prisma +14 -0
  47. package/prisma/VerificationToken.prisma +7 -0
  48. package/prisma/WebSearchTool.prisma +7 -0
  49. package/prisma/Workspace.prisma +14 -0
  50. package/prisma/enums/ApiKeyType.prisma +4 -0
  51. package/prisma/enums/AvatarType.prisma +5 -0
  52. package/prisma/enums/ClientToolHandlerType.prisma +3 -0
  53. package/prisma/enums/ComputerUseToolEnvironment.prisma +6 -0
  54. package/prisma/enums/FirecrawlHandlerType.prisma +6 -0
  55. package/prisma/enums/HandlerType.prisma +11 -0
  56. package/prisma/enums/IconAvatarName.prisma +14 -0
  57. package/prisma/enums/ImageGenerationToolOutputFormat.prisma +5 -0
  58. package/prisma/enums/ImageGenerationToolQuality.prisma +6 -0
  59. package/prisma/enums/ImageGenerationToolSize.prisma +6 -0
  60. package/prisma/enums/LogLevel.prisma +5 -0
  61. package/prisma/enums/LogRequestMethod.prisma +7 -0
  62. package/prisma/enums/LogRequestRoute.prisma +6 -0
  63. package/prisma/enums/MessageRole.prisma +4 -0
  64. package/prisma/enums/MessageStatus.prisma +5 -0
  65. package/prisma/enums/MethodType.prisma +7 -0
  66. package/prisma/enums/ModelProviderType.prisma +13 -0
  67. package/prisma/enums/OrganizationUserRoleType.prisma +3 -0
  68. package/prisma/enums/ReplicateHandlerType.prisma +3 -0
  69. package/prisma/enums/RunStatus.prisma +10 -0
  70. package/prisma/enums/RunStepStatus.prisma +7 -0
  71. package/prisma/enums/RunStepType.prisma +4 -0
  72. package/prisma/enums/StorageProviderType.prisma +7 -0
  73. package/prisma/enums/ToolType.prisma +7 -0
  74. package/prisma/enums/TransportType.prisma +5 -0
  75. package/prisma/enums/TruncationType.prisma +5 -0
  76. package/prisma/enums/UserRoleType.prisma +3 -0
  77. package/prisma/migrations/20251006235143_initial_setup/migration.sql +986 -0
  78. package/prisma/migrations/20251007163926_add_truncation_type/migration.sql +6 -0
  79. package/prisma/migrations/20251007190703_add_organizations/migration.sql +97 -0
  80. package/prisma/migrations/migration_lock.toml +3 -0
  81. package/prisma/schema.prisma +13 -0
  82. package/prisma.config.ts +6 -0
  83. package/scripts/cli.ts +84 -0
  84. package/scripts/commands/organizations/api-keys/create.ts +159 -0
  85. package/scripts/commands/organizations/create.ts +82 -0
  86. package/scripts/utils/env.ts +31 -0
  87. package/scripts/utils/errors.ts +6 -0
  88. package/src/app/api/api-keys/[apiKeyId]/route.ts +178 -0
  89. package/src/app/api/api-keys/route.ts +147 -0
  90. package/src/app/api/assistants/[assistantId]/functions/[functionId]/route.ts +245 -0
  91. package/src/app/api/assistants/[assistantId]/functions/route.ts +157 -0
  92. package/src/app/api/assistants/[assistantId]/initial-messages/route.ts +127 -0
  93. package/src/app/api/assistants/[assistantId]/mcp-servers/[mcpServerId]/route.ts +243 -0
  94. package/src/app/api/assistants/[assistantId]/mcp-servers/route.ts +163 -0
  95. package/src/app/api/assistants/[assistantId]/route.ts +336 -0
  96. package/src/app/api/assistants/route.ts +196 -0
  97. package/src/app/api/files/[fileId]/contents/route.ts +145 -0
  98. package/src/app/api/files/route.ts +117 -0
  99. package/src/app/api/messages/lib/getWorkspaceId.ts +12 -0
  100. package/src/app/api/messages/lib/initialMessagesResponse.ts +90 -0
  101. package/src/app/api/messages/lib/serializeThread.ts +22 -0
  102. package/src/app/api/messages/route.ts +710 -0
  103. package/src/app/api/providers/[modelProviderId]/assistants/route.ts +68 -0
  104. package/src/app/api/providers/[modelProviderId]/models/route.ts +68 -0
  105. package/src/app/api/providers/[modelProviderId]/route.ts +202 -0
  106. package/src/app/api/providers/route.ts +105 -0
  107. package/src/app/api/tasks/[taskId]/route.ts +213 -0
  108. package/src/app/api/tasks/callback/route.ts +280 -0
  109. package/src/app/api/tasks/route.ts +121 -0
  110. package/src/app/api/threads/runs/submit-client-tool-outputs/route.ts +54 -0
  111. package/src/app/api/workspaces/[workspaceId]/route.ts +137 -0
  112. package/src/app/api/workspaces/route.ts +139 -0
  113. package/src/app/layout.tsx +9 -0
  114. package/src/app/page.tsx +3 -0
  115. package/src/lib/apiKeys/formatApiKeyName.ts +13 -0
  116. package/src/lib/apiKeys/getApiKey.ts +25 -0
  117. package/src/lib/apiKeys/serializeApiKey.ts +11 -0
  118. package/src/lib/apiKeys/workspaceAccessWhere.ts +21 -0
  119. package/src/lib/assistants/assistantClientAdapter/buildGetOpenaiAssistant.ts +96 -0
  120. package/src/lib/assistants/assistantClientAdapter/index.ts +165 -0
  121. package/src/lib/assistants/formatName.ts +9 -0
  122. package/src/lib/assistants/serializeApiAssistant.ts +40 -0
  123. package/src/lib/assistants/serializeAssistant.ts +31 -0
  124. package/src/lib/assistants/storageAssistantId.ts +29 -0
  125. package/src/lib/avatars/defaultAvatar.ts +15 -0
  126. package/src/lib/avatars/serializeAvatar.ts +26 -0
  127. package/src/lib/cache/cacheHeaders.ts +5 -0
  128. package/src/lib/computerCalls/handleComputerCall/index.ts +173 -0
  129. package/src/lib/errors/index.ts +10 -0
  130. package/src/lib/errors/serializeError.ts +11 -0
  131. package/src/lib/functions/createFunction.ts +32 -0
  132. package/src/lib/functions/functionSchema.ts +201 -0
  133. package/src/lib/functions/handleFunction/getFunction.ts +43 -0
  134. package/src/lib/functions/handleFunction/handleAssistant.ts +399 -0
  135. package/src/lib/functions/handleFunction/handleClientTool.ts +127 -0
  136. package/src/lib/functions/handleFunction/handleFirecrawl.ts +212 -0
  137. package/src/lib/functions/handleFunction/handleReplicate.ts +109 -0
  138. package/src/lib/functions/handleFunction/handleRequest.ts +272 -0
  139. package/src/lib/functions/handleFunction/index.ts +474 -0
  140. package/src/lib/functions/handleFunction/tasks/handleCreateTask.ts +58 -0
  141. package/src/lib/functions/handleFunction/tasks/handleDeleteTask.ts +62 -0
  142. package/src/lib/functions/handleFunction/tasks/handleListTasks.ts +53 -0
  143. package/src/lib/functions/handleFunction/tasks/handleUpdateTask.ts +70 -0
  144. package/src/lib/functions/interpolateFunctionValue.ts +26 -0
  145. package/src/lib/functions/serializeApiFunction.ts +32 -0
  146. package/src/lib/functions/updateFunction.ts +42 -0
  147. package/src/lib/handlers/handlerPrismaInput.tsx +141 -0
  148. package/src/lib/handlers/serializeApiHandler.ts +94 -0
  149. package/src/lib/iconAvatars/serializeIconAvatar.ts +9 -0
  150. package/src/lib/imageAvatars/serializeImageAvatar.ts +9 -0
  151. package/src/lib/initialMessages/schema.ts +11 -0
  152. package/src/lib/initialMessages/serializeApiInitialMessage.ts +15 -0
  153. package/src/lib/initialMessages/updateInitialMessages.ts +33 -0
  154. package/src/lib/logs/createLog.ts +17 -0
  155. package/src/lib/mcpServers/closeMcpConnection.ts +16 -0
  156. package/src/lib/mcpServers/connectMcpServer.ts +117 -0
  157. package/src/lib/mcpServers/getToolCallMcpServer.ts +62 -0
  158. package/src/lib/mcpServers/headers.ts +113 -0
  159. package/src/lib/mcpServers/mcpServerSchema.ts +77 -0
  160. package/src/lib/mcpServers/serializeApiMcpServer.ts +51 -0
  161. package/src/lib/mcpServers/url.ts +98 -0
  162. package/src/lib/messages/content.ts +60 -0
  163. package/src/lib/messages/textContent.ts +13 -0
  164. package/src/lib/metadata/serializeMetadata.ts +34 -0
  165. package/src/lib/misc/isJSON.ts +9 -0
  166. package/src/lib/misc/merge/customizer.ts +8 -0
  167. package/src/lib/misc/merge/index.ts +6 -0
  168. package/src/lib/modelProviders/buildAzureOpenaiClientAdapter.ts +33 -0
  169. package/src/lib/modelProviders/buildOpenaiClient.ts +14 -0
  170. package/src/lib/modelProviders/buildOpenaiClientAdapter.ts +30 -0
  171. package/src/lib/modelProviders/clientAdapter.ts +121 -0
  172. package/src/lib/modelProviders/isModelProviderValid.ts +23 -0
  173. package/src/lib/modelProviders/modelProviderConfigs.ts +221 -0
  174. package/src/lib/modelProviders/serializeModelProvider.ts +19 -0
  175. package/src/lib/models/getModels.ts +27 -0
  176. package/src/lib/models/serializeApiModel.ts +5 -0
  177. package/src/lib/openai/getOpenaiAssistants.ts +30 -0
  178. package/src/lib/organizationApiKeys/getOrganizationApiKey.ts +23 -0
  179. package/src/lib/prisma/index.ts +29 -0
  180. package/src/lib/redis/index.ts +3 -0
  181. package/src/lib/runs/createRunOpts.ts +80 -0
  182. package/src/lib/storageProviders/getStorageProviderAssistants.ts +19 -0
  183. package/src/lib/storageProviders/getStorageProviderType.ts +21 -0
  184. package/src/lib/storageProviders/isOpenaiAssistantsStorageProvider.ts +8 -0
  185. package/src/lib/storageProviders/isResponsesStorageProvider.ts +8 -0
  186. package/src/lib/storageProviders/openaiAssistantsStorageProviderTypes.ts +6 -0
  187. package/src/lib/storageProviders/responsesStorageProviderTypes.ts +6 -0
  188. package/src/lib/storageProviders/serializeApiStorageProviderAssistant.ts +14 -0
  189. package/src/lib/tasks/cancelScheduledTask.ts +13 -0
  190. package/src/lib/tasks/getNextOccurrence.ts +77 -0
  191. package/src/lib/tasks/getTaskToolKey.ts +49 -0
  192. package/src/lib/tasks/parseTaskToolArgs.ts +101 -0
  193. package/src/lib/tasks/scheduleSchema.ts +34 -0
  194. package/src/lib/tasks/scheduleTask.ts +37 -0
  195. package/src/lib/tasks/schemas.ts +25 -0
  196. package/src/lib/tasks/serializeTask.ts +14 -0
  197. package/src/lib/tasks/validateSchedule.ts +23 -0
  198. package/src/lib/themes/defaultTheme.ts +7 -0
  199. package/src/lib/themes/serializeAccentColor.ts +9 -0
  200. package/src/lib/themes/serializeTheme/index.ts +25 -0
  201. package/src/lib/themes/serializeTheme/serializeScaling.ts +14 -0
  202. package/src/lib/threads/createThread/index.ts +185 -0
  203. package/src/lib/threads/createThread/initialMessages.ts +36 -0
  204. package/src/lib/threads/managedOpenaiThreadId.ts +72 -0
  205. package/src/lib/threads/storageThreadId.ts +49 -0
  206. package/src/lib/threads/validThreadId.ts +10 -0
  207. package/src/lib/toolCalls/handleToolCall.ts +121 -0
  208. package/src/lib/toolCalls/messagesToOutput.ts +8 -0
  209. package/src/lib/toolCalls/streamOutput.ts +106 -0
  210. package/src/lib/tools/tools/index.ts +316 -0
  211. package/src/lib/upstash/qstash.ts +5 -0
  212. package/src/lib/upstash/upstashWorkflowClient.ts +5 -0
  213. package/src/lib/workspaces/serializeApiWorkspace.ts +12 -0
  214. package/src/types/index.ts +133 -0
  215. package/tsconfig.build.json +13 -0
  216. package/tsconfig.json +27 -0
  217. package/types/prisma.d.ts +4 -0
@@ -0,0 +1,243 @@
1
+ import { headers } from 'next/headers'
2
+ import { ApiKeyType, TransportType } from '@prisma/client'
3
+ import { NextResponse, type NextRequest } from 'next/server'
4
+ import { cacheHeaders } from '@/lib/cache/cacheHeaders'
5
+ import { prisma } from '@/lib/prisma'
6
+ import { getApiKey } from '@/lib/apiKeys/getApiKey'
7
+ import { validate } from 'uuid'
8
+ import { serializeApiMcpServer } from '@/lib/mcpServers/serializeApiMcpServer'
9
+ import { mcpServerSchema } from '@/lib/mcpServers/mcpServerSchema'
10
+
11
+ export const GET = async (
12
+ _request: NextRequest,
13
+ props: { params: Promise<{ assistantId: string; mcpServerId: string }> },
14
+ ) => {
15
+ const { assistantId, mcpServerId } = await props.params
16
+
17
+ const headersList = await headers()
18
+ const authorization = headersList.get('authorization')
19
+ if (!authorization) {
20
+ return NextResponse.json(
21
+ { error: 'No authorization header found' },
22
+ { status: 400 },
23
+ )
24
+ }
25
+
26
+ const privateApiKey = await getApiKey({
27
+ type: ApiKeyType.PRIVATE,
28
+ authorization,
29
+ })
30
+
31
+ if (!privateApiKey) {
32
+ return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
33
+ }
34
+
35
+ if (!validate(assistantId)) {
36
+ return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
37
+ }
38
+
39
+ if (!validate(mcpServerId)) {
40
+ return NextResponse.json(
41
+ { error: 'Invalid MCP server id' },
42
+ { status: 400 },
43
+ )
44
+ }
45
+
46
+ const mcpServer = await prisma.mcpServer.findFirst({
47
+ where: {
48
+ id: mcpServerId,
49
+ assistant: {
50
+ id: assistantId,
51
+ workspaceId: privateApiKey.workspaceId,
52
+ },
53
+ },
54
+ include: {
55
+ sseTransport: true,
56
+ httpTransport: true,
57
+ },
58
+ })
59
+
60
+ if (!mcpServer) {
61
+ return NextResponse.json({ error: 'No MCP server found' }, { status: 400 })
62
+ }
63
+
64
+ return NextResponse.json(
65
+ {
66
+ mcpServer: serializeApiMcpServer({ mcpServer }),
67
+ },
68
+ { headers: cacheHeaders },
69
+ )
70
+ }
71
+
72
+ export const PATCH = async (
73
+ request: NextRequest,
74
+ props: { params: Promise<{ assistantId: string; mcpServerId: string }> },
75
+ ) => {
76
+ const { assistantId, mcpServerId } = await props.params
77
+
78
+ const headersList = await headers()
79
+ const authorization = headersList.get('authorization')
80
+ if (!authorization) {
81
+ return NextResponse.json(
82
+ { error: 'No authorization header found' },
83
+ { status: 400 },
84
+ )
85
+ }
86
+
87
+ const privateApiKey = await getApiKey({
88
+ authorization,
89
+ type: ApiKeyType.PRIVATE,
90
+ })
91
+
92
+ if (!privateApiKey) {
93
+ return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
94
+ }
95
+
96
+ if (!validate(assistantId)) {
97
+ return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
98
+ }
99
+
100
+ if (!validate(mcpServerId)) {
101
+ return NextResponse.json(
102
+ { error: 'Invalid MCP server id' },
103
+ { status: 400 },
104
+ )
105
+ }
106
+
107
+ const body = await request.json()
108
+
109
+ const parsed = mcpServerSchema.safeParse(body)
110
+
111
+ if (!parsed.success) {
112
+ return NextResponse.json({ error: 'Invalid payload' }, { status: 400 })
113
+ }
114
+
115
+ const { transportType, sseTransport, httpTransport } = parsed.data
116
+
117
+ const mcpServer = await prisma.mcpServer.findFirst({
118
+ where: {
119
+ id: mcpServerId,
120
+ assistant: {
121
+ id: assistantId,
122
+ workspaceId: privateApiKey.workspaceId,
123
+ },
124
+ },
125
+ })
126
+
127
+ if (!mcpServer) {
128
+ return NextResponse.json({ error: 'No MCP server found' }, { status: 400 })
129
+ }
130
+
131
+ const updatedMcpServer = await prisma.mcpServer.update({
132
+ where: {
133
+ id: mcpServerId,
134
+ },
135
+ data: {
136
+ transportType,
137
+ ...(transportType === TransportType.SSE
138
+ ? {
139
+ sseTransport: {
140
+ update: {
141
+ url: sseTransport!.url,
142
+ headers: JSON.parse(sseTransport!.headers),
143
+ },
144
+ },
145
+ }
146
+ : {}),
147
+ ...(transportType === TransportType.HTTP
148
+ ? {
149
+ httpTransport: {
150
+ update: {
151
+ url: httpTransport!.url,
152
+ headers: JSON.parse(httpTransport!.headers),
153
+ },
154
+ },
155
+ }
156
+ : {}),
157
+ },
158
+ include: {
159
+ sseTransport: true,
160
+ httpTransport: true,
161
+ },
162
+ })
163
+
164
+ return NextResponse.json(
165
+ {
166
+ mcpServer: serializeApiMcpServer({ mcpServer: updatedMcpServer }),
167
+ },
168
+ { headers: cacheHeaders },
169
+ )
170
+ }
171
+
172
+ export const DELETE = async (
173
+ _request: NextRequest,
174
+ props: { params: Promise<{ assistantId: string; mcpServerId: string }> },
175
+ ) => {
176
+ const { assistantId, mcpServerId } = await props.params
177
+
178
+ const headersList = await headers()
179
+ const authorization = headersList.get('authorization')
180
+ if (!authorization) {
181
+ return NextResponse.json(
182
+ { error: 'No authorization header found' },
183
+ { status: 400 },
184
+ )
185
+ }
186
+
187
+ const privateApiKey = await getApiKey({
188
+ authorization,
189
+ type: ApiKeyType.PRIVATE,
190
+ })
191
+
192
+ if (!privateApiKey) {
193
+ return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
194
+ }
195
+
196
+ if (!validate(assistantId)) {
197
+ return NextResponse.json({ error: 'Invalid assistant id' }, { status: 400 })
198
+ }
199
+
200
+ if (!validate(mcpServerId)) {
201
+ return NextResponse.json(
202
+ { error: 'Invalid MCP server id' },
203
+ { status: 400 },
204
+ )
205
+ }
206
+
207
+ const mcpServer = await prisma.mcpServer.findFirst({
208
+ where: {
209
+ id: mcpServerId,
210
+ assistant: {
211
+ id: assistantId,
212
+ workspaceId: privateApiKey.workspaceId,
213
+ },
214
+ },
215
+ })
216
+
217
+ if (!mcpServer) {
218
+ return NextResponse.json({ error: 'No MCP server found' }, { status: 400 })
219
+ }
220
+
221
+ const deletedMcpServer = await prisma.mcpServer.delete({
222
+ where: { id: mcpServerId },
223
+ include: {
224
+ sseTransport: true,
225
+ httpTransport: true,
226
+ },
227
+ })
228
+
229
+ return NextResponse.json(
230
+ {
231
+ mcpServer: serializeApiMcpServer({ mcpServer: deletedMcpServer }),
232
+ },
233
+ { headers: cacheHeaders },
234
+ )
235
+ }
236
+
237
+ export const OPTIONS = () =>
238
+ NextResponse.json(
239
+ {},
240
+ {
241
+ headers: cacheHeaders,
242
+ },
243
+ )
@@ -0,0 +1,163 @@
1
+ import { type NextRequest, NextResponse } from 'next/server'
2
+ import { ApiKeyType, TransportType } from '@prisma/client'
3
+ import { headers } from 'next/headers'
4
+ import { cacheHeaders } from '@/lib/cache/cacheHeaders'
5
+ import { prisma } from '@/lib/prisma'
6
+ import { getApiKey } from '@/lib/apiKeys/getApiKey'
7
+ import { serializeApiMcpServer } from '@/lib/mcpServers/serializeApiMcpServer'
8
+ import { mcpServerSchema } from '@/lib/mcpServers/mcpServerSchema'
9
+
10
+ export const GET = async (
11
+ _request: NextRequest,
12
+ props: { params: Promise<{ assistantId: string }> },
13
+ ) => {
14
+ const { assistantId } = await props.params
15
+
16
+ const headersList = await headers()
17
+ const authorization = headersList.get('authorization')
18
+ if (!authorization) {
19
+ return NextResponse.json(
20
+ { error: 'No authorization header found' },
21
+ { status: 400 },
22
+ )
23
+ }
24
+
25
+ const privateApiKey = await getApiKey({
26
+ type: ApiKeyType.PRIVATE,
27
+ authorization,
28
+ })
29
+
30
+ if (!privateApiKey) {
31
+ return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
32
+ }
33
+
34
+ const assistant = await prisma.assistant.findFirst({
35
+ where: {
36
+ id: assistantId,
37
+ workspaceId: privateApiKey.workspaceId,
38
+ },
39
+ include: {
40
+ mcpServers: {
41
+ include: {
42
+ stdioTransport: true,
43
+ sseTransport: true,
44
+ httpTransport: true,
45
+ },
46
+ orderBy: {
47
+ createdAt: 'desc',
48
+ },
49
+ },
50
+ },
51
+ })
52
+
53
+ if (!assistant) {
54
+ return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
55
+ }
56
+
57
+ return NextResponse.json(
58
+ {
59
+ mcpServers: assistant.mcpServers.map((mcpServer) =>
60
+ serializeApiMcpServer({
61
+ mcpServer,
62
+ }),
63
+ ),
64
+ },
65
+ { headers: cacheHeaders },
66
+ )
67
+ }
68
+
69
+ export const POST = async (
70
+ request: NextRequest,
71
+ props: { params: Promise<{ assistantId: string }> },
72
+ ) => {
73
+ const { assistantId } = await props.params
74
+
75
+ const headersList = await headers()
76
+ const authorization = headersList.get('authorization')
77
+ if (!authorization) {
78
+ return NextResponse.json(
79
+ { error: 'No authorization header found' },
80
+ { status: 400 },
81
+ )
82
+ }
83
+
84
+ const privateApiKey = await getApiKey({
85
+ authorization,
86
+ type: ApiKeyType.PRIVATE,
87
+ })
88
+
89
+ if (!privateApiKey) {
90
+ return NextResponse.json({ error: 'Invalid api key' }, { status: 400 })
91
+ }
92
+
93
+ const body = await request.json()
94
+ const parsed = mcpServerSchema.safeParse(body)
95
+
96
+ if (!parsed.success) {
97
+ return NextResponse.json({ error: 'Invalid payload' }, { status: 400 })
98
+ }
99
+
100
+ const { transportType, sseTransport, httpTransport } = parsed.data
101
+
102
+ const workspaceId = privateApiKey.workspaceId
103
+
104
+ const assistant = await prisma.assistant.findFirst({
105
+ where: { id: assistantId, workspaceId },
106
+ })
107
+
108
+ if (!assistant) {
109
+ return NextResponse.json({ error: 'No assistant found' }, { status: 400 })
110
+ }
111
+
112
+ const mcpServer = await prisma.mcpServer.create({
113
+ data: {
114
+ transportType,
115
+ ...(transportType === TransportType.SSE
116
+ ? {
117
+ sseTransport: {
118
+ create: {
119
+ url: sseTransport!.url,
120
+ headers: JSON.parse(sseTransport!.headers),
121
+ },
122
+ },
123
+ }
124
+ : {}),
125
+ ...(transportType === TransportType.HTTP
126
+ ? {
127
+ httpTransport: {
128
+ create: {
129
+ url: httpTransport!.url,
130
+ headers: JSON.parse(httpTransport!.headers),
131
+ },
132
+ },
133
+ }
134
+ : {}),
135
+ assistant: {
136
+ connect: {
137
+ id: assistantId,
138
+ workspaceId,
139
+ },
140
+ },
141
+ },
142
+ include: {
143
+ stdioTransport: true,
144
+ sseTransport: true,
145
+ httpTransport: true,
146
+ },
147
+ })
148
+
149
+ return NextResponse.json(
150
+ {
151
+ mcpServer: serializeApiMcpServer({ mcpServer }),
152
+ },
153
+ { headers: cacheHeaders },
154
+ )
155
+ }
156
+
157
+ export const OPTIONS = () =>
158
+ NextResponse.json(
159
+ {},
160
+ {
161
+ headers: cacheHeaders,
162
+ },
163
+ )