@decocms/bindings 1.2.1 → 1.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/bindings",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",
@@ -58,13 +58,17 @@ export interface PluginRenderHeaderProps {
58
58
  * Client plugins are separate from server plugins to avoid bundling
59
59
  * server code into the client bundle.
60
60
  */
61
- export interface ClientPlugin<TBinding extends Binder> {
61
+ export interface ClientPlugin<TBinding extends Binder = Binder> {
62
62
  id: string;
63
63
  /**
64
64
  * Short description of the plugin shown in the settings UI.
65
65
  */
66
66
  description?: string;
67
- binding: TBinding;
67
+ /**
68
+ * Binding schema used to filter compatible connections.
69
+ * Omit for plugins that manage their own connection (e.g. self MCP).
70
+ */
71
+ binding?: TBinding;
68
72
  setup?: PluginSetup;
69
73
  /**
70
74
  * Optional custom layout component for this plugin.
@@ -16,15 +16,45 @@ import type { Hono } from "hono";
16
16
  import type { Kysely } from "kysely";
17
17
 
18
18
  /**
19
- * Tool definition compatible with MCP tools.
20
- * This is a simplified type - the actual implementation uses the full ToolDefinition from mesh.
19
+ * Subset of MeshContext exposed to server plugin tool handlers.
20
+ *
21
+ * Plugins receive the full MeshContext at runtime but should only depend on
22
+ * these properties. This keeps the plugin contract stable and avoids coupling
23
+ * plugins to Mesh internals (db, vault, tracer, etc.).
24
+ */
25
+ export interface ServerPluginToolContext {
26
+ organization: { id: string } | null;
27
+ access: { check: () => Promise<void> };
28
+ auth: {
29
+ user?: { id: string; email?: string; name?: string };
30
+ };
31
+ /** Kysely database instance for direct queries. */
32
+ db: Kysely<unknown>;
33
+ createMCPProxy: (connectionId: string) => Promise<{
34
+ callTool: (args: {
35
+ name: string;
36
+ arguments?: Record<string, unknown>;
37
+ }) => Promise<{
38
+ isError?: boolean;
39
+ content?: Array<{ type?: string; text?: string }>;
40
+ structuredContent?: unknown;
41
+ }>;
42
+ listTools: () => Promise<{
43
+ tools: Array<{ name: string; description?: string }>;
44
+ }>;
45
+ close?: () => Promise<void>;
46
+ }>;
47
+ }
48
+
49
+ /**
50
+ * Tool definition for server plugins.
21
51
  */
22
52
  export interface ServerPluginToolDefinition {
23
53
  name: string;
24
54
  description?: string;
25
55
  inputSchema: unknown;
26
56
  outputSchema?: unknown;
27
- handler: (input: unknown, ctx: unknown) => Promise<unknown>;
57
+ handler: (input: unknown, ctx: ServerPluginToolContext) => Promise<unknown>;
28
58
  }
29
59
 
30
60
  /**
package/src/index.ts CHANGED
@@ -104,3 +104,27 @@ export {
104
104
 
105
105
  // Re-export workflow binding types
106
106
  export { WORKFLOWS_COLLECTION_BINDING } from "./well-known/workflow";
107
+
108
+ // Re-export reports binding types
109
+ export {
110
+ REPORTS_BINDING,
111
+ type ReportsBinding,
112
+ type ReportStatus,
113
+ type ReportLifecycleStatus,
114
+ type MetricItem,
115
+ type ReportSection,
116
+ type ReportSummary,
117
+ type Report,
118
+ type ReportsListInput,
119
+ type ReportsListOutput,
120
+ type ReportsGetInput,
121
+ type ReportsGetOutput,
122
+ type ReportsUpdateStatusInput,
123
+ type ReportsUpdateStatusOutput,
124
+ ReportStatusSchema,
125
+ ReportLifecycleStatusSchema,
126
+ MetricItemSchema,
127
+ ReportSectionSchema,
128
+ ReportSummarySchema,
129
+ ReportSchema,
130
+ } from "./well-known/reports";
@@ -166,7 +166,10 @@ const ToolCallOutputPartSchema = z.object({
166
166
 
167
167
  /**
168
168
  * Tool Result Output Schema
169
- * The output of a tool result
169
+ * The output of a tool result.
170
+ * Accepts typed objects (text, json, error-text, error-json, content),
171
+ * execution-denied (from AI SDK tool approval flow), and raw strings
172
+ * (JSON-serialized outputs from mapToolResultOutput).
170
173
  */
171
174
  const ToolResultOutputSchema = z.union([
172
175
  z.object({
@@ -201,6 +204,15 @@ const ToolResultOutputSchema = z.union([
201
204
  ]),
202
205
  ),
203
206
  }),
207
+ z.object({
208
+ type: z.literal("execution-denied"),
209
+ reason: z.string().optional(),
210
+ }),
211
+ z
212
+ .string()
213
+ .describe(
214
+ "Raw or JSON-serialized output (e.g. from AI SDK mapToolResultOutput)",
215
+ ),
204
216
  ]);
205
217
 
206
218
  /**
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Reports Well-Known Binding
3
+ *
4
+ * Defines the interface for viewing automated reports.
5
+ * Any MCP that implements this binding can provide reports to the Reports plugin
6
+ * (e.g. performance audits, security scans, accessibility checks).
7
+ *
8
+ * This binding includes:
9
+ * - REPORTS_LIST: List all available reports with metadata
10
+ * - REPORTS_GET: Get a specific report with full content
11
+ */
12
+
13
+ import { z } from "zod";
14
+ import type { Binder, ToolBinder } from "../core/binder";
15
+
16
+ // ============================================================================
17
+ // Shared Schemas
18
+ // ============================================================================
19
+
20
+ /**
21
+ * Report status indicates the overall health/outcome of the report.
22
+ */
23
+ export const ReportStatusSchema = z.enum([
24
+ "passing",
25
+ "warning",
26
+ "failing",
27
+ "info",
28
+ ]);
29
+ export type ReportStatus = z.infer<typeof ReportStatusSchema>;
30
+
31
+ /**
32
+ * A single metric item within a metrics section.
33
+ */
34
+ export const MetricItemSchema = z.object({
35
+ label: z.string().describe("Metric label (e.g. 'LCP', 'Performance')"),
36
+ value: z.union([z.number(), z.string()]).describe("Current metric value"),
37
+ unit: z
38
+ .string()
39
+ .optional()
40
+ .describe("Unit of measurement (e.g. 's', 'ms', 'score')"),
41
+ previousValue: z
42
+ .union([z.number(), z.string()])
43
+ .optional()
44
+ .describe("Previous value for delta comparison"),
45
+ status: ReportStatusSchema.optional().describe(
46
+ "Status of this individual metric",
47
+ ),
48
+ });
49
+ export type MetricItem = z.infer<typeof MetricItemSchema>;
50
+
51
+ /**
52
+ * Report sections -- polymorphic by type.
53
+ * Sections represent the main content blocks of a report.
54
+ */
55
+ export const ReportSectionSchema = z.discriminatedUnion("type", [
56
+ z.object({
57
+ type: z.literal("markdown"),
58
+ content: z.string().describe("Markdown content"),
59
+ }),
60
+ z.object({
61
+ type: z.literal("metrics"),
62
+ title: z.string().optional().describe("Section title"),
63
+ items: z.array(MetricItemSchema).describe("Metric items"),
64
+ }),
65
+ z.object({
66
+ type: z.literal("table"),
67
+ title: z.string().optional().describe("Section title"),
68
+ columns: z.array(z.string()).describe("Column headers"),
69
+ rows: z
70
+ .array(z.array(z.union([z.string(), z.number(), z.null()])))
71
+ .describe("Table rows"),
72
+ }),
73
+ ]);
74
+ export type ReportSection = z.infer<typeof ReportSectionSchema>;
75
+
76
+ /**
77
+ * Lifecycle status of a report within the inbox workflow.
78
+ */
79
+ export const ReportLifecycleStatusSchema = z.enum([
80
+ "unread",
81
+ "read",
82
+ "dismissed",
83
+ ]);
84
+ export type ReportLifecycleStatus = z.infer<typeof ReportLifecycleStatusSchema>;
85
+
86
+ /**
87
+ * Summary of a report returned by REPORTS_LIST.
88
+ */
89
+ export const ReportSummarySchema = z.object({
90
+ id: z.string().describe("Unique report identifier"),
91
+ title: z.string().describe("Report title"),
92
+ category: z
93
+ .string()
94
+ .describe(
95
+ "Report category (e.g. 'performance', 'security', 'accessibility')",
96
+ ),
97
+ status: ReportStatusSchema.describe("Overall report status"),
98
+ summary: z.string().describe("One-line summary of findings"),
99
+ updatedAt: z.string().describe("ISO 8601 timestamp of last update"),
100
+ source: z
101
+ .string()
102
+ .optional()
103
+ .describe(
104
+ "Agent or service that generated the report (e.g. 'security-auditor', 'performance-monitor')",
105
+ ),
106
+ tags: z
107
+ .array(z.string())
108
+ .optional()
109
+ .describe("Free-form tags for filtering (e.g. 'homepage', 'api', 'ci')"),
110
+ lifecycleStatus: ReportLifecycleStatusSchema.optional().describe(
111
+ "Inbox lifecycle status of the report (default: unread)",
112
+ ),
113
+ });
114
+ export type ReportSummary = z.infer<typeof ReportSummarySchema>;
115
+
116
+ /**
117
+ * Full report returned by REPORTS_GET.
118
+ */
119
+ export const ReportSchema = ReportSummarySchema.extend({
120
+ sections: z.array(ReportSectionSchema).describe("Ordered content sections"),
121
+ });
122
+ export type Report = z.infer<typeof ReportSchema>;
123
+
124
+ // ============================================================================
125
+ // Tool Schemas
126
+ // ============================================================================
127
+
128
+ /**
129
+ * REPORTS_LIST - List all available reports with optional filters
130
+ */
131
+ const ReportsListInputSchema = z.object({
132
+ category: z
133
+ .string()
134
+ .optional()
135
+ .describe("Filter by category (e.g. 'performance', 'security')"),
136
+ status: ReportStatusSchema.optional().describe("Filter by report status"),
137
+ });
138
+
139
+ const ReportsListOutputSchema = z.object({
140
+ reports: z.array(ReportSummarySchema).describe("List of report summaries"),
141
+ });
142
+
143
+ export type ReportsListInput = z.infer<typeof ReportsListInputSchema>;
144
+ export type ReportsListOutput = z.infer<typeof ReportsListOutputSchema>;
145
+
146
+ /**
147
+ * REPORTS_GET - Get a specific report with full content
148
+ */
149
+ const ReportsGetInputSchema = z.object({
150
+ id: z.string().describe("Report identifier"),
151
+ });
152
+
153
+ const ReportsGetOutputSchema = ReportSchema;
154
+
155
+ export type ReportsGetInput = z.infer<typeof ReportsGetInputSchema>;
156
+ export type ReportsGetOutput = z.infer<typeof ReportsGetOutputSchema>;
157
+
158
+ /**
159
+ * REPORTS_UPDATE_STATUS - Update the lifecycle status of a report (optional tool)
160
+ */
161
+ const ReportsUpdateStatusInputSchema = z.object({
162
+ reportId: z.string().describe("Report identifier"),
163
+ lifecycleStatus: ReportLifecycleStatusSchema.describe(
164
+ "New lifecycle status for the report",
165
+ ),
166
+ });
167
+
168
+ const ReportsUpdateStatusOutputSchema = z.object({
169
+ success: z.boolean().describe("Whether the operation succeeded"),
170
+ message: z.string().optional().describe("Human-readable result message"),
171
+ });
172
+
173
+ export type ReportsUpdateStatusInput = z.infer<
174
+ typeof ReportsUpdateStatusInputSchema
175
+ >;
176
+ export type ReportsUpdateStatusOutput = z.infer<
177
+ typeof ReportsUpdateStatusOutputSchema
178
+ >;
179
+
180
+ // ============================================================================
181
+ // Binding Definition
182
+ // ============================================================================
183
+
184
+ /**
185
+ * Reports Binding
186
+ *
187
+ * Defines the interface for viewing automated reports.
188
+ * Any MCP that implements this binding can be used with the Reports plugin.
189
+ *
190
+ * Required tools:
191
+ * - REPORTS_LIST: List available reports with optional filtering
192
+ * - REPORTS_GET: Get a single report with full content
193
+ *
194
+ * Optional tools:
195
+ * - REPORTS_UPDATE_STATUS: Update the lifecycle status of a report (unread → read → dismissed)
196
+ */
197
+ export const REPORTS_BINDING = [
198
+ {
199
+ name: "REPORTS_LIST" as const,
200
+ inputSchema: ReportsListInputSchema,
201
+ outputSchema: ReportsListOutputSchema,
202
+ } satisfies ToolBinder<"REPORTS_LIST", ReportsListInput, ReportsListOutput>,
203
+ {
204
+ name: "REPORTS_GET" as const,
205
+ inputSchema: ReportsGetInputSchema,
206
+ outputSchema: ReportsGetOutputSchema,
207
+ } satisfies ToolBinder<"REPORTS_GET", ReportsGetInput, ReportsGetOutput>,
208
+ {
209
+ name: "REPORTS_UPDATE_STATUS" as const,
210
+ inputSchema: ReportsUpdateStatusInputSchema,
211
+ outputSchema: ReportsUpdateStatusOutputSchema,
212
+ opt: true,
213
+ } satisfies ToolBinder<
214
+ "REPORTS_UPDATE_STATUS",
215
+ ReportsUpdateStatusInput,
216
+ ReportsUpdateStatusOutput
217
+ >,
218
+ ] as const satisfies Binder;
219
+
220
+ export type ReportsBinding = typeof REPORTS_BINDING;