@headless-lms/server 0.3.0 → 0.5.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.
- package/README.md +14 -0
- package/dist/app/community-mail.d.ts +10 -10
- package/dist/app/community-mail.js +72 -28
- package/dist/app/community-mail.js.map +1 -1
- package/dist/app/container.d.ts +48 -10
- package/dist/app/container.js +268 -48
- package/dist/app/container.js.map +1 -1
- package/dist/app/notification-channels.d.ts +47 -0
- package/dist/app/notification-channels.js +175 -0
- package/dist/app/notification-channels.js.map +1 -0
- package/dist/app/notification-reads.d.ts +23 -0
- package/dist/app/notification-reads.js +74 -0
- package/dist/app/notification-reads.js.map +1 -0
- package/dist/app/platform.d.ts +14 -0
- package/dist/app/platform.js +14 -0
- package/dist/app/platform.js.map +1 -0
- package/dist/http/config.d.ts +4 -0
- package/dist/http/errors.d.ts +1 -0
- package/dist/http/errors.js +24 -4
- package/dist/http/errors.js.map +1 -1
- package/dist/http/fastify.d.ts +8 -0
- package/dist/http/mcp/catalogue.d.ts +11 -9
- package/dist/http/mcp/catalogue.js +15 -21
- package/dist/http/mcp/catalogue.js.map +1 -1
- package/dist/http/mcp/challenge.js +3 -3
- package/dist/http/mcp/challenge.js.map +1 -1
- package/dist/http/mcp/route.js +7 -7
- package/dist/http/mcp/route.js.map +1 -1
- package/dist/http/mcp/test-support.d.ts +6 -5
- package/dist/http/mcp/test-support.js +32 -11
- package/dist/http/mcp/test-support.js.map +1 -1
- package/dist/http/mcp/tool.d.ts +3 -9
- package/dist/http/mcp/tool.js +14 -6
- package/dist/http/mcp/tool.js.map +1 -1
- package/dist/http/mcp/tools/automations.js +10 -20
- package/dist/http/mcp/tools/automations.js.map +1 -1
- package/dist/http/mcp/tools/catalog.js +25 -42
- package/dist/http/mcp/tools/catalog.js.map +1 -1
- package/dist/http/mcp/tools/comments.js +9 -19
- package/dist/http/mcp/tools/comments.js.map +1 -1
- package/dist/http/mcp/tools/communities.js +16 -31
- package/dist/http/mcp/tools/communities.js.map +1 -1
- package/dist/http/mcp/tools/community-members.js +9 -16
- package/dist/http/mcp/tools/community-members.js.map +1 -1
- package/dist/http/mcp/tools/community-moderation.js +13 -25
- package/dist/http/mcp/tools/community-moderation.js.map +1 -1
- package/dist/http/mcp/tools/courses.js +11 -21
- package/dist/http/mcp/tools/courses.js.map +1 -1
- package/dist/http/mcp/tools/events.d.ts +6 -0
- package/dist/http/mcp/tools/events.js +170 -0
- package/dist/http/mcp/tools/events.js.map +1 -0
- package/dist/http/mcp/tools/index.d.ts +5 -1
- package/dist/http/mcp/tools/index.js +45 -10
- package/dist/http/mcp/tools/index.js.map +1 -1
- package/dist/http/mcp/tools/organization.d.ts +6 -0
- package/dist/http/mcp/tools/organization.js +214 -0
- package/dist/http/mcp/tools/organization.js.map +1 -0
- package/dist/http/mcp/tools/people.js +30 -49
- package/dist/http/mcp/tools/people.js.map +1 -1
- package/dist/http/plugins/auth.js +37 -8
- package/dist/http/plugins/auth.js.map +1 -1
- package/dist/http/plugins/error-handler.d.ts +5 -1
- package/dist/http/plugins/error-handler.js +13 -3
- package/dist/http/plugins/error-handler.js.map +1 -1
- package/dist/http/plugins/openapi.js +18 -2
- package/dist/http/plugins/openapi.js.map +1 -1
- package/dist/http/plugins/platform.d.ts +7 -0
- package/dist/http/plugins/platform.js +13 -0
- package/dist/http/plugins/platform.js.map +1 -0
- package/dist/http/routes/access.js +54 -36
- package/dist/http/routes/access.js.map +1 -1
- package/dist/http/routes/activities.js +45 -45
- package/dist/http/routes/activities.js.map +1 -1
- package/dist/http/routes/assets.js +30 -65
- package/dist/http/routes/assets.js.map +1 -1
- package/dist/http/routes/automations.js +37 -42
- package/dist/http/routes/automations.js.map +1 -1
- package/dist/http/routes/bundles.js +33 -36
- package/dist/http/routes/bundles.js.map +1 -1
- package/dist/http/routes/communities.js +144 -136
- package/dist/http/routes/communities.js.map +1 -1
- package/dist/http/routes/community-moderation.js +83 -137
- package/dist/http/routes/community-moderation.js.map +1 -1
- package/dist/http/routes/course-analytics.js +32 -15
- package/dist/http/routes/course-analytics.js.map +1 -1
- package/dist/http/routes/courses.js +25 -32
- package/dist/http/routes/courses.js.map +1 -1
- package/dist/http/routes/dashboard.js +9 -9
- package/dist/http/routes/dashboard.js.map +1 -1
- package/dist/http/routes/discussion.js +21 -39
- package/dist/http/routes/discussion.js.map +1 -1
- package/dist/http/routes/downloads.js +41 -47
- package/dist/http/routes/downloads.js.map +1 -1
- package/dist/http/routes/entitlements.js +19 -23
- package/dist/http/routes/entitlements.js.map +1 -1
- package/dist/http/routes/events.d.ts +7 -0
- package/dist/http/routes/events.js +333 -0
- package/dist/http/routes/events.js.map +1 -0
- package/dist/http/routes/integrations.js +40 -73
- package/dist/http/routes/integrations.js.map +1 -1
- package/dist/http/routes/member/assets.js +10 -13
- package/dist/http/routes/member/assets.js.map +1 -1
- package/dist/http/routes/member/chats.js +177 -75
- package/dist/http/routes/member/chats.js.map +1 -1
- package/dist/http/routes/member/comments.js +65 -26
- package/dist/http/routes/member/comments.js.map +1 -1
- package/dist/http/routes/member/community.js +68 -51
- package/dist/http/routes/member/community.js.map +1 -1
- package/dist/http/routes/member/courses.js +12 -19
- package/dist/http/routes/member/courses.js.map +1 -1
- package/dist/http/routes/member/devices.d.ts +7 -0
- package/dist/http/routes/member/devices.js +97 -0
- package/dist/http/routes/member/devices.js.map +1 -0
- package/dist/http/routes/member/downloads.js +6 -9
- package/dist/http/routes/member/downloads.js.map +1 -1
- package/dist/http/routes/member/events.d.ts +7 -0
- package/dist/http/routes/member/events.js +386 -0
- package/dist/http/routes/member/events.js.map +1 -0
- package/dist/http/routes/member/files.js +71 -46
- package/dist/http/routes/member/files.js.map +1 -1
- package/dist/http/routes/member/index.js +6 -0
- package/dist/http/routes/member/index.js.map +1 -1
- package/dist/http/routes/member/notification-settings.d.ts +7 -0
- package/dist/http/routes/member/notification-settings.js +100 -0
- package/dist/http/routes/member/notification-settings.js.map +1 -0
- package/dist/http/routes/member/notifications.js +69 -45
- package/dist/http/routes/member/notifications.js.map +1 -1
- package/dist/http/routes/member/org.js +5 -15
- package/dist/http/routes/member/org.js.map +1 -1
- package/dist/http/routes/member/posts.js +94 -95
- package/dist/http/routes/member/posts.js.map +1 -1
- package/dist/http/routes/member/profile.js +15 -6
- package/dist/http/routes/member/profile.js.map +1 -1
- package/dist/http/routes/member/progress.js +7 -11
- package/dist/http/routes/member/progress.js.map +1 -1
- package/dist/http/routes/organizations.js +415 -110
- package/dist/http/routes/organizations.js.map +1 -1
- package/dist/http/routes/platform.d.ts +7 -0
- package/dist/http/routes/platform.js +61 -0
- package/dist/http/routes/platform.js.map +1 -0
- package/dist/http/routes/students.js +12 -75
- package/dist/http/routes/students.js.map +1 -1
- package/dist/http/routes/webhooks.js +30 -39
- package/dist/http/routes/webhooks.js.map +1 -1
- package/dist/http/routes.js +9 -0
- package/dist/http/routes.js.map +1 -1
- package/dist/http/schemas/access.d.ts +346 -64
- package/dist/http/schemas/access.js +39 -12
- package/dist/http/schemas/access.js.map +1 -1
- package/dist/http/schemas/assets.d.ts +13 -8
- package/dist/http/schemas/assets.js +6 -5
- package/dist/http/schemas/assets.js.map +1 -1
- package/dist/http/schemas/automations.d.ts +4 -8
- package/dist/http/schemas/chats.d.ts +238 -36
- package/dist/http/schemas/chats.js +14 -7
- package/dist/http/schemas/chats.js.map +1 -1
- package/dist/http/schemas/community.d.ts +140 -33
- package/dist/http/schemas/community.js +25 -9
- package/dist/http/schemas/community.js.map +1 -1
- package/dist/http/schemas/course-analytics.d.ts +51 -1
- package/dist/http/schemas/course-analytics.js +19 -1
- package/dist/http/schemas/course-analytics.js.map +1 -1
- package/dist/http/schemas/dashboard.d.ts +1 -0
- package/dist/http/schemas/dashboard.js +2 -1
- package/dist/http/schemas/dashboard.js.map +1 -1
- package/dist/http/schemas/discussion.d.ts +45 -73
- package/dist/http/schemas/discussion.js +16 -4
- package/dist/http/schemas/discussion.js.map +1 -1
- package/dist/http/schemas/entitlements.d.ts +9 -12
- package/dist/http/schemas/entitlements.js +11 -5
- package/dist/http/schemas/entitlements.js.map +1 -1
- package/dist/http/schemas/events.d.ts +527 -0
- package/dist/http/schemas/events.js +64 -0
- package/dist/http/schemas/events.js.map +1 -0
- package/dist/http/schemas/files.d.ts +15 -5
- package/dist/http/schemas/files.js +10 -2
- package/dist/http/schemas/files.js.map +1 -1
- package/dist/http/schemas/index.d.ts +14 -12
- package/dist/http/schemas/index.js +14 -12
- package/dist/http/schemas/invites.d.ts +3 -47
- package/dist/http/schemas/invites.js +4 -25
- package/dist/http/schemas/invites.js.map +1 -1
- package/dist/http/schemas/member.d.ts +94 -7
- package/dist/http/schemas/member.js +7 -3
- package/dist/http/schemas/member.js.map +1 -1
- package/dist/http/schemas/members.d.ts +329 -65
- package/dist/http/schemas/members.js +67 -25
- package/dist/http/schemas/members.js.map +1 -1
- package/dist/http/schemas/notifications.d.ts +502 -175
- package/dist/http/schemas/notifications.js +148 -28
- package/dist/http/schemas/notifications.js.map +1 -1
- package/dist/http/schemas/platform.d.ts +37 -0
- package/dist/http/schemas/platform.js +19 -0
- package/dist/http/schemas/platform.js.map +1 -0
- package/dist/http/schemas/posts.d.ts +92 -38
- package/dist/http/schemas/posts.js +4 -4
- package/dist/http/schemas/posts.js.map +1 -1
- package/dist/http/schemas/profile.d.ts +1 -1
- package/dist/http/schemas/shared.d.ts +10 -13
- package/dist/http/schemas/shared.js +3 -11
- package/dist/http/schemas/shared.js.map +1 -1
- package/dist/http/schemas/students.d.ts +22 -0
- package/dist/http/schemas/students.js +3 -1
- package/dist/http/schemas/students.js.map +1 -1
- package/dist/http/scope.d.ts +9 -12
- package/dist/http/scope.js +30 -35
- package/dist/http/scope.js.map +1 -1
- package/dist/http/server.js +9 -0
- package/dist/http/server.js.map +1 -1
- package/dist/http/shutdown.d.ts +11 -0
- package/dist/http/shutdown.js +40 -0
- package/dist/http/shutdown.js.map +1 -0
- package/dist/http/sse.d.ts +19 -0
- package/dist/http/sse.js +104 -0
- package/dist/http/sse.js.map +1 -0
- package/dist/http/test-caller.d.ts +13 -0
- package/dist/http/test-caller.js +14 -0
- package/dist/http/test-caller.js.map +1 -0
- package/dist/http/well-known.js +2 -2
- package/dist/http/well-known.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/packages/server/package.js +1 -1
- package/package.json +7 -6
- package/dist/http/routes/member/actor.d.ts +0 -14
- package/dist/http/routes/member/actor.js +0 -11
- package/dist/http/routes/member/actor.js.map +0 -1
package/dist/http/mcp/tool.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { classifyError } from "../errors.js";
|
|
2
|
+
import { refusalSubject } from "../plugins/error-handler.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
//#region src/http/mcp/tool.ts
|
|
4
5
|
const noInput = z.object({});
|
|
5
|
-
const actor = (scope) => ({
|
|
6
|
-
id: scope.orgUserId,
|
|
7
|
-
role: scope.role
|
|
8
|
-
});
|
|
9
6
|
function defineTool(def) {
|
|
10
7
|
return {
|
|
11
8
|
...def,
|
|
@@ -34,7 +31,18 @@ function toToolResult(data) {
|
|
|
34
31
|
}
|
|
35
32
|
function describeFailure(error, tool, ctx) {
|
|
36
33
|
const known = classifyError(error);
|
|
37
|
-
if (known)
|
|
34
|
+
if (known) {
|
|
35
|
+
ctx.container.logger.info("mcp tool refused", {
|
|
36
|
+
tool: tool.name,
|
|
37
|
+
status: known.status,
|
|
38
|
+
error: known.error,
|
|
39
|
+
message: known.message,
|
|
40
|
+
orgId: ctx.caller.orgId,
|
|
41
|
+
actorId: ctx.caller.orgUserId,
|
|
42
|
+
...refusalSubject(error)
|
|
43
|
+
});
|
|
44
|
+
return known.message;
|
|
45
|
+
}
|
|
38
46
|
ctx.container.logger.error("mcp tool failed", {
|
|
39
47
|
err: error instanceof Error ? error : new Error(String(error)),
|
|
40
48
|
tool: tool.name
|
|
@@ -53,6 +61,6 @@ async function runTool(tool, args, ctx) {
|
|
|
53
61
|
}
|
|
54
62
|
}
|
|
55
63
|
//#endregion
|
|
56
|
-
export {
|
|
64
|
+
export { defineTool, noInput, runTool, toToolResult, toolError };
|
|
57
65
|
|
|
58
66
|
//# sourceMappingURL=tool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","names":[],"sources":["../../../src/http/mcp/tool.ts"],"sourcesContent":["import { z } from 'zod';\nimport type {
|
|
1
|
+
{"version":3,"file":"tool.js","names":[],"sources":["../../../src/http/mcp/tool.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { Container } from '../../app/container.js';\nimport { classifyError } from '../errors.js';\nimport { refusalSubject } from '../plugins/error-handler.js';\nimport type { Caller } from '../scope.js';\n\nexport interface ToolContext {\n container: Container;\n caller: Caller;\n requestId: string;\n}\n\nexport type ToolKind = 'read' | 'write' | 'destructive';\n\nexport interface Tool {\n name: string;\n title: string;\n description: string;\n kind: ToolKind;\n idempotent: boolean;\n openWorld: boolean;\n input: z.ZodObject;\n output?: z.ZodType;\n call(input: unknown, ctx: ToolContext): unknown;\n}\n\nexport interface ToolDef<Input extends z.ZodObject> extends Omit<Tool, 'input' | 'call'> {\n input: Input;\n call(input: z.output<Input>, ctx: ToolContext): unknown;\n}\n\nexport const noInput = z.object({});\n\nexport function defineTool<Input extends z.ZodObject>(def: ToolDef<Input>): Tool {\n return { ...def, call: (input, ctx) => def.call(input as z.output<Input>, ctx) };\n}\n\nexport interface ToolResult {\n [key: string]: unknown;\n content: Array<{ type: 'text'; text: string }>;\n structuredContent?: Record<string, unknown>;\n isError?: boolean;\n}\n\nexport function toolError(message: string): ToolResult {\n return { content: [{ type: 'text', text: message }], isError: true };\n}\n\nexport function toToolResult(data: unknown): ToolResult {\n const plain: unknown = JSON.parse(JSON.stringify(data === undefined ? { ok: true } : data));\n const structuredContent =\n plain !== null && typeof plain === 'object' && !Array.isArray(plain)\n ? (plain as Record<string, unknown>)\n : { result: plain };\n return {\n content: [{ type: 'text', text: JSON.stringify(structuredContent) }],\n structuredContent,\n };\n}\n\nfunction describeFailure(error: unknown, tool: Tool, ctx: ToolContext): string {\n const known = classifyError(error);\n if (known) {\n ctx.container.logger.info('mcp tool refused', {\n tool: tool.name,\n status: known.status,\n error: known.error,\n message: known.message,\n orgId: ctx.caller.orgId,\n actorId: ctx.caller.orgUserId,\n ...refusalSubject(error),\n });\n return known.message;\n }\n ctx.container.logger.error('mcp tool failed', {\n err: error instanceof Error ? error : new Error(String(error)),\n tool: tool.name,\n });\n return `Internal error (request ${ctx.requestId})`;\n}\n\nexport async function runTool(tool: Tool, args: unknown, ctx: ToolContext): Promise<ToolResult> {\n const input = tool.input.safeParse(args);\n if (!input.success) {\n return toolError(`Invalid input: ${z.prettifyError(input.error)}`);\n }\n try {\n const result = await tool.call(input.data, ctx);\n if (result === null || result === false) {\n return toolError('Not found.');\n }\n return toToolResult(tool.output && result !== undefined ? tool.output.parse(result) : result);\n } catch (error) {\n return toolError(describeFailure(error, tool, ctx));\n }\n}\n"],"mappings":";;;;AA+BA,MAAa,UAAU,EAAE,OAAO,CAAC,CAAC;AAElC,SAAgB,WAAsC,KAA2B;CAC/E,OAAO;EAAE,GAAG;EAAK,OAAO,OAAO,QAAQ,IAAI,KAAK,OAA0B,GAAG;CAAE;AACjF;AASA,SAAgB,UAAU,SAA6B;CACrD,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM;EAAQ,CAAC;EAAG,SAAS;CAAK;AACrE;AAEA,SAAgB,aAAa,MAA2B;CACtD,MAAM,QAAiB,KAAK,MAAM,KAAK,UAAU,SAAS,KAAA,IAAY,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC;CAC1F,MAAM,oBACJ,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC9D,QACD,EAAE,QAAQ,MAAM;CACtB,OAAO;EACL,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,KAAK,UAAU,iBAAiB;EAAE,CAAC;EACnE;CACF;AACF;AAEA,SAAS,gBAAgB,OAAgB,MAAY,KAA0B;CAC7E,MAAM,QAAQ,cAAc,KAAK;CACjC,IAAI,OAAO;EACT,IAAI,UAAU,OAAO,KAAK,oBAAoB;GAC5C,MAAM,KAAK;GACX,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,SAAS,MAAM;GACf,OAAO,IAAI,OAAO;GAClB,SAAS,IAAI,OAAO;GACpB,GAAG,eAAe,KAAK;EACzB,CAAC;EACD,OAAO,MAAM;CACf;CACA,IAAI,UAAU,OAAO,MAAM,mBAAmB;EAC5C,KAAK,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EAC7D,MAAM,KAAK;CACb,CAAC;CACD,OAAO,2BAA2B,IAAI,UAAU;AAClD;AAEA,eAAsB,QAAQ,MAAY,MAAe,KAAuC;CAC9F,MAAM,QAAQ,KAAK,MAAM,UAAU,IAAI;CACvC,IAAI,CAAC,MAAM,SACT,OAAO,UAAU,kBAAkB,EAAE,cAAc,MAAM,KAAK,GAAG;CAEnE,IAAI;EACF,MAAM,SAAS,MAAM,KAAK,KAAK,MAAM,MAAM,GAAG;EAC9C,IAAI,WAAW,QAAQ,WAAW,OAChC,OAAO,UAAU,YAAY;EAE/B,OAAO,aAAa,KAAK,UAAU,WAAW,KAAA,IAAY,KAAK,OAAO,MAAM,MAAM,IAAI,MAAM;CAC9F,SAAS,OAAO;EACd,OAAO,UAAU,gBAAgB,OAAO,MAAM,GAAG,CAAC;CACpD;AACF"}
|
|
@@ -7,111 +7,101 @@ const automationTools = [
|
|
|
7
7
|
name: "list_automation_triggers",
|
|
8
8
|
title: "List workflow triggers",
|
|
9
9
|
description: "The events that can start a workflow.",
|
|
10
|
-
scope: "automations:read",
|
|
11
10
|
kind: "read",
|
|
12
11
|
idempotent: true,
|
|
13
12
|
openWorld: false,
|
|
14
13
|
input: noInput,
|
|
15
|
-
call: (_input, { container }) => container.automations.availableTriggers()
|
|
14
|
+
call: (_input, { container, caller }) => container.automations.availableTriggers(caller.actor)
|
|
16
15
|
}),
|
|
17
16
|
defineTool({
|
|
18
17
|
name: "list_automation_actions",
|
|
19
18
|
title: "List workflow actions",
|
|
20
19
|
description: "The actions a workflow can run, with the settings each one takes.",
|
|
21
|
-
scope: "automations:read",
|
|
22
20
|
kind: "read",
|
|
23
21
|
idempotent: true,
|
|
24
22
|
openWorld: false,
|
|
25
23
|
input: noInput,
|
|
26
|
-
call: (_input, { container }) => container.automations.availableActions()
|
|
24
|
+
call: (_input, { container, caller }) => container.automations.availableActions(caller.actor)
|
|
27
25
|
}),
|
|
28
26
|
defineTool({
|
|
29
27
|
name: "list_automations",
|
|
30
28
|
title: "List workflows and webhooks",
|
|
31
29
|
description: "Workflows and webhooks with their triggers, ordered actions and enabled state. Filter by kind (workflow or webhook).",
|
|
32
|
-
scope: "automations:read",
|
|
33
30
|
kind: "read",
|
|
34
31
|
idempotent: true,
|
|
35
32
|
openWorld: false,
|
|
36
33
|
input: AutomationsQuery,
|
|
37
|
-
call: (input, { container,
|
|
34
|
+
call: (input, { container, caller }) => container.automations.list(input, caller.actor)
|
|
38
35
|
}),
|
|
39
36
|
defineTool({
|
|
40
37
|
name: "list_automation_runs",
|
|
41
38
|
title: "List workflow and webhook runs",
|
|
42
39
|
description: "Runs of one workflow or webhook, newest first, with the trigger event as a webhook would receive it and each action result.",
|
|
43
|
-
scope: "automations:read",
|
|
44
40
|
kind: "read",
|
|
45
41
|
idempotent: true,
|
|
46
42
|
openWorld: false,
|
|
47
43
|
input: AutomationRunsQuery.extend(AutomationIdParam.shape),
|
|
48
|
-
call: ({ id, ...query }, { container,
|
|
44
|
+
call: ({ id, ...query }, { container, caller }) => container.automations.listRuns(id, query, caller.actor)
|
|
49
45
|
}),
|
|
50
46
|
defineTool({
|
|
51
47
|
name: "create_automation",
|
|
52
48
|
title: "Create workflow",
|
|
53
49
|
description: "Create a workflow from triggers and ordered actions. Use list_automation_triggers and list_automation_actions for valid values.",
|
|
54
|
-
scope: "automations:write",
|
|
55
50
|
kind: "write",
|
|
56
51
|
idempotent: false,
|
|
57
52
|
openWorld: false,
|
|
58
53
|
input: CreateAutomationBody,
|
|
59
|
-
call: (input, { container,
|
|
54
|
+
call: (input, { container, caller }) => container.automations.create(input, caller.actor)
|
|
60
55
|
}),
|
|
61
56
|
defineTool({
|
|
62
57
|
name: "update_automation",
|
|
63
58
|
title: "Update workflow",
|
|
64
59
|
description: "Change a workflow name, description, triggers or actions, or turn it on and off with enabled. Fields left out stay as they are.",
|
|
65
|
-
scope: "automations:write",
|
|
66
60
|
kind: "write",
|
|
67
61
|
idempotent: true,
|
|
68
62
|
openWorld: false,
|
|
69
63
|
input: UpdateAutomationBody.extend(AutomationIdParam.shape),
|
|
70
|
-
call: ({ id, ...patch }, { container,
|
|
64
|
+
call: ({ id, ...patch }, { container, caller }) => container.automations.update(id, patch, caller.actor)
|
|
71
65
|
}),
|
|
72
66
|
defineTool({
|
|
73
67
|
name: "rerun_automation_run",
|
|
74
68
|
title: "Re-run workflow or webhook run",
|
|
75
69
|
description: "Run a finished workflow or webhook run again with its original trigger event, using the automation's current actions. Emails and webhook deliveries are sent again. The new outcome replaces the run's previous one. A run still in progress can't be re-run.",
|
|
76
|
-
scope: "automations:write",
|
|
77
70
|
kind: "write",
|
|
78
71
|
idempotent: false,
|
|
79
72
|
openWorld: true,
|
|
80
73
|
input: AutomationRunParams,
|
|
81
|
-
call: ({ id, runId }, { container,
|
|
74
|
+
call: ({ id, runId }, { container, caller }) => container.automations.rerun(id, runId, caller.actor)
|
|
82
75
|
}),
|
|
83
76
|
defineTool({
|
|
84
77
|
name: "delete_automation",
|
|
85
78
|
title: "Delete workflow",
|
|
86
79
|
description: "Permanently delete a workflow.",
|
|
87
|
-
scope: "automations:delete",
|
|
88
80
|
kind: "destructive",
|
|
89
81
|
idempotent: true,
|
|
90
82
|
openWorld: false,
|
|
91
83
|
input: AutomationIdParam,
|
|
92
|
-
call: ({ id }, { container,
|
|
84
|
+
call: ({ id }, { container, caller }) => container.automations.delete(id, caller.actor)
|
|
93
85
|
}),
|
|
94
86
|
defineTool({
|
|
95
87
|
name: "update_webhook",
|
|
96
88
|
title: "Update webhook",
|
|
97
89
|
description: "Change a webhook URL, events or description, or turn it on and off with enabled. Fields left out stay as they are.",
|
|
98
|
-
scope: "automations:write",
|
|
99
90
|
kind: "write",
|
|
100
91
|
idempotent: true,
|
|
101
92
|
openWorld: false,
|
|
102
93
|
input: UpdateWebhookBody.extend(AutomationIdParam.shape),
|
|
103
|
-
call: ({ id, ...patch }, { container,
|
|
94
|
+
call: ({ id, ...patch }, { container, caller }) => container.automations.updateWebhook(id, patch, caller.actor)
|
|
104
95
|
}),
|
|
105
96
|
defineTool({
|
|
106
97
|
name: "delete_webhook",
|
|
107
98
|
title: "Delete webhook",
|
|
108
99
|
description: "Permanently delete a webhook and its signing secret. Its delivery history is kept.",
|
|
109
|
-
scope: "automations:delete",
|
|
110
100
|
kind: "destructive",
|
|
111
101
|
idempotent: true,
|
|
112
102
|
openWorld: false,
|
|
113
103
|
input: AutomationIdParam,
|
|
114
|
-
call: ({ id }, { container,
|
|
104
|
+
call: ({ id }, { container, caller }) => container.automations.deleteWebhook(id, caller.actor)
|
|
115
105
|
})
|
|
116
106
|
];
|
|
117
107
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automations.js","names":[],"sources":["../../../../src/http/mcp/tools/automations.ts"],"sourcesContent":["import {\n AutomationIdParam,\n AutomationRunParams,\n AutomationRunsQuery,\n AutomationsQuery,\n CreateAutomationBody,\n UpdateAutomationBody,\n UpdateWebhookBody,\n} from '../../schemas/index.js';\nimport { defineTool, noInput, type Tool } from '../tool.js';\n\nexport const automationTools: Tool[] = [\n defineTool({\n name: 'list_automation_triggers',\n title: 'List workflow triggers',\n description: 'The events that can start a workflow.',\n
|
|
1
|
+
{"version":3,"file":"automations.js","names":[],"sources":["../../../../src/http/mcp/tools/automations.ts"],"sourcesContent":["import {\n AutomationIdParam,\n AutomationRunParams,\n AutomationRunsQuery,\n AutomationsQuery,\n CreateAutomationBody,\n UpdateAutomationBody,\n UpdateWebhookBody,\n} from '../../schemas/index.js';\nimport { defineTool, noInput, type Tool } from '../tool.js';\n\nexport const automationTools: Tool[] = [\n defineTool({\n name: 'list_automation_triggers',\n title: 'List workflow triggers',\n description: 'The events that can start a workflow.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: noInput,\n call: (_input, { container, caller }) => container.automations.availableTriggers(caller.actor),\n }),\n defineTool({\n name: 'list_automation_actions',\n title: 'List workflow actions',\n description: 'The actions a workflow can run, with the settings each one takes.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: noInput,\n call: (_input, { container, caller }) => container.automations.availableActions(caller.actor),\n }),\n defineTool({\n name: 'list_automations',\n title: 'List workflows and webhooks',\n description:\n 'Workflows and webhooks with their triggers, ordered actions and enabled state. Filter by kind (workflow or webhook).',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: AutomationsQuery,\n call: (input, { container, caller }) => container.automations.list(input, caller.actor),\n }),\n defineTool({\n name: 'list_automation_runs',\n title: 'List workflow and webhook runs',\n description:\n 'Runs of one workflow or webhook, newest first, with the trigger event as a webhook would receive it and each action result.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: AutomationRunsQuery.extend(AutomationIdParam.shape),\n call: ({ id, ...query }, { container, caller }) =>\n container.automations.listRuns(id, query, caller.actor),\n }),\n defineTool({\n name: 'create_automation',\n title: 'Create workflow',\n description:\n 'Create a workflow from triggers and ordered actions. Use list_automation_triggers and list_automation_actions for valid values.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: CreateAutomationBody,\n call: (input, { container, caller }) => container.automations.create(input, caller.actor),\n }),\n defineTool({\n name: 'update_automation',\n title: 'Update workflow',\n description:\n 'Change a workflow name, description, triggers or actions, or turn it on and off with enabled. Fields left out stay as they are.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateAutomationBody.extend(AutomationIdParam.shape),\n call: ({ id, ...patch }, { container, caller }) =>\n container.automations.update(id, patch, caller.actor),\n }),\n defineTool({\n name: 'rerun_automation_run',\n title: 'Re-run workflow or webhook run',\n description:\n \"Run a finished workflow or webhook run again with its original trigger event, using the automation's current actions. Emails and webhook deliveries are sent again. The new outcome replaces the run's previous one. A run still in progress can't be re-run.\",\n kind: 'write',\n idempotent: false,\n openWorld: true,\n input: AutomationRunParams,\n call: ({ id, runId }, { container, caller }) =>\n container.automations.rerun(id, runId, caller.actor),\n }),\n defineTool({\n name: 'delete_automation',\n title: 'Delete workflow',\n description: 'Permanently delete a workflow.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: AutomationIdParam,\n call: ({ id }, { container, caller }) => container.automations.delete(id, caller.actor),\n }),\n defineTool({\n name: 'update_webhook',\n title: 'Update webhook',\n description:\n 'Change a webhook URL, events or description, or turn it on and off with enabled. Fields left out stay as they are.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateWebhookBody.extend(AutomationIdParam.shape),\n call: ({ id, ...patch }, { container, caller }) =>\n container.automations.updateWebhook(id, patch, caller.actor),\n }),\n defineTool({\n name: 'delete_webhook',\n title: 'Delete webhook',\n description:\n 'Permanently delete a webhook and its signing secret. Its delivery history is kept.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: AutomationIdParam,\n call: ({ id }, { container, caller }) => container.automations.deleteWebhook(id, caller.actor),\n }),\n];\n"],"mappings":";;;;AAWA,MAAa,kBAA0B;CACrC,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,QAAQ,EAAE,WAAW,aAAa,UAAU,YAAY,kBAAkB,OAAO,KAAK;CAC/F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,QAAQ,EAAE,WAAW,aAAa,UAAU,YAAY,iBAAiB,OAAO,KAAK;CAC9F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,aAAa,UAAU,YAAY,KAAK,OAAO,OAAO,KAAK;CACxF,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,oBAAoB,OAAO,kBAAkB,KAAK;EACzD,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,WAAW,aACpC,UAAU,YAAY,SAAS,IAAI,OAAO,OAAO,KAAK;CAC1D,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,aAAa,UAAU,YAAY,OAAO,OAAO,OAAO,KAAK;CAC1F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,qBAAqB,OAAO,kBAAkB,KAAK;EAC1D,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,WAAW,aACpC,UAAU,YAAY,OAAO,IAAI,OAAO,OAAO,KAAK;CACxD,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,IAAI,SAAS,EAAE,WAAW,aACjC,UAAU,YAAY,MAAM,IAAI,OAAO,OAAO,KAAK;CACvD,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,MAAM,EAAE,WAAW,aAAa,UAAU,YAAY,OAAO,IAAI,OAAO,KAAK;CACxF,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,kBAAkB,OAAO,kBAAkB,KAAK;EACvD,OAAO,EAAE,IAAI,GAAG,SAAS,EAAE,WAAW,aACpC,UAAU,YAAY,cAAc,IAAI,OAAO,OAAO,KAAK;CAC/D,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,MAAM,EAAE,WAAW,aAAa,UAAU,YAAY,cAAc,IAAI,OAAO,KAAK;CAC/F,CAAC;AACH"}
|
|
@@ -2,196 +2,179 @@ import { AddDownloadAsset, CreateDownload, DownloadAssetParams, DownloadIdParam,
|
|
|
2
2
|
import { AddBundleItem, BundleIdParam, BundleItemParams, BundlesQuery, CreateBundle, UpdateBundle } from "../../schemas/bundles.js";
|
|
3
3
|
import { AssetsPage, AssetsQuery } from "../../schemas/assets.js";
|
|
4
4
|
import "../../schemas/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { defineTool } from "../tool.js";
|
|
6
6
|
//#region src/http/mcp/tools/catalog.ts
|
|
7
7
|
const catalogTools = [
|
|
8
8
|
defineTool({
|
|
9
9
|
name: "list_downloads",
|
|
10
10
|
title: "List downloads",
|
|
11
11
|
description: "Search and page through downloads: file collections a student can be granted. Filter by status or category.",
|
|
12
|
-
scope: "downloads:read",
|
|
13
12
|
kind: "read",
|
|
14
13
|
idempotent: true,
|
|
15
14
|
openWorld: false,
|
|
16
15
|
input: DownloadsQuery,
|
|
17
|
-
call: (input, { container,
|
|
16
|
+
call: (input, { container, caller }) => container.content.listDownloads(input, caller.actor)
|
|
18
17
|
}),
|
|
19
18
|
defineTool({
|
|
20
19
|
name: "list_download_files",
|
|
21
20
|
title: "List download files",
|
|
22
21
|
description: "The files of a download, in order, with their display names.",
|
|
23
|
-
scope: "downloads:read",
|
|
24
22
|
kind: "read",
|
|
25
23
|
idempotent: true,
|
|
26
24
|
openWorld: false,
|
|
27
25
|
input: DownloadIdParam,
|
|
28
|
-
call: ({ downloadId }, { container,
|
|
26
|
+
call: ({ downloadId }, { container, caller }) => container.content.listDownloadAssets(downloadId, caller.actor)
|
|
29
27
|
}),
|
|
30
28
|
defineTool({
|
|
31
29
|
name: "create_download",
|
|
32
30
|
title: "Create download",
|
|
33
31
|
description: "Create a draft download. Add files with add_download_file and publish it with update_download.",
|
|
34
|
-
scope: "downloads:write",
|
|
35
32
|
kind: "write",
|
|
36
33
|
idempotent: false,
|
|
37
34
|
openWorld: false,
|
|
38
35
|
input: CreateDownload,
|
|
39
|
-
call: (input, { container,
|
|
36
|
+
call: (input, { container, caller }) => container.content.createDownload(input, caller.actor)
|
|
40
37
|
}),
|
|
41
38
|
defineTool({
|
|
42
39
|
name: "update_download",
|
|
43
40
|
title: "Update download",
|
|
44
41
|
description: "Change a download title, description, category or cover image, or publish and unpublish it with status. Fields left out stay as they are.",
|
|
45
|
-
scope: "downloads:write",
|
|
46
42
|
kind: "write",
|
|
47
43
|
idempotent: true,
|
|
48
44
|
openWorld: false,
|
|
49
45
|
input: UpdateDownload.extend(DownloadIdParam.shape),
|
|
50
|
-
call: ({ downloadId, ...patch }, { container,
|
|
46
|
+
call: ({ downloadId, ...patch }, { container, caller }) => container.content.updateDownload(downloadId, patch, caller.actor)
|
|
51
47
|
}),
|
|
52
48
|
defineTool({
|
|
53
49
|
name: "add_download_file",
|
|
54
50
|
title: "Add file to download",
|
|
55
51
|
description: "Add an uploaded file to the end of a download. Find file ids with list_media.",
|
|
56
|
-
scope: "downloads:write",
|
|
57
52
|
kind: "write",
|
|
58
53
|
idempotent: false,
|
|
59
54
|
openWorld: false,
|
|
60
55
|
input: AddDownloadAsset.extend(DownloadIdParam.shape),
|
|
61
|
-
call: ({ downloadId, ...file }, { container,
|
|
56
|
+
call: ({ downloadId, ...file }, { container, caller }) => container.content.addDownloadAsset(downloadId, file, caller.actor)
|
|
62
57
|
}),
|
|
63
58
|
defineTool({
|
|
64
59
|
name: "rename_download_file",
|
|
65
60
|
title: "Rename download file",
|
|
66
61
|
description: "Set the name a file shows under in a download. null shows the file name.",
|
|
67
|
-
scope: "downloads:write",
|
|
68
62
|
kind: "write",
|
|
69
63
|
idempotent: true,
|
|
70
64
|
openWorld: false,
|
|
71
65
|
input: RenameDownloadAsset.extend(DownloadAssetParams.shape),
|
|
72
|
-
call: ({ downloadId, assetId, displayName }, { container,
|
|
66
|
+
call: ({ downloadId, assetId, displayName }, { container, caller }) => container.content.renameDownloadAsset(downloadId, assetId, displayName, caller.actor)
|
|
73
67
|
}),
|
|
74
68
|
defineTool({
|
|
75
69
|
name: "reorder_download_files",
|
|
76
70
|
title: "Reorder download files",
|
|
77
71
|
description: "Set the file order of a download. Pass every file id of the download in the new order.",
|
|
78
|
-
scope: "downloads:write",
|
|
79
72
|
kind: "write",
|
|
80
73
|
idempotent: true,
|
|
81
74
|
openWorld: false,
|
|
82
75
|
input: ReorderDownloadAssets.extend(DownloadIdParam.shape),
|
|
83
|
-
call: ({ downloadId, assetIds }, { container,
|
|
76
|
+
call: ({ downloadId, assetIds }, { container, caller }) => container.content.reorderDownloadAssets(downloadId, assetIds, caller.actor)
|
|
84
77
|
}),
|
|
85
78
|
defineTool({
|
|
86
79
|
name: "remove_download_file",
|
|
87
80
|
title: "Remove file from download",
|
|
88
81
|
description: "Take a file out of a download. The uploaded file itself is kept.",
|
|
89
|
-
scope: "downloads:write",
|
|
90
82
|
kind: "destructive",
|
|
91
83
|
idempotent: true,
|
|
92
84
|
openWorld: false,
|
|
93
85
|
input: DownloadAssetParams,
|
|
94
|
-
call: ({ downloadId, assetId }, { container,
|
|
86
|
+
call: ({ downloadId, assetId }, { container, caller }) => container.content.removeDownloadAsset(downloadId, assetId, caller.actor)
|
|
95
87
|
}),
|
|
96
88
|
defineTool({
|
|
97
89
|
name: "delete_download",
|
|
98
90
|
title: "Delete download",
|
|
99
91
|
description: "Permanently delete a download. The uploaded files are kept.",
|
|
100
|
-
scope: "downloads:delete",
|
|
101
92
|
kind: "destructive",
|
|
102
93
|
idempotent: true,
|
|
103
94
|
openWorld: false,
|
|
104
95
|
input: DownloadIdParam,
|
|
105
|
-
call: ({ downloadId }, { container,
|
|
96
|
+
call: ({ downloadId }, { container, caller }) => container.content.removeDownload(downloadId, caller.actor)
|
|
106
97
|
}),
|
|
107
98
|
defineTool({
|
|
108
99
|
name: "list_bundles",
|
|
109
100
|
title: "List bundles",
|
|
110
|
-
description: "Search and page through bundles: sets of courses, downloads and
|
|
111
|
-
scope: "bundles:read",
|
|
101
|
+
description: "Search and page through bundles: sets of courses, downloads, communities and events granted together.",
|
|
112
102
|
kind: "read",
|
|
113
103
|
idempotent: true,
|
|
114
104
|
openWorld: false,
|
|
115
105
|
input: BundlesQuery,
|
|
116
|
-
call: (input, { container,
|
|
106
|
+
call: (input, { container, caller }) => container.content.listBundles(input, caller.actor)
|
|
117
107
|
}),
|
|
118
108
|
defineTool({
|
|
119
109
|
name: "list_bundle_items",
|
|
120
110
|
title: "List bundle items",
|
|
121
|
-
description: "The courses, downloads and
|
|
122
|
-
scope: "bundles:read",
|
|
111
|
+
description: "The courses, downloads, communities and events in a bundle.",
|
|
123
112
|
kind: "read",
|
|
124
113
|
idempotent: true,
|
|
125
114
|
openWorld: false,
|
|
126
115
|
input: BundleIdParam,
|
|
127
|
-
call: ({ bundleId }, { container,
|
|
116
|
+
call: ({ bundleId }, { container, caller }) => container.content.listBundleItems(bundleId, caller.actor)
|
|
128
117
|
}),
|
|
129
118
|
defineTool({
|
|
130
119
|
name: "create_bundle",
|
|
131
120
|
title: "Create bundle",
|
|
132
|
-
description: "Create a bundle, optionally with the course, download and
|
|
133
|
-
scope: "bundles:write",
|
|
121
|
+
description: "Create a bundle, optionally with the course, download, community and event ids it starts with.",
|
|
134
122
|
kind: "write",
|
|
135
123
|
idempotent: false,
|
|
136
124
|
openWorld: false,
|
|
137
125
|
input: CreateBundle,
|
|
138
|
-
call: (input, { container,
|
|
126
|
+
call: (input, { container, caller }) => container.content.createBundle(input, caller.actor)
|
|
139
127
|
}),
|
|
140
128
|
defineTool({
|
|
141
129
|
name: "rename_bundle",
|
|
142
130
|
title: "Rename bundle",
|
|
143
131
|
description: "Rename a bundle.",
|
|
144
|
-
scope: "bundles:write",
|
|
145
132
|
kind: "write",
|
|
146
133
|
idempotent: true,
|
|
147
134
|
openWorld: false,
|
|
148
135
|
input: UpdateBundle.extend(BundleIdParam.shape),
|
|
149
|
-
call: ({ bundleId, ...patch }, { container,
|
|
136
|
+
call: ({ bundleId, ...patch }, { container, caller }) => container.content.updateBundle(bundleId, patch, caller.actor)
|
|
150
137
|
}),
|
|
151
138
|
defineTool({
|
|
152
139
|
name: "add_bundle_item",
|
|
153
140
|
title: "Add to bundle",
|
|
154
|
-
description: "Add a course, download or
|
|
155
|
-
scope: "bundles:write",
|
|
141
|
+
description: "Add a course, download, community or event to a bundle. Returns the bundle items.",
|
|
156
142
|
kind: "write",
|
|
157
143
|
idempotent: false,
|
|
158
144
|
openWorld: false,
|
|
159
145
|
input: AddBundleItem.extend(BundleIdParam.shape),
|
|
160
|
-
call: ({ bundleId, contentId }, { container,
|
|
146
|
+
call: ({ bundleId, contentId }, { container, caller }) => container.content.addBundleItem(bundleId, contentId, caller.actor)
|
|
161
147
|
}),
|
|
162
148
|
defineTool({
|
|
163
149
|
name: "remove_bundle_item",
|
|
164
150
|
title: "Remove from bundle",
|
|
165
|
-
description: "Take a course, download or
|
|
166
|
-
scope: "bundles:write",
|
|
151
|
+
description: "Take a course, download, community or event out of a bundle. Returns the remaining items.",
|
|
167
152
|
kind: "destructive",
|
|
168
153
|
idempotent: true,
|
|
169
154
|
openWorld: false,
|
|
170
155
|
input: BundleItemParams,
|
|
171
|
-
call: ({ bundleId, contentId }, { container,
|
|
156
|
+
call: ({ bundleId, contentId }, { container, caller }) => container.content.removeBundleItem(bundleId, contentId, caller.actor)
|
|
172
157
|
}),
|
|
173
158
|
defineTool({
|
|
174
159
|
name: "delete_bundle",
|
|
175
160
|
title: "Delete bundle",
|
|
176
|
-
description: "Permanently delete a bundle. Its courses, downloads and
|
|
177
|
-
scope: "bundles:delete",
|
|
161
|
+
description: "Permanently delete a bundle. Its courses, downloads, communities and events are kept.",
|
|
178
162
|
kind: "destructive",
|
|
179
163
|
idempotent: true,
|
|
180
164
|
openWorld: false,
|
|
181
165
|
input: BundleIdParam,
|
|
182
|
-
call: ({ bundleId }, { container,
|
|
166
|
+
call: ({ bundleId }, { container, caller }) => container.content.deleteBundle(bundleId, caller.actor)
|
|
183
167
|
}),
|
|
184
168
|
defineTool({
|
|
185
169
|
name: "list_media",
|
|
186
170
|
title: "List media",
|
|
187
|
-
description: "Search and page through uploaded files, to use in downloads or as cover images of courses, downloads and
|
|
188
|
-
scope: "media:read",
|
|
171
|
+
description: "Search and page through uploaded files, to use in downloads and events or as cover images of courses, downloads, communities and events. Uploading is done in the admin app.",
|
|
189
172
|
kind: "read",
|
|
190
173
|
idempotent: true,
|
|
191
174
|
openWorld: false,
|
|
192
175
|
input: AssetsQuery,
|
|
193
176
|
output: AssetsPage,
|
|
194
|
-
call: (input, { container,
|
|
177
|
+
call: (input, { container, caller }) => container.assets.list(input, caller.actor)
|
|
195
178
|
})
|
|
196
179
|
];
|
|
197
180
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.js","names":[],"sources":["../../../../src/http/mcp/tools/catalog.ts"],"sourcesContent":["import {\n AddBundleItem,\n AddDownloadAsset,\n AssetsPage,\n AssetsQuery,\n BundleIdParam,\n BundleItemParams,\n BundlesQuery,\n CreateBundle,\n CreateDownload,\n DownloadAssetParams,\n DownloadIdParam,\n DownloadsQuery,\n RenameDownloadAsset,\n ReorderDownloadAssets,\n UpdateBundle,\n UpdateDownload,\n} from '../../schemas/index.js';\nimport { actor, defineTool, type Tool } from '../tool.js';\n\nexport const catalogTools: Tool[] = [\n defineTool({\n name: 'list_downloads',\n title: 'List downloads',\n description:\n 'Search and page through downloads: file collections a student can be granted. Filter by status or category.',\n scope: 'downloads:read',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: DownloadsQuery,\n call: (input, { container, scope }) => container.content.listDownloads(scope.orgId, input),\n }),\n defineTool({\n name: 'list_download_files',\n title: 'List download files',\n description: 'The files of a download, in order, with their display names.',\n scope: 'downloads:read',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: DownloadIdParam,\n call: ({ downloadId }, { container, scope }) =>\n container.content.listDownloadAssets(scope.orgId, downloadId),\n }),\n defineTool({\n name: 'create_download',\n title: 'Create download',\n description:\n 'Create a draft download. Add files with add_download_file and publish it with update_download.',\n scope: 'downloads:write',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: CreateDownload,\n call: (input, { container, scope }) => container.content.createDownload(scope.orgId, input),\n }),\n defineTool({\n name: 'update_download',\n title: 'Update download',\n description:\n 'Change a download title, description, category or cover image, or publish and unpublish it with status. Fields left out stay as they are.',\n scope: 'downloads:write',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateDownload.extend(DownloadIdParam.shape),\n call: ({ downloadId, ...patch }, { container, scope }) =>\n container.content.updateDownload(scope.orgId, downloadId, patch),\n }),\n defineTool({\n name: 'add_download_file',\n title: 'Add file to download',\n description: 'Add an uploaded file to the end of a download. Find file ids with list_media.',\n scope: 'downloads:write',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: AddDownloadAsset.extend(DownloadIdParam.shape),\n call: ({ downloadId, ...file }, { container, scope }) =>\n container.content.addDownloadAsset(scope.orgId, downloadId, file),\n }),\n defineTool({\n name: 'rename_download_file',\n title: 'Rename download file',\n description: 'Set the name a file shows under in a download. null shows the file name.',\n scope: 'downloads:write',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: RenameDownloadAsset.extend(DownloadAssetParams.shape),\n call: ({ downloadId, assetId, displayName }, { container, scope }) =>\n container.content.renameDownloadAsset(scope.orgId, downloadId, assetId, displayName),\n }),\n defineTool({\n name: 'reorder_download_files',\n title: 'Reorder download files',\n description:\n 'Set the file order of a download. Pass every file id of the download in the new order.',\n scope: 'downloads:write',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: ReorderDownloadAssets.extend(DownloadIdParam.shape),\n call: ({ downloadId, assetIds }, { container, scope }) =>\n container.content.reorderDownloadAssets(scope.orgId, downloadId, assetIds),\n }),\n defineTool({\n name: 'remove_download_file',\n title: 'Remove file from download',\n description: 'Take a file out of a download. The uploaded file itself is kept.',\n scope: 'downloads:write',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: DownloadAssetParams,\n call: ({ downloadId, assetId }, { container, scope }) =>\n container.content.removeDownloadAsset(scope.orgId, downloadId, assetId),\n }),\n defineTool({\n name: 'delete_download',\n title: 'Delete download',\n description: 'Permanently delete a download. The uploaded files are kept.',\n scope: 'downloads:delete',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: DownloadIdParam,\n call: ({ downloadId }, { container, scope }) =>\n container.content.removeDownload(scope.orgId, downloadId, actor(scope)),\n }),\n defineTool({\n name: 'list_bundles',\n title: 'List bundles',\n description:\n 'Search and page through bundles: sets of courses, downloads and communities granted together.',\n scope: 'bundles:read',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: BundlesQuery,\n call: (input, { container, scope }) => container.content.listBundles(scope.orgId, input),\n }),\n defineTool({\n name: 'list_bundle_items',\n title: 'List bundle items',\n description: 'The courses, downloads and communities in a bundle.',\n scope: 'bundles:read',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: BundleIdParam,\n call: ({ bundleId }, { container, scope }) =>\n container.content.listBundleItems(scope.orgId, bundleId),\n }),\n defineTool({\n name: 'create_bundle',\n title: 'Create bundle',\n description:\n 'Create a bundle, optionally with the course, download and community ids it starts with.',\n scope: 'bundles:write',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: CreateBundle,\n call: (input, { container, scope }) => container.content.createBundle(scope.orgId, input),\n }),\n defineTool({\n name: 'rename_bundle',\n title: 'Rename bundle',\n description: 'Rename a bundle.',\n scope: 'bundles:write',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateBundle.extend(BundleIdParam.shape),\n call: ({ bundleId, ...patch }, { container, scope }) =>\n container.content.updateBundle(scope.orgId, bundleId, patch),\n }),\n defineTool({\n name: 'add_bundle_item',\n title: 'Add to bundle',\n description: 'Add a course, download or community to a bundle. Returns the bundle items.',\n scope: 'bundles:write',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: AddBundleItem.extend(BundleIdParam.shape),\n call: ({ bundleId, contentId }, { container, scope }) =>\n container.content.addBundleItem(scope.orgId, bundleId, contentId),\n }),\n defineTool({\n name: 'remove_bundle_item',\n title: 'Remove from bundle',\n description:\n 'Take a course, download or community out of a bundle. Returns the remaining items.',\n scope: 'bundles:write',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: BundleItemParams,\n call: ({ bundleId, contentId }, { container, scope }) =>\n container.content.removeBundleItem(scope.orgId, bundleId, contentId),\n }),\n defineTool({\n name: 'delete_bundle',\n title: 'Delete bundle',\n description: 'Permanently delete a bundle. Its courses, downloads and communities are kept.',\n scope: 'bundles:delete',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: BundleIdParam,\n call: ({ bundleId }, { container, scope }) =>\n container.content.deleteBundle(scope.orgId, bundleId),\n }),\n defineTool({\n name: 'list_media',\n title: 'List media',\n description:\n 'Search and page through uploaded files, to use in downloads or as cover images of courses, downloads and communities. Uploading is done in the admin app.',\n scope: 'media:read',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: AssetsQuery,\n output: AssetsPage,\n call: (input, { container, scope }) => container.assets.list(scope.orgId, input),\n }),\n];\n"],"mappings":";;;;;;AAoBA,MAAa,eAAuB;CAClC,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,YAAY,UAAU,QAAQ,cAAc,MAAM,OAAO,KAAK;CAC3F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,cAAc,EAAE,WAAW,YAClC,UAAU,QAAQ,mBAAmB,MAAM,OAAO,UAAU;CAChE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,YAAY,UAAU,QAAQ,eAAe,MAAM,OAAO,KAAK;CAC5F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,eAAe,OAAO,gBAAgB,KAAK;EAClD,OAAO,EAAE,YAAY,GAAG,SAAS,EAAE,WAAW,YAC5C,UAAU,QAAQ,eAAe,MAAM,OAAO,YAAY,KAAK;CACnE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,iBAAiB,OAAO,gBAAgB,KAAK;EACpD,OAAO,EAAE,YAAY,GAAG,QAAQ,EAAE,WAAW,YAC3C,UAAU,QAAQ,iBAAiB,MAAM,OAAO,YAAY,IAAI;CACpE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,oBAAoB,OAAO,oBAAoB,KAAK;EAC3D,OAAO,EAAE,YAAY,SAAS,eAAe,EAAE,WAAW,YACxD,UAAU,QAAQ,oBAAoB,MAAM,OAAO,YAAY,SAAS,WAAW;CACvF,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,sBAAsB,OAAO,gBAAgB,KAAK;EACzD,OAAO,EAAE,YAAY,YAAY,EAAE,WAAW,YAC5C,UAAU,QAAQ,sBAAsB,MAAM,OAAO,YAAY,QAAQ;CAC7E,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,YAAY,WAAW,EAAE,WAAW,YAC3C,UAAU,QAAQ,oBAAoB,MAAM,OAAO,YAAY,OAAO;CAC1E,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,cAAc,EAAE,WAAW,YAClC,UAAU,QAAQ,eAAe,MAAM,OAAO,YAAY,MAAM,KAAK,CAAC;CAC1E,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,YAAY,UAAU,QAAQ,YAAY,MAAM,OAAO,KAAK;CACzF,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,YAAY,EAAE,WAAW,YAChC,UAAU,QAAQ,gBAAgB,MAAM,OAAO,QAAQ;CAC3D,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,YAAY,UAAU,QAAQ,aAAa,MAAM,OAAO,KAAK;CAC1F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,aAAa,OAAO,cAAc,KAAK;EAC9C,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,WAAW,YAC1C,UAAU,QAAQ,aAAa,MAAM,OAAO,UAAU,KAAK;CAC/D,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,cAAc,OAAO,cAAc,KAAK;EAC/C,OAAO,EAAE,UAAU,aAAa,EAAE,WAAW,YAC3C,UAAU,QAAQ,cAAc,MAAM,OAAO,UAAU,SAAS;CACpE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,UAAU,aAAa,EAAE,WAAW,YAC3C,UAAU,QAAQ,iBAAiB,MAAM,OAAO,UAAU,SAAS;CACvE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,YAAY,EAAE,WAAW,YAChC,UAAU,QAAQ,aAAa,MAAM,OAAO,QAAQ;CACxD,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,OAAO;EACP,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,QAAQ;EACR,OAAO,OAAO,EAAE,WAAW,YAAY,UAAU,OAAO,KAAK,MAAM,OAAO,KAAK;CACjF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"catalog.js","names":[],"sources":["../../../../src/http/mcp/tools/catalog.ts"],"sourcesContent":["import {\n AddBundleItem,\n AddDownloadAsset,\n AssetsPage,\n AssetsQuery,\n BundleIdParam,\n BundleItemParams,\n BundlesQuery,\n CreateBundle,\n CreateDownload,\n DownloadAssetParams,\n DownloadIdParam,\n DownloadsQuery,\n RenameDownloadAsset,\n ReorderDownloadAssets,\n UpdateBundle,\n UpdateDownload,\n} from '../../schemas/index.js';\nimport { defineTool, type Tool } from '../tool.js';\n\nexport const catalogTools: Tool[] = [\n defineTool({\n name: 'list_downloads',\n title: 'List downloads',\n description:\n 'Search and page through downloads: file collections a student can be granted. Filter by status or category.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: DownloadsQuery,\n call: (input, { container, caller }) => container.content.listDownloads(input, caller.actor),\n }),\n defineTool({\n name: 'list_download_files',\n title: 'List download files',\n description: 'The files of a download, in order, with their display names.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: DownloadIdParam,\n call: ({ downloadId }, { container, caller }) =>\n container.content.listDownloadAssets(downloadId, caller.actor),\n }),\n defineTool({\n name: 'create_download',\n title: 'Create download',\n description:\n 'Create a draft download. Add files with add_download_file and publish it with update_download.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: CreateDownload,\n call: (input, { container, caller }) => container.content.createDownload(input, caller.actor),\n }),\n defineTool({\n name: 'update_download',\n title: 'Update download',\n description:\n 'Change a download title, description, category or cover image, or publish and unpublish it with status. Fields left out stay as they are.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateDownload.extend(DownloadIdParam.shape),\n call: ({ downloadId, ...patch }, { container, caller }) =>\n container.content.updateDownload(downloadId, patch, caller.actor),\n }),\n defineTool({\n name: 'add_download_file',\n title: 'Add file to download',\n description: 'Add an uploaded file to the end of a download. Find file ids with list_media.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: AddDownloadAsset.extend(DownloadIdParam.shape),\n call: ({ downloadId, ...file }, { container, caller }) =>\n container.content.addDownloadAsset(downloadId, file, caller.actor),\n }),\n defineTool({\n name: 'rename_download_file',\n title: 'Rename download file',\n description: 'Set the name a file shows under in a download. null shows the file name.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: RenameDownloadAsset.extend(DownloadAssetParams.shape),\n call: ({ downloadId, assetId, displayName }, { container, caller }) =>\n container.content.renameDownloadAsset(downloadId, assetId, displayName, caller.actor),\n }),\n defineTool({\n name: 'reorder_download_files',\n title: 'Reorder download files',\n description:\n 'Set the file order of a download. Pass every file id of the download in the new order.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: ReorderDownloadAssets.extend(DownloadIdParam.shape),\n call: ({ downloadId, assetIds }, { container, caller }) =>\n container.content.reorderDownloadAssets(downloadId, assetIds, caller.actor),\n }),\n defineTool({\n name: 'remove_download_file',\n title: 'Remove file from download',\n description: 'Take a file out of a download. The uploaded file itself is kept.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: DownloadAssetParams,\n call: ({ downloadId, assetId }, { container, caller }) =>\n container.content.removeDownloadAsset(downloadId, assetId, caller.actor),\n }),\n defineTool({\n name: 'delete_download',\n title: 'Delete download',\n description: 'Permanently delete a download. The uploaded files are kept.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: DownloadIdParam,\n call: ({ downloadId }, { container, caller }) =>\n container.content.removeDownload(downloadId, caller.actor),\n }),\n defineTool({\n name: 'list_bundles',\n title: 'List bundles',\n description:\n 'Search and page through bundles: sets of courses, downloads, communities and events granted together.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: BundlesQuery,\n call: (input, { container, caller }) => container.content.listBundles(input, caller.actor),\n }),\n defineTool({\n name: 'list_bundle_items',\n title: 'List bundle items',\n description: 'The courses, downloads, communities and events in a bundle.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: BundleIdParam,\n call: ({ bundleId }, { container, caller }) =>\n container.content.listBundleItems(bundleId, caller.actor),\n }),\n defineTool({\n name: 'create_bundle',\n title: 'Create bundle',\n description:\n 'Create a bundle, optionally with the course, download, community and event ids it starts with.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: CreateBundle,\n call: (input, { container, caller }) => container.content.createBundle(input, caller.actor),\n }),\n defineTool({\n name: 'rename_bundle',\n title: 'Rename bundle',\n description: 'Rename a bundle.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: UpdateBundle.extend(BundleIdParam.shape),\n call: ({ bundleId, ...patch }, { container, caller }) =>\n container.content.updateBundle(bundleId, patch, caller.actor),\n }),\n defineTool({\n name: 'add_bundle_item',\n title: 'Add to bundle',\n description:\n 'Add a course, download, community or event to a bundle. Returns the bundle items.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: AddBundleItem.extend(BundleIdParam.shape),\n call: ({ bundleId, contentId }, { container, caller }) =>\n container.content.addBundleItem(bundleId, contentId, caller.actor),\n }),\n defineTool({\n name: 'remove_bundle_item',\n title: 'Remove from bundle',\n description:\n 'Take a course, download, community or event out of a bundle. Returns the remaining items.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: BundleItemParams,\n call: ({ bundleId, contentId }, { container, caller }) =>\n container.content.removeBundleItem(bundleId, contentId, caller.actor),\n }),\n defineTool({\n name: 'delete_bundle',\n title: 'Delete bundle',\n description:\n 'Permanently delete a bundle. Its courses, downloads, communities and events are kept.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: BundleIdParam,\n call: ({ bundleId }, { container, caller }) =>\n container.content.deleteBundle(bundleId, caller.actor),\n }),\n defineTool({\n name: 'list_media',\n title: 'List media',\n description:\n 'Search and page through uploaded files, to use in downloads and events or as cover images of courses, downloads, communities and events. Uploading is done in the admin app.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: AssetsQuery,\n output: AssetsPage,\n call: (input, { container, caller }) => container.assets.list(input, caller.actor),\n }),\n];\n"],"mappings":"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"}
|
|
@@ -1,67 +1,57 @@
|
|
|
1
|
-
import { CommentIdParam, CommentsQuery,
|
|
1
|
+
import { CommentIdParam, CommentsQuery, ReplyToComment } from "../../schemas/discussion.js";
|
|
2
2
|
import "../../schemas/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { defineTool } from "../tool.js";
|
|
4
4
|
//#region src/http/mcp/tools/comments.ts
|
|
5
5
|
const commentTools = [
|
|
6
6
|
defineTool({
|
|
7
7
|
name: "list_comments",
|
|
8
8
|
title: "List comments",
|
|
9
9
|
description: "The comment moderation queue. Filter by status, reported, course, activity or author. Each comment carries its activityId and parentId.",
|
|
10
|
-
scope: "comments:read",
|
|
11
10
|
kind: "read",
|
|
12
11
|
idempotent: true,
|
|
13
12
|
openWorld: false,
|
|
14
13
|
input: CommentsQuery,
|
|
15
|
-
call: (input, { container,
|
|
14
|
+
call: (input, { container, caller }) => container.discussion.listComments(input, caller.actor)
|
|
16
15
|
}),
|
|
17
16
|
defineTool({
|
|
18
17
|
name: "publish_comment",
|
|
19
18
|
title: "Publish comment",
|
|
20
19
|
description: "Publish a comment: approves one waiting for review, or restores a removed one.",
|
|
21
|
-
scope: "comments:moderate",
|
|
22
20
|
kind: "write",
|
|
23
21
|
idempotent: true,
|
|
24
22
|
openWorld: false,
|
|
25
23
|
input: CommentIdParam,
|
|
26
|
-
call: ({ commentId }, { container,
|
|
24
|
+
call: ({ commentId }, { container, caller }) => container.discussion.publish(commentId, "lesson", caller.actor)
|
|
27
25
|
}),
|
|
28
26
|
defineTool({
|
|
29
27
|
name: "dismiss_comment_reports",
|
|
30
28
|
title: "Dismiss comment reports",
|
|
31
29
|
description: "Mark the reports on a comment as resolved. The comment's status does not change.",
|
|
32
|
-
scope: "comments:moderate",
|
|
33
30
|
kind: "write",
|
|
34
31
|
idempotent: true,
|
|
35
32
|
openWorld: false,
|
|
36
33
|
input: CommentIdParam,
|
|
37
|
-
call: ({ commentId }, { container,
|
|
34
|
+
call: ({ commentId }, { container, caller }) => container.discussion.resolveReports(commentId, "lesson", caller.actor)
|
|
38
35
|
}),
|
|
39
36
|
defineTool({
|
|
40
37
|
name: "reply_to_comment",
|
|
41
38
|
title: "Reply to comment",
|
|
42
|
-
description: "Reply to a published
|
|
43
|
-
scope: "comments:moderate",
|
|
39
|
+
description: "Reply to a published comment as yourself. A reply to a reply attaches to its top-level comment.",
|
|
44
40
|
kind: "write",
|
|
45
41
|
idempotent: false,
|
|
46
42
|
openWorld: false,
|
|
47
|
-
input: ReplyToComment.extend(CommentIdParam.shape)
|
|
48
|
-
call: ({
|
|
49
|
-
actor: actor(scope),
|
|
50
|
-
activityId,
|
|
51
|
-
parentId: commentId,
|
|
52
|
-
body
|
|
53
|
-
})
|
|
43
|
+
input: ReplyToComment.extend(CommentIdParam.shape),
|
|
44
|
+
call: ({ commentId, body }, { container, caller }) => container.discussion.replyToComment(commentId, body, caller.actor)
|
|
54
45
|
}),
|
|
55
46
|
defineTool({
|
|
56
47
|
name: "remove_comment",
|
|
57
48
|
title: "Remove comment",
|
|
58
49
|
description: "Take a comment down.",
|
|
59
|
-
scope: "comments:moderate",
|
|
60
50
|
kind: "destructive",
|
|
61
51
|
idempotent: true,
|
|
62
52
|
openWorld: false,
|
|
63
53
|
input: CommentIdParam,
|
|
64
|
-
call: ({ commentId }, { container,
|
|
54
|
+
call: ({ commentId }, { container, caller }) => container.discussion.remove(commentId, "lesson", caller.actor)
|
|
65
55
|
})
|
|
66
56
|
];
|
|
67
57
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.js","names":[],"sources":["../../../../src/http/mcp/tools/comments.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"comments.js","names":[],"sources":["../../../../src/http/mcp/tools/comments.ts"],"sourcesContent":["import { CommentIdParam, CommentsQuery, ReplyToComment } from '../../schemas/index.js';\nimport { defineTool, type Tool } from '../tool.js';\n\nexport const commentTools: Tool[] = [\n defineTool({\n name: 'list_comments',\n title: 'List comments',\n description:\n 'The comment moderation queue. Filter by status, reported, course, activity or author. Each comment carries its activityId and parentId.',\n kind: 'read',\n idempotent: true,\n openWorld: false,\n input: CommentsQuery,\n call: (input, { container, caller }) => container.discussion.listComments(input, caller.actor),\n }),\n defineTool({\n name: 'publish_comment',\n title: 'Publish comment',\n description: 'Publish a comment: approves one waiting for review, or restores a removed one.',\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: CommentIdParam,\n call: ({ commentId }, { container, caller }) =>\n container.discussion.publish(commentId, 'lesson', caller.actor),\n }),\n defineTool({\n name: 'dismiss_comment_reports',\n title: 'Dismiss comment reports',\n description: \"Mark the reports on a comment as resolved. The comment's status does not change.\",\n kind: 'write',\n idempotent: true,\n openWorld: false,\n input: CommentIdParam,\n call: ({ commentId }, { container, caller }) =>\n container.discussion.resolveReports(commentId, 'lesson', caller.actor),\n }),\n defineTool({\n name: 'reply_to_comment',\n title: 'Reply to comment',\n description:\n 'Reply to a published comment as yourself. A reply to a reply attaches to its top-level comment.',\n kind: 'write',\n idempotent: false,\n openWorld: false,\n input: ReplyToComment.extend(CommentIdParam.shape),\n call: ({ commentId, body }, { container, caller }) =>\n container.discussion.replyToComment(commentId, body, caller.actor),\n }),\n defineTool({\n name: 'remove_comment',\n title: 'Remove comment',\n description: 'Take a comment down.',\n kind: 'destructive',\n idempotent: true,\n openWorld: false,\n input: CommentIdParam,\n call: ({ commentId }, { container, caller }) =>\n container.discussion.remove(commentId, 'lesson', caller.actor),\n }),\n];\n"],"mappings":";;;;AAGA,MAAa,eAAuB;CAClC,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,OAAO,EAAE,WAAW,aAAa,UAAU,WAAW,aAAa,OAAO,OAAO,KAAK;CAC/F,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,aAAa,EAAE,WAAW,aACjC,UAAU,WAAW,QAAQ,WAAW,UAAU,OAAO,KAAK;CAClE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,aAAa,EAAE,WAAW,aACjC,UAAU,WAAW,eAAe,WAAW,UAAU,OAAO,KAAK;CACzE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO,eAAe,OAAO,eAAe,KAAK;EACjD,OAAO,EAAE,WAAW,QAAQ,EAAE,WAAW,aACvC,UAAU,WAAW,eAAe,WAAW,MAAM,OAAO,KAAK;CACrE,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,YAAY;EACZ,WAAW;EACX,OAAO;EACP,OAAO,EAAE,aAAa,EAAE,WAAW,aACjC,UAAU,WAAW,OAAO,WAAW,UAAU,OAAO,KAAK;CACjE,CAAC;AACH"}
|