@deckflow/deckprobe-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.
- package/LICENSE +22 -0
- package/README.md +244 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -0
- package/dist/engine/index.d.ts +11 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +60 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/native.d.ts +21 -0
- package/dist/engine/native.d.ts.map +1 -0
- package/dist/engine/native.js +193 -0
- package/dist/engine/native.js.map +1 -0
- package/dist/engine/types.d.ts +52 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +21 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/wasm.d.ts +23 -0
- package/dist/engine/wasm.d.ts.map +1 -0
- package/dist/engine/wasm.js +116 -0
- package/dist/engine/wasm.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +25 -0
- package/dist/errors.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +68 -0
- package/dist/main.js.map +1 -0
- package/dist/paths.d.ts +9 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +34 -0
- package/dist/paths.js.map +1 -0
- package/dist/result.d.ts +28 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +101 -0
- package/dist/result.js.map +1 -0
- package/dist/schemas.d.ts +59 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +53 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +47 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/context.d.ts +7 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +2 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/discovery.d.ts +4 -0
- package/dist/tools/discovery.d.ts.map +1 -0
- package/dist/tools/discovery.js +130 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/probe-batch.d.ts +4 -0
- package/dist/tools/probe-batch.d.ts.map +1 -0
- package/dist/tools/probe-batch.js +97 -0
- package/dist/tools/probe-batch.js.map +1 -0
- package/dist/tools/probe.d.ts +4 -0
- package/dist/tools/probe.d.ts.map +1 -0
- package/dist/tools/probe.js +45 -0
- package/dist/tools/probe.js.map +1 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Field descriptions are deliberately terse: they are re-sent in every
|
|
4
|
+
* `tools/list`, and the server `instructions` already carry the vocabulary and
|
|
5
|
+
* the rules for reading a report.
|
|
6
|
+
*/
|
|
7
|
+
export declare const levelSchema: z.ZodEnum<{
|
|
8
|
+
header: "header";
|
|
9
|
+
metadata: "metadata";
|
|
10
|
+
deep: "deep";
|
|
11
|
+
}>;
|
|
12
|
+
export declare const confidenceSchema: z.ZodEnum<{
|
|
13
|
+
low: "low";
|
|
14
|
+
medium: "medium";
|
|
15
|
+
high: "high";
|
|
16
|
+
exact: "exact";
|
|
17
|
+
}>;
|
|
18
|
+
export declare const targetsSchema: z.ZodArray<z.ZodString>;
|
|
19
|
+
export declare const budgetSchema: z.ZodObject<{
|
|
20
|
+
max_physical_bytes: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
max_expanded_bytes: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
max_archive_entries: z.ZodOptional<z.ZodNumber>;
|
|
23
|
+
timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
export declare const minConfidenceSchema: z.ZodEnum<{
|
|
26
|
+
low: "low";
|
|
27
|
+
medium: "medium";
|
|
28
|
+
high: "high";
|
|
29
|
+
exact: "exact";
|
|
30
|
+
}>;
|
|
31
|
+
export declare const targetConfidenceSchema: z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
32
|
+
low: "low";
|
|
33
|
+
medium: "medium";
|
|
34
|
+
high: "high";
|
|
35
|
+
exact: "exact";
|
|
36
|
+
}>>;
|
|
37
|
+
export declare const viewSchema: z.ZodEnum<{
|
|
38
|
+
values: "values";
|
|
39
|
+
report: "report";
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Deliberately permissive: one tool returns reports, values views, and error
|
|
43
|
+
* envelopes, and the authoritative contract is the JSON Schema the engine
|
|
44
|
+
* itself bundles, served as the `deckprobe://schema` resource.
|
|
45
|
+
*/
|
|
46
|
+
export declare const envelopeSchema: z.ZodObject<{
|
|
47
|
+
schema_version: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
status: z.ZodOptional<z.ZodString>;
|
|
49
|
+
}, z.core.$loose>;
|
|
50
|
+
export declare const batchOutputSchema: z.ZodObject<{
|
|
51
|
+
reports: z.ZodArray<z.ZodObject<{
|
|
52
|
+
path: z.ZodString;
|
|
53
|
+
report: z.ZodObject<{
|
|
54
|
+
schema_version: z.ZodOptional<z.ZodNumber>;
|
|
55
|
+
status: z.ZodOptional<z.ZodString>;
|
|
56
|
+
}, z.core.$loose>;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;GAIG;AACH,eAAO,MAAM,WAAW;;;;EAKrB,CAAC;AAEJ,eAAO,MAAM,gBAAgB;;;;;EAA6C,CAAC;AAE3E,eAAO,MAAM,aAAa,yBAUvB,CAAC;AAEJ,eAAO,MAAM,YAAY;;;;;iBAOgE,CAAC;AAE1F,eAAO,MAAM,mBAAmB;;;;;EAE/B,CAAC;AAEF,eAAO,MAAM,sBAAsB;;;;;GAE+D,CAAC;AAEnG,eAAO,MAAM,UAAU;;;EAKpB,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;iBAKwD,CAAC;AAEpF,eAAO,MAAM,iBAAiB;;;;;;;;iBAI5B,CAAC"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Field descriptions are deliberately terse: they are re-sent in every
|
|
4
|
+
* `tools/list`, and the server `instructions` already carry the vocabulary and
|
|
5
|
+
* the rules for reading a report.
|
|
6
|
+
*/
|
|
7
|
+
export const levelSchema = z
|
|
8
|
+
.enum(["header", "metadata", "deep"])
|
|
9
|
+
.describe("Probe budget and eligible paths. header: identity only. metadata (default). " +
|
|
10
|
+
"deep: higher-cost paths, needed only when a target's min_level says so.");
|
|
11
|
+
export const confidenceSchema = z.enum(["low", "medium", "high", "exact"]);
|
|
12
|
+
export const targetsSchema = z
|
|
13
|
+
.array(z.string().min(1))
|
|
14
|
+
.min(1)
|
|
15
|
+
.max(64)
|
|
16
|
+
.describe("Short names (slide_count), canonical names (powerpoint.slide_count), or presets: " +
|
|
17
|
+
"@header, @summary, @security, @structure, @assets, @quality, @format, @all. " +
|
|
18
|
+
"Defaults to the driver's own set. Call list_targets rather than guessing a name. " +
|
|
19
|
+
"@summary omits statistics needing a full-file read, so ask for a PDF's page_count " +
|
|
20
|
+
"explicitly.");
|
|
21
|
+
export const budgetSchema = z
|
|
22
|
+
.object({
|
|
23
|
+
max_physical_bytes: z.number().int().positive().optional(),
|
|
24
|
+
max_expanded_bytes: z.number().int().positive().optional(),
|
|
25
|
+
max_archive_entries: z.number().int().positive().optional(),
|
|
26
|
+
timeout_ms: z.number().int().positive().optional(),
|
|
27
|
+
})
|
|
28
|
+
.describe("Override the level's resource limits. Raise after a BUDGET_EXCEEDED error.");
|
|
29
|
+
export const minConfidenceSchema = confidenceSchema.describe("Weakest evidence a path may offer. Default high; lower it to accept an approximation.");
|
|
30
|
+
export const targetConfidenceSchema = z
|
|
31
|
+
.record(z.string(), confidenceSchema)
|
|
32
|
+
.describe('Per-target override, e.g. {"slide_count": "exact"} to force the authoritative path.');
|
|
33
|
+
export const viewSchema = z
|
|
34
|
+
.enum(["report", "values"])
|
|
35
|
+
.describe("report: full evidence — value, confidence, path, and cost per target. " +
|
|
36
|
+
"values: a compact target-to-value map.");
|
|
37
|
+
/**
|
|
38
|
+
* Deliberately permissive: one tool returns reports, values views, and error
|
|
39
|
+
* envelopes, and the authoritative contract is the JSON Schema the engine
|
|
40
|
+
* itself bundles, served as the `deckprobe://schema` resource.
|
|
41
|
+
*/
|
|
42
|
+
export const envelopeSchema = z
|
|
43
|
+
.looseObject({
|
|
44
|
+
schema_version: z.number().optional(),
|
|
45
|
+
status: z.string().optional(),
|
|
46
|
+
})
|
|
47
|
+
.describe("A DeckProbe schema-v2 envelope. See the deckprobe://schema resource.");
|
|
48
|
+
export const batchOutputSchema = z.object({
|
|
49
|
+
reports: z
|
|
50
|
+
.array(z.object({ path: z.string(), report: envelopeSchema }))
|
|
51
|
+
.describe("One entry per requested path, in order. A per-file failure is confined to it."),
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;KACpC,QAAQ,CACP,8EAA8E;IAC5E,yEAAyE,CAC5E,CAAC;AAEJ,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KACxB,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,EAAE,CAAC;KACP,QAAQ,CACP,mFAAmF;IACjF,8EAA8E;IAC9E,mFAAmF;IACnF,oFAAoF;IACpF,aAAa,CAChB,CAAC;AAEJ,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC1D,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC1D,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACnD,CAAC;KACD,QAAQ,CAAC,4EAA4E,CAAC,CAAC;AAE1F,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,QAAQ,CAC1D,uFAAuF,CACxF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC;KACpC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC;KACpC,QAAQ,CAAC,qFAAqF,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;KAC1B,QAAQ,CACP,wEAAwE;IACtE,wCAAwC,CAC3C,CAAC;AAEJ;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC;KAC5B,WAAW,CAAC;IACX,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,QAAQ,CAAC,sEAAsE,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;SAC7D,QAAQ,CAAC,+EAA+E,CAAC;CAC7F,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
|
+
import type { Config } from "./config.js";
|
|
3
|
+
import type { Engine } from "./engine/index.js";
|
|
4
|
+
export declare function buildServer(engine: Engine, config: Config): McpServer;
|
|
5
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAqChD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAerE"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/server";
|
|
2
|
+
import { registerDiscovery } from "./tools/discovery.js";
|
|
3
|
+
import { registerProbe } from "./tools/probe.js";
|
|
4
|
+
import { registerProbeBatch } from "./tools/probe-batch.js";
|
|
5
|
+
import { SERVER_NAME, SERVER_VERSION } from "./version.js";
|
|
6
|
+
/**
|
|
7
|
+
* Sent with `initialize`, so a client learns the vocabulary without installing
|
|
8
|
+
* the DeckProbe agent skill. Everything here is about reading the report
|
|
9
|
+
* correctly — the parts agents get wrong when left to infer them.
|
|
10
|
+
*/
|
|
11
|
+
const INSTRUCTIONS = `DeckProbe answers questions ABOUT a document — how many slides, is it \
|
|
12
|
+
encrypted, does it have macros, is it damaged, is this really a .pptx — for PDF, Microsoft \
|
|
13
|
+
Office, and modern Apple iWork files. It is safe on untrusted input: nothing is rendered, no \
|
|
14
|
+
macro runs, no external reference is followed, and no network connection is opened.
|
|
15
|
+
|
|
16
|
+
Getting started:
|
|
17
|
+
- probe with targets ["@summary"] when you do not yet know what a file holds.
|
|
18
|
+
- ["@security"] to triage an untrusted file; ["@structure"] for counts and dimensions.
|
|
19
|
+
- probe_batch to inventory many files in one call.
|
|
20
|
+
- Never guess a target name. list_targets returns the valid names for a format, and probe \
|
|
21
|
+
rejects an unknown one rather than approximating.
|
|
22
|
+
|
|
23
|
+
Reading a report:
|
|
24
|
+
- status "partial" is not a failure. It means at least one requested target was not resolved \
|
|
25
|
+
at the requested confidence; it is listed in execution.unresolved_targets and every other \
|
|
26
|
+
result still stands.
|
|
27
|
+
- Only results with status "resolved" or "estimated" carry a value. "unknown" is common and \
|
|
28
|
+
usually means the document does not record that fact — it is not an error.
|
|
29
|
+
- results is keyed by canonical target name even when you asked with a short alias.
|
|
30
|
+
- confidence_score is a fixed constant per label (0.4 / 0.7 / 0.95 / 1.0), not a calibrated \
|
|
31
|
+
probability. 0.95 does not mean the value is right 95% of the time.
|
|
32
|
+
|
|
33
|
+
Limits worth knowing: there is no text extraction, no OCR, and no rendering. Routing is by \
|
|
34
|
+
filename extension and then verified against the container, so a renamed file returns \
|
|
35
|
+
MALFORMED_INPUT. Legacy XML iWork packages are rejected by design; .xlsb is identity-only.`;
|
|
36
|
+
export function buildServer(engine, config) {
|
|
37
|
+
const server = new McpServer({ name: SERVER_NAME, title: "DeckProbe", version: SERVER_VERSION }, {
|
|
38
|
+
instructions: INSTRUCTIONS,
|
|
39
|
+
capabilities: { tools: {}, resources: {} },
|
|
40
|
+
});
|
|
41
|
+
const context = { engine, config };
|
|
42
|
+
registerProbe(server, context);
|
|
43
|
+
registerProbeBatch(server, context);
|
|
44
|
+
registerDiscovery(server, context);
|
|
45
|
+
return server;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE3D;;;;GAIG;AACH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;2FAwBsE,CAAC;AAE5F,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,MAAc;IACxD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAClE;QACE,YAAY,EAAE,YAAY;QAC1B,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;KAC3C,CACF,CAAC;IAEF,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACnC,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/tools/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAM9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAgEhD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAsF/E"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { isRecord } from "../engine/index.js";
|
|
3
|
+
import { guard, outcomeResult, successResult } from "../result.js";
|
|
4
|
+
/**
|
|
5
|
+
* Discovery output is fixed for a given engine binary, so the first call in a
|
|
6
|
+
* session pays for the subprocess and the rest are free. A failed lookup is
|
|
7
|
+
* not cached, so a transient problem can be retried.
|
|
8
|
+
*/
|
|
9
|
+
function memoize(load) {
|
|
10
|
+
const cache = new Map();
|
|
11
|
+
return (key) => {
|
|
12
|
+
const cached = cache.get(key);
|
|
13
|
+
if (cached)
|
|
14
|
+
return cached;
|
|
15
|
+
const pending = load(key).catch((error) => {
|
|
16
|
+
cache.delete(key);
|
|
17
|
+
throw error;
|
|
18
|
+
});
|
|
19
|
+
cache.set(key, pending);
|
|
20
|
+
return pending;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Fields of a target spec worth spending an agent's context on. */
|
|
24
|
+
const TARGET_FIELDS = [
|
|
25
|
+
"id",
|
|
26
|
+
"aliases",
|
|
27
|
+
"description",
|
|
28
|
+
"value_type",
|
|
29
|
+
"min_level",
|
|
30
|
+
"cost_class",
|
|
31
|
+
"selectors",
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* The full `targets` report is around 20 KB per format, most of it per-target
|
|
35
|
+
* JSON Schema fragments and fully expanded selector lists that an agent
|
|
36
|
+
* choosing a target does not read. The compact projection keeps everything
|
|
37
|
+
* needed to name a target correctly and is roughly a third of the size.
|
|
38
|
+
*/
|
|
39
|
+
function compactTargets(json) {
|
|
40
|
+
if (!isRecord(json) || !Array.isArray(json.targets))
|
|
41
|
+
return json;
|
|
42
|
+
return {
|
|
43
|
+
schema_version: json.schema_version,
|
|
44
|
+
tool_version: json.tool_version,
|
|
45
|
+
driver: json.driver,
|
|
46
|
+
profile: json.profile,
|
|
47
|
+
detail: "compact",
|
|
48
|
+
selectors: Object.keys(isRecord(json.selector_expansions) ? json.selector_expansions : {}),
|
|
49
|
+
format_options: json.format_options,
|
|
50
|
+
targets: json.targets.map((target) => {
|
|
51
|
+
if (!isRecord(target))
|
|
52
|
+
return target;
|
|
53
|
+
const compact = {};
|
|
54
|
+
for (const field of TARGET_FIELDS) {
|
|
55
|
+
if (target[field] !== undefined)
|
|
56
|
+
compact[field] = target[field];
|
|
57
|
+
}
|
|
58
|
+
// Only worth stating when it is a warning; nearly every target is applicable.
|
|
59
|
+
if (target.applicable === false)
|
|
60
|
+
compact.applicable = false;
|
|
61
|
+
return compact;
|
|
62
|
+
}),
|
|
63
|
+
omitted: 'per-target JSON Schema fragments, supported_levels, and expanded selector member lists. Call again with detail: "full" for the complete report.',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function registerDiscovery(server, context) {
|
|
67
|
+
const loadFormats = memoize(() => context.engine.formats());
|
|
68
|
+
const loadTargets = memoize((format) => context.engine.targets(format));
|
|
69
|
+
const loadSchema = memoize(() => context.engine.schema());
|
|
70
|
+
server.registerTool("list_formats", {
|
|
71
|
+
title: "List supported formats",
|
|
72
|
+
description: "List the document formats DeckProbe can inspect: drivers, the extensions each one " +
|
|
73
|
+
"handles, and where support stops. Call this when you are unsure whether a file type " +
|
|
74
|
+
"is supported at all.",
|
|
75
|
+
annotations: {
|
|
76
|
+
readOnlyHint: true,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
idempotentHint: true,
|
|
79
|
+
openWorldHint: false,
|
|
80
|
+
},
|
|
81
|
+
}, async () => guard(async () => outcomeResult(await loadFormats("formats"))));
|
|
82
|
+
server.registerTool("list_targets", {
|
|
83
|
+
title: "List targets for a format",
|
|
84
|
+
description: "List every target a format supports, with its aliases, value type, minimum probe " +
|
|
85
|
+
"level, cost class, and which @selectors include it. Call this before naming a target " +
|
|
86
|
+
"you have not already seen — probe rejects an unknown one rather than guessing.",
|
|
87
|
+
inputSchema: z.object({
|
|
88
|
+
format: z
|
|
89
|
+
.string()
|
|
90
|
+
.min(1)
|
|
91
|
+
.describe('A format profile from list_formats, such as "pdf", "docx", "xlsx", "pptx", ' +
|
|
92
|
+
'"doc", "xls", "ppt", "key", "numbers", or "pages".'),
|
|
93
|
+
detail: z
|
|
94
|
+
.enum(["compact", "full"])
|
|
95
|
+
.optional()
|
|
96
|
+
.describe("compact (default): target names, aliases, descriptions, levels, and selector " +
|
|
97
|
+
"membership. full: the complete report, including each target's JSON Schema " +
|
|
98
|
+
"fragment and every selector's expanded member list."),
|
|
99
|
+
}),
|
|
100
|
+
annotations: {
|
|
101
|
+
readOnlyHint: true,
|
|
102
|
+
destructiveHint: false,
|
|
103
|
+
idempotentHint: true,
|
|
104
|
+
openWorldHint: false,
|
|
105
|
+
},
|
|
106
|
+
}, async ({ format, detail }) => guard(async () => {
|
|
107
|
+
const outcome = await loadTargets(format);
|
|
108
|
+
if (outcome.exitCode !== 0 || detail === "full")
|
|
109
|
+
return outcomeResult(outcome);
|
|
110
|
+
return successResult(compactTargets(outcome.json));
|
|
111
|
+
}));
|
|
112
|
+
server.registerResource("report-schema", "deckprobe://schema", {
|
|
113
|
+
title: "DeckProbe report JSON Schema",
|
|
114
|
+
description: "The authoritative JSON Schema for the schema-v2 report envelope, as bundled with " +
|
|
115
|
+
"the running engine.",
|
|
116
|
+
mimeType: "application/json",
|
|
117
|
+
}, async (uri) => {
|
|
118
|
+
const outcome = await loadSchema("schema");
|
|
119
|
+
return {
|
|
120
|
+
contents: [
|
|
121
|
+
{
|
|
122
|
+
uri: uri.href,
|
|
123
|
+
mimeType: "application/json",
|
|
124
|
+
text: JSON.stringify(outcome.json, null, 2),
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/tools/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-batch.d.ts","sourceRoot":"","sources":["../../src/tools/probe-batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAe9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAkBhD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAgEhF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { exitCodeOf } from "../engine/index.js";
|
|
3
|
+
import { ServerError } from "../errors.js";
|
|
4
|
+
import { resolveInputPath } from "../paths.js";
|
|
5
|
+
import { guard, hintFor, jsonText } from "../result.js";
|
|
6
|
+
import { batchOutputSchema, budgetSchema, levelSchema, minConfidenceSchema, targetsSchema, viewSchema, } from "../schemas.js";
|
|
7
|
+
const DESCRIPTION = `Probe many local documents in one call — inventory a folder, triage a batch \
|
|
8
|
+
of uploads, or compare a set of files. One engine process handles the whole batch, so this is \
|
|
9
|
+
much cheaper than calling probe once per file.
|
|
10
|
+
|
|
11
|
+
Takes literal paths; expand any glob yourself first. Returns one entry per path, in the order \
|
|
12
|
+
given, each carrying that file's report or its own error envelope. A file that fails does not \
|
|
13
|
+
affect the others.
|
|
14
|
+
|
|
15
|
+
Defaults to the compact "values" view because inventory rarely needs per-target evidence; pass \
|
|
16
|
+
view: "report" when it does.`;
|
|
17
|
+
export function registerProbeBatch(server, context) {
|
|
18
|
+
const { maxBatch } = context.config;
|
|
19
|
+
server.registerTool("probe_batch", {
|
|
20
|
+
title: "Probe several documents",
|
|
21
|
+
description: DESCRIPTION,
|
|
22
|
+
inputSchema: z.object({
|
|
23
|
+
paths: z
|
|
24
|
+
.array(z.string().min(1))
|
|
25
|
+
.min(1)
|
|
26
|
+
.max(maxBatch)
|
|
27
|
+
.describe(`Document paths, at most ${maxBatch} per call. Literal paths only.`),
|
|
28
|
+
targets: targetsSchema.optional(),
|
|
29
|
+
level: levelSchema.optional(),
|
|
30
|
+
min_confidence: minConfidenceSchema.optional(),
|
|
31
|
+
view: viewSchema.optional(),
|
|
32
|
+
budget: budgetSchema.optional(),
|
|
33
|
+
}),
|
|
34
|
+
outputSchema: batchOutputSchema,
|
|
35
|
+
annotations: {
|
|
36
|
+
readOnlyHint: true,
|
|
37
|
+
destructiveHint: false,
|
|
38
|
+
idempotentHint: true,
|
|
39
|
+
openWorldHint: false,
|
|
40
|
+
},
|
|
41
|
+
}, async (args) => guard(async () => {
|
|
42
|
+
const request = { ...args, view: args.view ?? "values" };
|
|
43
|
+
// A path the server rejects becomes an in-place error, matching how the
|
|
44
|
+
// engine's own JSONL mode treats a bad record: report it and continue.
|
|
45
|
+
const resolved = args.paths.map((path) => {
|
|
46
|
+
try {
|
|
47
|
+
return { path, engine: resolveInputPath(path, context.config) };
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error instanceof ServerError)
|
|
51
|
+
return { path, failure: error };
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const probeable = resolved.filter((entry) => "engine" in entry);
|
|
56
|
+
const outcomes = probeable.length > 0
|
|
57
|
+
? await context.engine.probeBatch(probeable.map((entry) => entry.engine), request)
|
|
58
|
+
: [];
|
|
59
|
+
let next = 0;
|
|
60
|
+
const entries = resolved.map((entry) => {
|
|
61
|
+
if ("failure" in entry)
|
|
62
|
+
return { path: entry.path, report: entry.failure.envelope() };
|
|
63
|
+
const outcome = outcomes[next++];
|
|
64
|
+
return { path: entry.path, report: outcome?.json ?? null };
|
|
65
|
+
});
|
|
66
|
+
return batchResult(entries);
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The call itself succeeds whenever the batch ran; per-file failures live in
|
|
71
|
+
* their own entries. A leading summary line tells the caller which files
|
|
72
|
+
* failed without making it scan a long array.
|
|
73
|
+
*/
|
|
74
|
+
function batchResult(entries) {
|
|
75
|
+
const structured = { reports: entries };
|
|
76
|
+
const failed = entries.filter((entry) => exitCodeOf(entry.report) !== 0);
|
|
77
|
+
const notes = [];
|
|
78
|
+
if (failed.length > 0) {
|
|
79
|
+
notes.push(`${failed.length} of ${entries.length} file(s) failed: ${failed
|
|
80
|
+
.map((entry) => entry.path)
|
|
81
|
+
.join(", ")}`);
|
|
82
|
+
const first = failed[0];
|
|
83
|
+
if (first) {
|
|
84
|
+
const hint = hintFor(first.report, exitCodeOf(first.report));
|
|
85
|
+
if (hint)
|
|
86
|
+
notes.push(hint);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
...notes.map((text) => ({ type: "text", text })),
|
|
92
|
+
{ type: "text", text: jsonText(structured) },
|
|
93
|
+
],
|
|
94
|
+
structuredContent: structured,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=probe-batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-batch.js","sourceRoot":"","sources":["../../src/tools/probe-batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/tools/probe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAc9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAchD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAmC3E"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { resolveInputPath } from "../paths.js";
|
|
3
|
+
import { guard, outcomeResult } from "../result.js";
|
|
4
|
+
import { budgetSchema, envelopeSchema, levelSchema, minConfidenceSchema, targetConfidenceSchema, targetsSchema, viewSchema, } from "../schemas.js";
|
|
5
|
+
const DESCRIPTION = `Read facts about one local PDF, Microsoft Office, or Apple iWork document \
|
|
6
|
+
without opening or rendering it: page, slide, and sheet counts; title, author, and dates; \
|
|
7
|
+
encryption, macro, signature, and active-content signals; structure; embedded assets; and \
|
|
8
|
+
integrity. Handles .pdf, .docx/.xlsx/.pptx, legacy .doc/.xls/.ppt, and modern \
|
|
9
|
+
.key/.numbers/.pages.
|
|
10
|
+
|
|
11
|
+
Start with targets ["@summary"], or ["@security"] to triage an untrusted file. Prefer this \
|
|
12
|
+
over unzipping the document or parsing its bytes by hand.
|
|
13
|
+
|
|
14
|
+
Reports facts ABOUT the document, never its text: it does not extract, render, run macros, \
|
|
15
|
+
follow external references, or open a network connection.`;
|
|
16
|
+
export function registerProbe(server, context) {
|
|
17
|
+
server.registerTool("probe", {
|
|
18
|
+
title: "Probe a document",
|
|
19
|
+
description: DESCRIPTION,
|
|
20
|
+
inputSchema: z.object({
|
|
21
|
+
path: z
|
|
22
|
+
.string()
|
|
23
|
+
.min(1)
|
|
24
|
+
.describe("Path to the document. The filename extension selects the format driver, and " +
|
|
25
|
+
"the container is then verified against it."),
|
|
26
|
+
targets: targetsSchema.optional(),
|
|
27
|
+
level: levelSchema.optional(),
|
|
28
|
+
min_confidence: minConfidenceSchema.optional(),
|
|
29
|
+
target_confidence: targetConfidenceSchema.optional(),
|
|
30
|
+
view: viewSchema.optional(),
|
|
31
|
+
budget: budgetSchema.optional(),
|
|
32
|
+
}),
|
|
33
|
+
outputSchema: envelopeSchema,
|
|
34
|
+
annotations: {
|
|
35
|
+
readOnlyHint: true,
|
|
36
|
+
destructiveHint: false,
|
|
37
|
+
idempotentHint: true,
|
|
38
|
+
openWorldHint: false,
|
|
39
|
+
},
|
|
40
|
+
}, async (args) => guard(async () => {
|
|
41
|
+
const path = resolveInputPath(args.path, context.config);
|
|
42
|
+
return outcomeResult(await context.engine.probe(path, args));
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/tools/probe.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,UAAU,GACX,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,GAAG;;;;;;;;;;0DAUsC,CAAC;AAE3D,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,OAAoB;IACnE,MAAM,CAAC,YAAY,CACjB,OAAO,EACP;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CACP,8EAA8E;gBAC5E,4CAA4C,CAC/C;YACH,OAAO,EAAE,aAAa,CAAC,QAAQ,EAAE;YACjC,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE;YAC7B,cAAc,EAAE,mBAAmB,CAAC,QAAQ,EAAE;YAC9C,iBAAiB,EAAE,sBAAsB,CAAC,QAAQ,EAAE;YACpD,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE;YAC3B,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;SAChC,CAAC;QACF,YAAY,EAAE,cAAc;QAC5B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CACb,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACzD,OAAO,aAAa,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The name clients see in `initialize`; kept short because it prefixes every tool in some UIs. */
|
|
2
|
+
export declare const SERVER_NAME = "deckprobe";
|
|
3
|
+
export declare const SERVER_VERSION: string;
|
|
4
|
+
export declare const PACKAGE_NAME: string;
|
|
5
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAOA,mGAAmG;AACnG,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,cAAc,QAAmB,CAAC;AAC/C,eAAO,MAAM,YAAY,QAAgB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const manifest = createRequire(import.meta.url)("../package.json");
|
|
3
|
+
/** The name clients see in `initialize`; kept short because it prefixes every tool in some UIs. */
|
|
4
|
+
export const SERVER_NAME = "deckprobe";
|
|
5
|
+
export const SERVER_VERSION = manifest.version;
|
|
6
|
+
export const PACKAGE_NAME = manifest.name;
|
|
7
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAGhE,CAAC;AAEF,mGAAmG;AACnG,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deckflow/deckprobe-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for DeckProbe: inspect PDF, Microsoft Office, and Apple iWork documents without rendering them",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "DeckFlow",
|
|
8
|
+
"homepage": "https://github.com/deckflow/deckprobe-mcp-server#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/deckflow/deckprobe-mcp-server.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/deckflow/deckprobe-mcp-server/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"modelcontextprotocol",
|
|
19
|
+
"deckprobe",
|
|
20
|
+
"pdf",
|
|
21
|
+
"docx",
|
|
22
|
+
"xlsx",
|
|
23
|
+
"pptx",
|
|
24
|
+
"keynote",
|
|
25
|
+
"document-metadata",
|
|
26
|
+
"ffprobe"
|
|
27
|
+
],
|
|
28
|
+
"bin": {
|
|
29
|
+
"deckprobe-mcp": "./dist/main.js"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/server.d.ts",
|
|
34
|
+
"default": "./dist/server.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.json",
|
|
45
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"lint": "biome check src tests",
|
|
47
|
+
"lint:fix": "biome check --write src tests",
|
|
48
|
+
"test": "npm run check && npm run lint && npm run build && vitest run",
|
|
49
|
+
"test:watch": "vitest",
|
|
50
|
+
"prepublishOnly": "npm run build"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@deckflow/deckprobe": "^2.4.0",
|
|
54
|
+
"@modelcontextprotocol/server": "^2.0.0",
|
|
55
|
+
"zod": "^4.4.3"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@biomejs/biome": "^2.3.14",
|
|
59
|
+
"@modelcontextprotocol/client": "^2.0.0",
|
|
60
|
+
"@types/node": "^24.10.1",
|
|
61
|
+
"typescript": "^5.9.3",
|
|
62
|
+
"vitest": "^3.2.4"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=20"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public",
|
|
69
|
+
"provenance": true
|
|
70
|
+
}
|
|
71
|
+
}
|