@ingcreators/annot-mcp 0.1.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.
@@ -0,0 +1,16 @@
1
+ export interface PngDimensions {
2
+ width: number;
3
+ height: number;
4
+ }
5
+ export declare class InvalidPngError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ /**
9
+ * Parse the width / height fields from a PNG IHDR chunk. Throws
10
+ * `InvalidPngError` if the input doesn't start with a valid PNG
11
+ * signature or the IHDR chunk type is missing.
12
+ *
13
+ * Accepts any byte source with a `BufferSource`-compatible shape
14
+ * (`Uint8Array`, `ArrayBuffer`, Node `Buffer`).
15
+ */
16
+ export declare function readPngDimensions(bytes: Uint8Array): PngDimensions;
@@ -0,0 +1,24 @@
1
+ import { PngDimensions } from './png-dimensions.js';
2
+ export interface ResolvedImage {
3
+ /** Raw PNG bytes. */
4
+ bytes: Uint8Array;
5
+ /** `data:image/png;base64,...` form. Suitable for the annotator. */
6
+ dataUrl: string;
7
+ /** Width / height parsed from the IHDR chunk. */
8
+ dimensions: PngDimensions;
9
+ }
10
+ export declare class InvalidImageInputError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ /**
14
+ * Resolve an `image` field from a tool call. Accepts either:
15
+ *
16
+ * - a `data:image/png;base64,...` URL
17
+ * - an absolute filesystem path to a PNG file
18
+ *
19
+ * Relative paths are rejected — agents are required to pass
20
+ * absolute paths so the resolution doesn't depend on the MCP
21
+ * server's current working directory (which the agent has no
22
+ * control over).
23
+ */
24
+ export declare function resolveImageInput(input: string): Promise<ResolvedImage>;
@@ -0,0 +1,14 @@
1
+ import { BBox, RedactStyle } from '../dsl/types.js';
2
+ export interface RedactRegion {
3
+ bbox: BBox;
4
+ style?: RedactStyle;
5
+ color?: string;
6
+ }
7
+ /**
8
+ * Burn redactions into a PNG buffer. Returns a new PNG with the
9
+ * regions painted over the source pixels.
10
+ *
11
+ * Regions are processed in order; later regions overlay earlier
12
+ * ones (no automatic deduplication or alpha-blending).
13
+ */
14
+ export declare function burnRedactions(pngBytes: Uint8Array, regions: readonly RedactRegion[]): Promise<Uint8Array>;
@@ -0,0 +1,34 @@
1
+ import { Annotator, AnnotatorOptions } from '@ingcreators/annot-annotator';
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { BrowserPool } from './browser/pool.js';
4
+ export interface CreateServerOptions {
5
+ /**
6
+ * Override the version reported in the MCP `initialize` response.
7
+ * Defaults to the package version baked at build time. Mostly
8
+ * useful for tests that want a deterministic version string.
9
+ */
10
+ version?: string;
11
+ /**
12
+ * Inject a pre-built annotator. Tests pass a stub here to avoid
13
+ * loading resvg-js's native rasteriser; production callers omit
14
+ * the field and let the server construct one with default
15
+ * options.
16
+ */
17
+ annotator?: Annotator;
18
+ /**
19
+ * Forwarded to `createAnnotator()` when `annotator` is omitted.
20
+ * Lets the host opt into system fonts or register a custom font
21
+ * set without subclassing the server.
22
+ */
23
+ annotatorOptions?: AnnotatorOptions;
24
+ /**
25
+ * Inject a pre-built browser pool. Tests pass a stub to skip the
26
+ * Chromium launch; production callers omit the field and let
27
+ * the server construct a `createChromiumPool()` lazily.
28
+ */
29
+ pool?: BrowserPool;
30
+ }
31
+ /**
32
+ * Construct an MCP server instance with the Annot tool surface.
33
+ */
34
+ export declare function createServer(options?: CreateServerOptions): Server;
@@ -0,0 +1,293 @@
1
+ import { Annotator } from '@ingcreators/annot-annotator';
2
+ export declare const ANNOTATE_SCREENSHOT_TOOL_NAME = "annot_annotate_screenshot";
3
+ /**
4
+ * Tool descriptor for the MCP `tools/list` response. The
5
+ * `inputSchema` is shipped as a plain JSON Schema literal; the
6
+ * MCP SDK runs Ajv on the agent's payload before our handler sees
7
+ * it.
8
+ */
9
+ export declare const annotateScreenshotTool: {
10
+ readonly name: "annot_annotate_screenshot";
11
+ readonly description: string;
12
+ readonly inputSchema: {
13
+ readonly type: "object";
14
+ readonly required: readonly ["image", "annotations"];
15
+ readonly additionalProperties: false;
16
+ readonly properties: {
17
+ readonly image: {
18
+ readonly type: "string";
19
+ readonly description: string;
20
+ };
21
+ readonly annotations: {
22
+ readonly type: "array";
23
+ readonly items: {
24
+ readonly $ref: "#/$defs/BboxAnnotation";
25
+ };
26
+ readonly description: string;
27
+ };
28
+ readonly output: {
29
+ readonly type: "string";
30
+ readonly description: string;
31
+ };
32
+ };
33
+ readonly $defs: {
34
+ readonly BboxAnnotation: {
35
+ oneOf: ({
36
+ type: string;
37
+ required: string[];
38
+ additionalProperties: boolean;
39
+ properties: {
40
+ type: {
41
+ const: string;
42
+ };
43
+ bbox: {
44
+ $ref: string;
45
+ };
46
+ intent: {
47
+ $ref: string;
48
+ };
49
+ stroke: {
50
+ type: string;
51
+ };
52
+ strokeWidth: {
53
+ type: string;
54
+ minimum: number;
55
+ };
56
+ fill: {
57
+ type: string;
58
+ };
59
+ color: {
60
+ type: string;
61
+ };
62
+ };
63
+ } | {
64
+ type: string;
65
+ required: string[];
66
+ additionalProperties: boolean;
67
+ properties: {
68
+ type: {
69
+ const: string;
70
+ };
71
+ center: {
72
+ $ref: string;
73
+ };
74
+ radius: {
75
+ type: string;
76
+ minimum: number;
77
+ };
78
+ intent: {
79
+ $ref: string;
80
+ };
81
+ stroke: {
82
+ type: string;
83
+ };
84
+ strokeWidth: {
85
+ type: string;
86
+ minimum: number;
87
+ };
88
+ fill: {
89
+ type: string;
90
+ };
91
+ color: {
92
+ type: string;
93
+ };
94
+ };
95
+ } | {
96
+ type: string;
97
+ required: string[];
98
+ additionalProperties: boolean;
99
+ properties: {
100
+ type: {
101
+ const: string;
102
+ };
103
+ from: {
104
+ $ref: string;
105
+ };
106
+ to: {
107
+ $ref: string;
108
+ };
109
+ intent: {
110
+ $ref: string;
111
+ };
112
+ stroke: {
113
+ type: string;
114
+ };
115
+ strokeWidth: {
116
+ type: string;
117
+ minimum: number;
118
+ };
119
+ color: {
120
+ type: string;
121
+ };
122
+ };
123
+ } | {
124
+ type: string;
125
+ required: string[];
126
+ additionalProperties: boolean;
127
+ properties: {
128
+ type: {
129
+ const: string;
130
+ };
131
+ at: {
132
+ $ref: string;
133
+ };
134
+ content: {
135
+ type: string;
136
+ };
137
+ fontSize: {
138
+ type: string;
139
+ minimum: number;
140
+ };
141
+ anchor: {
142
+ type: string;
143
+ enum: string[];
144
+ };
145
+ intent: {
146
+ $ref: string;
147
+ };
148
+ color: {
149
+ type: string;
150
+ };
151
+ };
152
+ } | {
153
+ type: string;
154
+ required: string[];
155
+ additionalProperties: boolean;
156
+ properties: {
157
+ type: {
158
+ const: string;
159
+ };
160
+ at: {
161
+ $ref: string;
162
+ };
163
+ targetBbox: {
164
+ $ref: string;
165
+ };
166
+ content: {
167
+ type: string;
168
+ };
169
+ intent: {
170
+ $ref: string;
171
+ };
172
+ stroke: {
173
+ type: string;
174
+ };
175
+ color: {
176
+ type: string;
177
+ };
178
+ };
179
+ } | {
180
+ type: string;
181
+ required: string[];
182
+ additionalProperties: boolean;
183
+ properties: {
184
+ type: {
185
+ const: string;
186
+ };
187
+ svgFragment: {
188
+ type: string;
189
+ };
190
+ };
191
+ })[];
192
+ };
193
+ readonly BBox: {
194
+ type: string;
195
+ required: string[];
196
+ additionalProperties: boolean;
197
+ properties: {
198
+ x: {
199
+ type: string;
200
+ };
201
+ y: {
202
+ type: string;
203
+ };
204
+ width: {
205
+ type: string;
206
+ minimum: number;
207
+ };
208
+ height: {
209
+ type: string;
210
+ minimum: number;
211
+ };
212
+ };
213
+ };
214
+ readonly Point: {
215
+ type: string;
216
+ required: string[];
217
+ additionalProperties: boolean;
218
+ properties: {
219
+ x: {
220
+ type: string;
221
+ };
222
+ y: {
223
+ type: string;
224
+ };
225
+ };
226
+ };
227
+ readonly Intent: {
228
+ type: string;
229
+ enum: string[];
230
+ };
231
+ readonly AnnotationStyle: {
232
+ type: string;
233
+ additionalProperties: boolean;
234
+ properties: {
235
+ intent: {
236
+ $ref: string;
237
+ };
238
+ stroke: {
239
+ type: string;
240
+ };
241
+ strokeWidth: {
242
+ type: string;
243
+ minimum: number;
244
+ };
245
+ fill: {
246
+ type: string;
247
+ };
248
+ color: {
249
+ type: string;
250
+ };
251
+ };
252
+ };
253
+ readonly Locator: {
254
+ type: string;
255
+ minLength: number;
256
+ };
257
+ };
258
+ };
259
+ };
260
+ /** Tool dependencies — injected at server construction time. */
261
+ export interface AnnotateScreenshotDeps {
262
+ annotator: Annotator;
263
+ }
264
+ /** Raw, pre-validation tool input. The MCP SDK has already run the
265
+ * JSON schema check by the time we see this, but we still
266
+ * defensively narrow before reaching into fields. */
267
+ interface AnnotateScreenshotInput {
268
+ image?: unknown;
269
+ annotations?: unknown;
270
+ output?: unknown;
271
+ }
272
+ /** MCP `tools/call` result content block. */
273
+ type ContentBlock = {
274
+ type: "text";
275
+ text: string;
276
+ } | {
277
+ type: "image";
278
+ data: string;
279
+ mimeType: string;
280
+ };
281
+ /**
282
+ * Subset of the MCP SDK's `CallToolResult` we actually emit. The
283
+ * SDK's full type also covers async-task responses (added in MCP
284
+ * v2025-06-19); our handler always returns the synchronous content
285
+ * shape, so we narrow here for clarity. Dispatch in `server.ts`
286
+ * casts back up to the SDK union at the boundary.
287
+ */
288
+ export interface AnnotateToolResult {
289
+ content: ContentBlock[];
290
+ isError?: boolean;
291
+ }
292
+ export declare function handleAnnotateScreenshot(input: AnnotateScreenshotInput, deps: AnnotateScreenshotDeps): Promise<AnnotateToolResult>;
293
+ export {};