Showing the changes to plugins (3 of 5 files). Show all
Unified · Split
| @@ -55,6 +55,9 @@ type McpExecutorExtension = { · 54 unmodified lines | |||
| 55 | updateSource: ( | 55 | updateSource: ( |
| 56 | input: McpUpdateSourceInput, | 56 | input: McpUpdateSourceInput, |
| 57 | ) => Effect.Effect<Source, Error>; | 57 | ) => Effect.Effect<Source, Error>; |
| 58 | refreshSource: ( | ||
| 59 | sourceId: Source["id"], | ||
| 60 | ) => Effect.Effect<Source, Error>; | ||
| 58 | removeSource: ( | 61 | removeSource: ( |
| 59 | sourceId: Source["id"], | 62 | sourceId: Source["id"], |
| 60 | ) => Effect.Effect<boolean, Error>; | 63 | ) => Effect.Effect<boolean, Error>; |
| @@ -117,6 +120,14 @@ export const McpHttpGroup = HttpApiGroup.make("mcp") · 56 unmodified lines | |||
| 117 | .addError(ControlPlaneNotFoundError) | 120 | .addError(ControlPlaneNotFoundError) |
| 118 | .addError(ControlPlaneStorageError), | 121 | .addError(ControlPlaneStorageError), |
| 119 | ) | 122 | ) |
| 123 | .add( | ||
| 124 | HttpApiEndpoint.post("refreshSource")`/workspaces/${workspaceIdParam}/plugins/mcp/sources/${sourceIdParam}/refresh` | ||
| 125 | .addSuccess(SourceSchema) | ||
| 126 | .addError(ControlPlaneBadRequestError) | ||
| 127 | .addError(ControlPlaneForbiddenError) | ||
| 128 | .addError(ControlPlaneNotFoundError) | ||
| 129 | .addError(ControlPlaneStorageError), | ||
| 130 | ) | ||
| 120 | .add( | 131 | .add( |
| 121 | HttpApiEndpoint.del("removeSource")`/workspaces/${workspaceIdParam}/plugins/mcp/sources/${sourceIdParam}` | 132 | HttpApiEndpoint.del("removeSource")`/workspaces/${workspaceIdParam}/plugins/mcp/sources/${sourceIdParam}` |
| 122 | .addSuccess(Schema.Struct({ removed: Schema.Boolean })) | 133 | .addSuccess(Schema.Struct({ removed: Schema.Boolean })) |
| @@ -284,6 +295,17 @@ export const mcpHttpPlugin = (): ExecutorHttpPlugin< · 161 unmodified lines | |||
| 284 | ), | 295 | ), |
| 285 | ) | 296 | ) |
| 286 | ) | 297 | ) |
| 298 | .handle("refreshSource", ({ path }) => | ||
| 299 | resolveRequestedLocalWorkspace( | ||
| 300 | "mcp.refreshSource", | ||
| 301 | path.workspaceId, | ||
| 302 | ).pipe( | ||
| 303 | Effect.flatMap(() => executor.mcp.refreshSource(path.sourceId)), | ||
| 304 | Effect.mapError((cause) => | ||
| 305 | mapPluginStorageError("mcp.refreshSource", cause) | ||
| 306 | ), | ||
| 307 | ) | ||
| 308 | ) | ||
| 287 | .handle("removeSource", ({ path }) => | 309 | .handle("removeSource", ({ path }) => |
| 288 | resolveRequestedLocalWorkspace( | 310 | resolveRequestedLocalWorkspace( |
| 289 | "mcp.removeSource", | 311 | "mcp.removeSource", |
| @@ -733,6 +733,25 @@ export function McpDetailPage(props: { · 732 unmodified lines | |||
| 733 | client.mutation("mcp", "removeSource"), | 733 | client.mutation("mcp", "removeSource"), |
| 734 | { mode: "promise" }, | 734 | { mode: "promise" }, |
| 735 | ); | 735 | ); |
| 736 | const refreshSource = useAtomSet( | ||
| 737 | client.mutation("mcp", "refreshSource"), | ||
| 738 | { mode: "promise" }, | ||
| 739 | ); | ||
| 740 | const refreshMutation = useExecutorMutation<Source["id"], Source>(async (sourceId) => | ||
| 741 | refreshSource({ | ||
| 742 | path: { | ||
| 743 | workspaceId: props.source.scopeId, | ||
| 744 | sourceId, | ||
| 745 | }, | ||
| 746 | reactivityKeys: { | ||
| 747 | sources: [props.source.scopeId], | ||
| 748 | source: [props.source.scopeId, sourceId], | ||
| 749 | sourceInspection: [props.source.scopeId, sourceId], | ||
| 750 | sourceInspectionTool: [props.source.scopeId, sourceId], | ||
| 751 | sourceDiscovery: [props.source.scopeId, sourceId], | ||
| 752 | }, | ||
| 753 | }) | ||
| 754 | ); | ||
| 736 | const [confirmDelete, setConfirmDelete] = useState(false); | 755 | const [confirmDelete, setConfirmDelete] = useState(false); |
| 737 | const [isDeleting, setIsDeleting] = useState(false); | 756 | const [isDeleting, setIsDeleting] = useState(false); |
| 738 | const configResult = useAtomValue( | 757 | const configResult = useAtomValue( |
| @@ -815,6 +834,19 @@ export function McpDetailPage(props: { · 76 unmodified lines | |||
| 815 | <> | 834 | <> |
| 816 | <Button | 835 | <Button |
| 817 | variant="outline" | 836 | variant="outline" |
| 837 | size="sm" | ||
| 838 | type="button" | ||
| 839 | onClick={() => { | ||
| 840 | void refreshMutation.mutateAsync(props.source.id); | ||
| 841 | }} | ||
| 842 | disabled={refreshMutation.status === "pending"} | ||
| 843 | > | ||
| 844 | {refreshMutation.status === "pending" ? "Refreshing..." : "Refresh"} | ||
| 845 | </Button> | ||
| 846 | <Button | ||
| 847 | variant="outline" | ||
| 848 | size="sm" | ||
| 849 | type="button" | ||
| 818 | onClick={() => | 850 | onClick={() => |
| 819 | void navigation.edit(props.source.id)} | 851 | void navigation.edit(props.source.id)} |
| 820 | > | 852 | > |
| @@ -163,6 +163,9 @@ export type McpSdk = { · 162 unmodified lines | |||
| 163 | updateSource: ( | 163 | updateSource: ( |
| 164 | input: McpUpdateSourceInput, | 164 | input: McpUpdateSourceInput, |
| 165 | ) => Effect.Effect<Source, Error>; | 165 | ) => Effect.Effect<Source, Error>; |
| 166 | refreshSource: ( | ||
| 167 | sourceId: Source["id"], | ||
| 168 | ) => Effect.Effect<Source, Error>; | ||
| 166 | removeSource: ( | 169 | removeSource: ( |
| 167 | sourceId: Source["id"], | 170 | sourceId: Source["id"], |
| 168 | ) => Effect.Effect<boolean, Error>; | 171 | ) => Effect.Effect<boolean, Error>; |
| @@ -948,6 +951,13 @@ export const mcpSdkPlugin = ( · 779 unmodified lines | |||
| 948 | outputSchema: SourceSchema, | 951 | outputSchema: SourceSchema, |
| 949 | execute: ({ args, source }) => source.updateSource(args), | 952 | execute: ({ args, source }) => source.updateSource(args), |
| 950 | }, | 953 | }, |
| 954 | { | ||
| 955 | name: "refreshSource", | ||
| 956 | description: "Refresh an MCP source and resync its catalog.", | ||
| 957 | inputSchema: McpSourceIdInputSchema, | ||
| 958 | outputSchema: SourceSchema, | ||
| 959 | execute: ({ args, source }) => source.refreshSource(args.sourceId), | ||
| 960 | }, | ||
| 951 | { | 961 | { |
| 952 | name: "removeSource", | 962 | name: "removeSource", |
| 953 | description: "Remove an MCP source and its stored plugin data.", | 963 | description: "Remove an MCP source and its stored plugin data.", |
| @@ -1092,6 +1102,8 @@ export const mcpSdkPlugin = ( · 138 unmodified lines | |||
| 1092 | provideRuntime(source.createSource(input)), | 1102 | provideRuntime(source.createSource(input)), |
| 1093 | updateSource: (input) => | 1103 | updateSource: (input) => |
| 1094 | provideRuntime(source.updateSource(input)), | 1104 | provideRuntime(source.updateSource(input)), |
| 1105 | refreshSource: (sourceId) => | ||
| 1106 | provideRuntime(source.refreshSource(sourceId)), | ||
| 1095 | removeSource: (sourceId) => | 1107 | removeSource: (sourceId) => |
| 1096 | provideRuntime(source.removeSource(sourceId)), | 1108 | provideRuntime(source.removeSource(sourceId)), |
| 1097 | startOAuth: (input) => | 1109 | startOAuth: (input) => |