@cloudhal/mcp-server 0.0.0-stage → 0.1.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.
Files changed (105) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +18 -2
  3. package/dist/src/analytics-reports.d.ts +164 -0
  4. package/dist/src/analytics-reports.js +632 -0
  5. package/dist/src/analytics-tools.d.ts +4 -0
  6. package/dist/src/analytics-tools.js +597 -0
  7. package/dist/src/asset-tools.d.ts +5 -0
  8. package/dist/src/asset-tools.js +685 -0
  9. package/dist/src/body-tools.d.ts +46 -0
  10. package/dist/src/body-tools.js +708 -0
  11. package/dist/src/changes.d.ts +10 -0
  12. package/dist/src/changes.js +112 -0
  13. package/dist/src/chrome-tools.d.ts +8 -0
  14. package/dist/src/chrome-tools.js +207 -0
  15. package/dist/src/comment-tools.d.ts +9 -0
  16. package/dist/src/comment-tools.js +743 -0
  17. package/dist/src/comments.d.ts +184 -0
  18. package/dist/src/comments.js +408 -0
  19. package/dist/src/common.d.ts +258 -0
  20. package/dist/src/common.js +488 -0
  21. package/dist/src/content-shared.d.ts +50 -0
  22. package/dist/src/content-shared.js +102 -0
  23. package/dist/src/design-tools.d.ts +9 -0
  24. package/dist/src/design-tools.js +349 -0
  25. package/dist/src/elevation-tools.d.ts +3 -0
  26. package/dist/src/elevation-tools.js +331 -0
  27. package/dist/src/entry-terms.d.ts +14 -0
  28. package/dist/src/entry-terms.js +51 -0
  29. package/dist/src/entry-tools.d.ts +4 -0
  30. package/dist/src/entry-tools.js +442 -0
  31. package/dist/src/http.d.ts +48 -0
  32. package/dist/src/http.js +101 -0
  33. package/dist/src/index.d.ts +10 -0
  34. package/dist/src/index.js +10 -0
  35. package/dist/src/menu-tools.d.ts +41 -0
  36. package/dist/src/menu-tools.js +1058 -0
  37. package/dist/src/page-tools.d.ts +5 -0
  38. package/dist/src/page-tools.js +311 -0
  39. package/dist/src/preview-doc.d.ts +9 -0
  40. package/dist/src/preview-doc.js +56 -0
  41. package/dist/src/preview-view.d.ts +19 -0
  42. package/dist/src/preview-view.js +71 -0
  43. package/dist/src/publish-tools.d.ts +10 -0
  44. package/dist/src/publish-tools.js +248 -0
  45. package/dist/src/render/cdp.d.ts +29 -0
  46. package/dist/src/render/cdp.js +190 -0
  47. package/dist/src/render/checks/components.d.ts +5 -0
  48. package/dist/src/render/checks/components.js +95 -0
  49. package/dist/src/render/checks/content.d.ts +5 -0
  50. package/dist/src/render/checks/content.js +63 -0
  51. package/dist/src/render/checks/contrast.d.ts +5 -0
  52. package/dist/src/render/checks/contrast.js +72 -0
  53. package/dist/src/render/checks/index.d.ts +1 -0
  54. package/dist/src/render/checks/index.js +29 -0
  55. package/dist/src/render/checks/layout.d.ts +5 -0
  56. package/dist/src/render/checks/layout.js +44 -0
  57. package/dist/src/render/checks/motion.d.ts +5 -0
  58. package/dist/src/render/checks/motion.js +66 -0
  59. package/dist/src/render/checks/navigation.d.ts +5 -0
  60. package/dist/src/render/checks/navigation.js +78 -0
  61. package/dist/src/render/checks/prelude.d.ts +1 -0
  62. package/dist/src/render/checks/prelude.js +64 -0
  63. package/dist/src/render/limiter.d.ts +11 -0
  64. package/dist/src/render/limiter.js +29 -0
  65. package/dist/src/render/page.d.ts +19 -0
  66. package/dist/src/render/page.js +135 -0
  67. package/dist/src/render/types.d.ts +89 -0
  68. package/dist/src/render/types.js +140 -0
  69. package/dist/src/render-tools.d.ts +14 -0
  70. package/dist/src/render-tools.js +314 -0
  71. package/dist/src/render.d.ts +14 -0
  72. package/dist/src/render.js +33 -0
  73. package/dist/src/schedule-tools.d.ts +2 -0
  74. package/dist/src/schedule-tools.js +1596 -0
  75. package/dist/src/schedules.d.ts +292 -0
  76. package/dist/src/schedules.js +890 -0
  77. package/dist/src/schema-transforms.d.ts +14 -0
  78. package/dist/src/schema-transforms.js +50 -0
  79. package/dist/src/search-tools.d.ts +2 -0
  80. package/dist/src/search-tools.js +112 -0
  81. package/dist/src/server-approvals.d.ts +51 -0
  82. package/dist/src/server-approvals.js +273 -0
  83. package/dist/src/server-call.d.ts +28 -0
  84. package/dist/src/server-call.js +259 -0
  85. package/dist/src/server-instructions.d.ts +4 -0
  86. package/dist/src/server-instructions.js +74 -0
  87. package/dist/src/server-resources.d.ts +4 -0
  88. package/dist/src/server-resources.js +83 -0
  89. package/dist/src/server-schema.d.ts +20 -0
  90. package/dist/src/server-schema.js +82 -0
  91. package/dist/src/server.d.ts +80 -0
  92. package/dist/src/server.js +135 -0
  93. package/dist/src/stdio.d.ts +9 -0
  94. package/dist/src/stdio.js +18 -0
  95. package/dist/src/surface-tools.d.ts +4 -0
  96. package/dist/src/surface-tools.js +357 -0
  97. package/dist/src/taxonomy-tools.d.ts +16 -0
  98. package/dist/src/taxonomy-tools.js +1433 -0
  99. package/dist/src/terms.d.ts +47 -0
  100. package/dist/src/terms.js +271 -0
  101. package/dist/src/tools.d.ts +39 -0
  102. package/dist/src/tools.js +511 -0
  103. package/dist/src/translation-tools.d.ts +3 -0
  104. package/dist/src/translation-tools.js +422 -0
  105. package/package.json +86 -3
@@ -0,0 +1,258 @@
1
+ /**
2
+ * What every tool module shares: the SDK-independent tool shape, the call context, `ToolError` and
3
+ * the mapping of store errors to it (stable codes, actionable text), and small schema/prompt helpers.
4
+ */
5
+ import { type ApprovalStore, type AuditLog, type CallClass, type Decision, type OwnershipResolver, type OwnLimit, type PolicyEngine, type Principal, type Scope, type ToolAnnotations } from "@cloudhal/agent-runtime";
6
+ import type { AnalyticsService } from "@cloudhal/analytics/service";
7
+ import type { Actor, ContentEntry, Page, Site, Snapshot } from "@cloudhal/core-contracts";
8
+ import type { InvariantCode, SiteGraphStore } from "@cloudhal/core-ts";
9
+ import type { BodyDiff } from "@cloudhal/core-ts/body-blocks";
10
+ import type { FetchTransport } from "@cloudhal/core-ts/media";
11
+ import type { CommentsDeps } from "./comments.js";
12
+ import type { PageRenderer, RenderLimiter } from "./render.js";
13
+ import { type RunContext, type SchedulesDeps } from "./schedules.js";
14
+ export type JsonSchema = Record<string, unknown>;
15
+ export interface ToolDefinition {
16
+ name: string;
17
+ title: string;
18
+ description: string;
19
+ inputSchema: JsonSchema;
20
+ outputSchema: JsonSchema;
21
+ annotations: ToolAnnotations;
22
+ scopes: Scope[];
23
+ /**
24
+ * MCP Apps (RFC-0020 §6): the View a host shows with this tool's results
25
+ * (`_meta.ui.resourceUri`); `visibility` defaults to the model and the View.
26
+ */
27
+ ui?: {
28
+ readonly resourceUri: string;
29
+ readonly visibility?: readonly ("model" | "app")[];
30
+ };
31
+ requiresApproval?: boolean;
32
+ /** Human-readable question shown in the approval gate. */
33
+ approvalPrompt?: (args: Record<string, unknown>, ctx: ToolContext) => Promise<string>;
34
+ /**
35
+ * Agent-layer refusals (RFC-0002 §6.4: who may create terms, external redirect targets, approving
36
+ * one's own proposal). Runs after the scope check and before anyone is asked to approve, so a call
37
+ * that cannot succeed never waits for a person; a throw is audited as a denial.
38
+ */
39
+ precheck?: (args: Record<string, unknown>, ctx: ToolContext) => Promise<void>;
40
+ /**
41
+ * The own variants of the tool's scope satisfy it with a limit (RFC-0005 §9): `entry` — the
42
+ * handler (and `precheck`) check the target with `entryLimitCheck`; `changeset` — `runTool`
43
+ * checks that a publish is own-only.
44
+ */
45
+ own?: "entry" | "changeset" | "comment" | "release";
46
+ /**
47
+ * Per-argument policy (RFC-0007 §10.2): `read`, `advisory`, `reduce` or `person`. `person`
48
+ * calls wait for a person in every mode, `bypass` included.
49
+ */
50
+ classify?: (args: Record<string, unknown>) => CallClass | undefined;
51
+ /** The scopes a `propose` call needs instead of `scopes` (ADR-0028). */
52
+ proposeScopes?: Scope[];
53
+ /**
54
+ * What the call would change, for a person deciding its approval request (RFC-0014 §5): Studio
55
+ * lists it with the request. Computed against the current state when the request is listed.
56
+ */
57
+ changes?: (args: Record<string, unknown>, ctx: ToolContext) => Promise<ApprovalChanges>;
58
+ /**
59
+ * What an approval of this call is bound to, instead of the site graph's `stateHash` (RFC-0007
60
+ * §10.3): comment tools bind to the `cm1:` hash of the comments and threads they name.
61
+ */
62
+ bindState?: (args: Record<string, unknown>, ctx: ToolContext) => Promise<string>;
63
+ /**
64
+ * Approving a request for this tool in Studio runs it at once as the approving person
65
+ * (RFC-0007 §10.3); the agent never redeems it.
66
+ */
67
+ carryOutOnApproval?: boolean;
68
+ /**
69
+ * RFC-0008 §10.4: the tool files its own approval request (a release bound to its `rl1:` hash,
70
+ * open until the release's time) instead of the generic gate. When the decision for an agent is
71
+ * `approval-required` and the server has out-of-band approvals — or `auto` mode offers the
72
+ * low-risk path — the handler runs with `ctx.pending` set and answers `approval-pending` itself.
73
+ */
74
+ handlesApproval?: boolean;
75
+ /**
76
+ * The text content of a result (default: the result as JSON). Comment tools write reader text
77
+ * inside labelled untrusted blocks (RFC-0007 §11.2).
78
+ */
79
+ renderText?: (result: unknown) => string;
80
+ /**
81
+ * Rich content for a result (RFC-0021 §4: `render_page`'s screenshots): the blocks a client
82
+ * shows, and the structured result without the bytes. Takes precedence over `renderText`.
83
+ */
84
+ renderContent?: (result: unknown) => {
85
+ content: ToolContent[];
86
+ structured: Record<string, unknown>;
87
+ };
88
+ handler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<unknown>;
89
+ /**
90
+ * What the audit log keeps of the arguments (default: all of them, truncated). `upload_asset`
91
+ * replaces its base64 payload with its size, so file bytes never land in the audit table.
92
+ */
93
+ auditArgs?: (args: Record<string, unknown>) => Record<string, unknown>;
94
+ }
95
+ /** A content block of a tool result (the MCP shapes Cloudhal uses). */
96
+ export type ToolContent = {
97
+ type: "text";
98
+ text: string;
99
+ } | {
100
+ type: "image";
101
+ data: string;
102
+ mimeType: string;
103
+ };
104
+ /** Media settings of a deployment for the asset tools (RFC-0004 §5.6–§5.7). */
105
+ export interface MediaToolOptions {
106
+ /**
107
+ * How `fetch_asset_url` reaches the network: `nodeTransport()` from `@cloudhal/core-ts/media-node`
108
+ * on Node (resolves, checks and pins every address), `workersTransport()` (the default) on Workers.
109
+ */
110
+ fetchTransport?: FetchTransport | undefined;
111
+ /** Hosts agents may fetch from, for every site (each site may add `cloudhal.media.allowHosts`). */
112
+ allowHosts?: readonly string[] | undefined;
113
+ /** This deployment's own hosts (Studio, admin API, workers.dev): never fetched. */
114
+ blockedHosts?: readonly string[] | undefined;
115
+ /** Per agent key per day (default 100 assets and 500 MB; audited as a denial when exceeded). */
116
+ agentDailyAssets?: number | undefined;
117
+ agentDailyBytes?: number | undefined;
118
+ }
119
+ /** What `render_page` renders with (RFC-0021 §4). */
120
+ export interface RenderDeps {
121
+ readonly renderer: PageRenderer;
122
+ /** Defaults to one shared per process: 10 a minute per key, 200 a day per site. */
123
+ readonly limiter?: RenderLimiter | undefined;
124
+ /** Per call (default 20 s). */
125
+ readonly timeoutMs?: number | undefined;
126
+ }
127
+ /**
128
+ * Watches drafts being built (RFC-0020 §6): Studio's Build view follows a page while agents
129
+ * change it. Called after a write succeeds, and when a build's operations are refused, so a
130
+ * person sees the agent correct itself. Awaited through `notifyBuild`, which bounds and swallows
131
+ * failures: watching never fails or slows a write noticeably.
132
+ */
133
+ export interface BuildObserver {
134
+ pageChanged(change: {
135
+ readonly siteId: string;
136
+ readonly page: Page;
137
+ readonly tool: string;
138
+ readonly actor: Actor;
139
+ /** The operations applied (after repairs), when the change was a patch. */
140
+ readonly ops?: readonly unknown[] | undefined;
141
+ readonly repairs?: readonly string[] | undefined;
142
+ }): void | Promise<void>;
143
+ patchRejected(rejection: {
144
+ readonly siteId: string;
145
+ readonly pageId: string;
146
+ readonly tool: string;
147
+ readonly actor: Actor;
148
+ readonly issues: readonly unknown[];
149
+ }): void | Promise<void>;
150
+ }
151
+ /** Tells the Build view, waiting at most 2 s; a failure is logged, never thrown (RFC-0020 §6). */
152
+ export declare function notifyBuild(report: () => void | Promise<void>): Promise<void>;
153
+ export interface ToolContext {
154
+ store: SiteGraphStore;
155
+ /** Studio's Build view, when a server runs one (RFC-0020 §6). */
156
+ build?: BuildObserver | undefined;
157
+ principal: Principal;
158
+ /** Out-of-band approvals (HTTP): where `request_elevation` files its request. */
159
+ approvals?: ApprovalStore | undefined;
160
+ /** Clock (tests); defaults to the system time. */
161
+ now?: (() => Date) | undefined;
162
+ /** Base URL of a running `cloudhal dev` server, when known (preview links). */
163
+ previewBaseUrl?: string | undefined;
164
+ /** Shared preview secret: signed links to the deployed site (preferred over `previewBaseUrl`). */
165
+ previewSecret?: string | undefined;
166
+ /**
167
+ * Set by `runTool` for one call: what the call did beyond its arguments (assignment deltas, a
168
+ * governance operation's id and counts). It lands in the audit row's `input.effect`.
169
+ */
170
+ report?: ((effect: Record<string, unknown>) => void) | undefined;
171
+ /** Who owns what: the person behind an agent (RFC-0005 §4). */
172
+ ownership?: OwnershipResolver | undefined;
173
+ /** Set by `runTool`: the own limit this call runs under (absent = full scope). */
174
+ limit?: OwnLimit | undefined;
175
+ /** Media settings (fetch transport, host lists, daily limits). */
176
+ media?: MediaToolOptions | undefined;
177
+ /** Site analytics (RFC-0006): the analytics tools answer `analytics_disabled` without it. */
178
+ analytics?: AnalyticsService | undefined;
179
+ /** Reader comments (RFC-0007): the comment tools answer `comments_disabled` without them. */
180
+ comments?: CommentsDeps | undefined;
181
+ /**
182
+ * Set by `runTool`: a person said yes to this call in their own client (or a decided approval
183
+ * is being carried out), so a `person`-class call may run.
184
+ */
185
+ confirmed?: boolean | undefined;
186
+ /**
187
+ * Set when Studio carries out an approved request (RFC-0007 §10.3): `principal` is the approving
188
+ * person, `requestedBy` the agent that asked.
189
+ */
190
+ approval?: {
191
+ readonly id: string;
192
+ readonly requestedBy: Actor;
193
+ } | undefined;
194
+ /** Schedules (RFC-0008): the schedule tools answer `schedules_disabled` without them. */
195
+ schedules?: SchedulesDeps | undefined;
196
+ /** A browser for `render_page` (RFC-0021 §4); without it the tool answers `render_unavailable`. */
197
+ render?: RenderDeps | undefined;
198
+ /** Set by the server for an automation key's call: its open run (RFC-0008 §11.2). */
199
+ run?: RunContext | undefined;
200
+ /**
201
+ * Set by `runTool` for a `handlesApproval` tool whose decision waits for a person: the handler
202
+ * files the request itself (or takes the `auto` low-risk path).
203
+ */
204
+ pending?: Extract<Decision, {
205
+ kind: "approval-required";
206
+ }> | undefined;
207
+ /** Set by `runTool`: the policy engine (a run envelope lists the tools the run may call). */
208
+ policy?: PolicyEngine | undefined;
209
+ /** Set by `runTool`: the audit log (`get_run` lists a run's rows). */
210
+ audit?: AuditLog | undefined;
211
+ }
212
+ /**
213
+ * Without a membership source an agent owns what it wrote itself (local stdio with own-limited
214
+ * scopes); people are themselves; the system owns nothing.
215
+ */
216
+ export declare const ACTOR_OWNERSHIP: OwnershipResolver;
217
+ /** The person a call is measured against for "own" (RFC-0005 §4). */
218
+ export declare function callerPerson(ctx: ToolContext): string;
219
+ /** Checks an entry write against the call's own limit (I9); refusals are `denied`. */
220
+ export declare function entryLimitCheck(ctx: ToolContext, op: "create" | "update" | "delete", stored: ContentEntry | undefined, next?: Pick<ContentEntry, "author" | "status"> & {
221
+ publishedAt?: string | undefined;
222
+ }): Promise<void>;
223
+ /** Stable error codes agents can branch on; the text says what to do next. */
224
+ export type ToolErrorCode = "not_found" | "conflict" | "invalid" | "denied" | "approval_required" | InvariantCode | "unknown_taxonomy" | "unknown_term" | "ambiguous_term" | "invalid_filter" | "analytics_disabled" | "analytics_unavailable" | "comments_disabled" | "schedules_disabled" | "outside_run" | "tainted" | "no_egress_in_runs" | "budget_exceeded" | "run" | "render_unavailable" | "render_limited" | "render_failed";
225
+ /** What an approval request would change (RFC-0014 §5): a body, block by block. */
226
+ export interface ApprovalChanges {
227
+ kind: "body";
228
+ /** The article, or the page whose rich-text section `sectionId` it changes. */
229
+ nodeId: string;
230
+ sectionId?: string;
231
+ title: string;
232
+ diff: BodyDiff;
233
+ }
234
+ export declare class ToolError extends Error {
235
+ readonly name = "ToolError";
236
+ readonly code: ToolErrorCode;
237
+ /** Machine-readable context (suggestions, counts, ids). */
238
+ readonly details: Readonly<Record<string, unknown>>;
239
+ constructor(code: ToolErrorCode, message: string, details?: Record<string, unknown>);
240
+ }
241
+ export declare const id: {
242
+ type: string;
243
+ pattern: string;
244
+ };
245
+ export declare const SLUG_PATTERN = "^[a-z0-9]+(?:-[a-z0-9]+)*$";
246
+ export declare const str: (desc: string, extra?: JsonSchema) => {
247
+ type: string;
248
+ description: string;
249
+ };
250
+ export declare const obj: (properties: JsonSchema, required?: string[], extra?: JsonSchema) => JsonSchema;
251
+ export declare const strip: (schema: unknown) => JsonSchema;
252
+ /** Agent-controlled text in approval prompts is shortened and quoted so it cannot pose as UI. */
253
+ export declare function quote(text: string, max?: number): string;
254
+ export declare function requireSite(ctx: ToolContext, siteId: string): Promise<Site>;
255
+ export declare function autoSnapshot(ctx: ToolContext, siteId: string, tool: string, metadata?: Record<string, string>): Promise<Snapshot>;
256
+ /** Store errors as `ToolError`s with stable codes; anything else is returned unchanged. */
257
+ export declare function toToolError(e: unknown): unknown;
258
+ export declare function mapError(e: unknown): never;