@attentionform/astra-mcp-server 0.0.0-stage → 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,161 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @attentionform/astra-mcp-server visual tool.
4
+ *
5
+ * Dual-mode visual review for MCP:
6
+ * - Level 1 (default, always-on, <500 tokens): deterministic spatial
7
+ * telemetry (ASCII wireframe + large-defect warnings) in every inspect.
8
+ * - Level 2 (opt-in `withVisual:true` tool param only, no launch flag): headless
9
+ * LO -> PDF -> pdftoppm render (PNG default, JPEG opt-in) returning
10
+ * server-side FILE PATHS + metadata (never base64 — token bloat).
11
+ *
12
+ * Missing binaries degrade gracefully with `{ok:false, code:'E_DEPENDENCY',
13
+ * remedy}` (install LibreOffice + poppler-utils). Prompt law applies:
14
+ * image is approximate, XML is truth, large defects only.
15
+ *
16
+ * Engine wiring: session store via ../lib/session-store, visual review via
17
+ * @attentionform/astra-engine (single source of truth, no drift).
18
+ * Standalone module: registered in `src/index.ts` tool table.
19
+ */
20
+ import { z } from 'zod';
21
+ import { type McpSessionStore } from '../lib/session-store';
22
+ import { buildVisualTelemetry, hasVisualPdfBackend as hasPdfBackend, type EngineErrorCode, type VisualImageFormat, type VisualPageMap, type VisualTelemetry } from '@attentionform/astra-engine';
23
+ /** Legacy argv helper; opt-in renders use the withVisual tool param (startup rejects unknown flags). */
24
+ export declare const MCP_VISUAL_FLAG = "--with-visual";
25
+ /** True when argv carries `--with-visual`; startup rejects unknown flags so this enables nothing. */
26
+ export declare function isVisualEnabled(argv?: readonly string[]): boolean;
27
+ export type McpVisualErrorCode = EngineErrorCode;
28
+ export interface McpVisualError {
29
+ ok: false;
30
+ code: McpVisualErrorCode;
31
+ message: string;
32
+ remedy: string;
33
+ }
34
+ export interface VisualImageRef {
35
+ page: number;
36
+ path: string;
37
+ format: VisualImageFormat;
38
+ bytes: number;
39
+ }
40
+ export interface VisualInspectOk {
41
+ ok: true;
42
+ sessionId: string;
43
+ revision: number;
44
+ /**
45
+ * Phase C-1b: true when the in-memory session holds unsaved execute_batch
46
+ * edits — visual renders in-memory session state, not the last saved file.
47
+ */
48
+ dirty: boolean;
49
+ /** Always-on spatial telemetry (<500 tokens). */
50
+ telemetry: VisualTelemetry;
51
+ /** Prompt law + verify rule (vision-model instruction). */
52
+ promptLaw: string;
53
+ verifyRule: string;
54
+ /** Opt-in renders (only when withVisual:true). File paths, not base64. */
55
+ images?: VisualImageRef[];
56
+ totalPages: number;
57
+ outDir?: string;
58
+ /**
59
+ * Advisory stale-seed hint (additive, present only when untouched template
60
+ * seed tables are detected; absent when clean). Lists table node ids whose
61
+ * text still matches known financial-template seed values.
62
+ */
63
+ staleTableIds?: string[];
64
+ /** One-line advisory naming staleTableIds + heuristic limits. */
65
+ staleContentHint?: string;
66
+ /** True when the stale list hit STALE_SEED_TABLE_MAX (ids truncated). */
67
+ staleTruncated?: boolean;
68
+ }
69
+ /**
70
+ * Q0b: pure mapper for render-stage failures (exported for the E-code
71
+ * contract test). Previously every non-DEPENDENCY failure collapsed to E_IO;
72
+ * now the engine code survives verbatim, E_IO stays the uncoded fallback.
73
+ */
74
+ export declare function mapVisualRenderError(err: unknown): McpVisualError;
75
+ /**
76
+ * Q0b: pure mapper for outer (session-resolution) failures. Previously every
77
+ * failure collapsed to E_SESSION; now the engine code survives verbatim,
78
+ * E_SESSION stays the fallback for unknown/expired sessions.
79
+ */
80
+ export declare function mapVisualOuterError(err: unknown): McpVisualError;
81
+ export declare const VisualInspectSchema: z.ZodObject<{
82
+ sessionId: z.ZodString;
83
+ pages: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
84
+ withVisual: z.ZodOptional<z.ZodBoolean>;
85
+ format: z.ZodOptional<z.ZodEnum<{
86
+ png: "png";
87
+ jpeg: "jpeg";
88
+ }>>;
89
+ jpegQuality: z.ZodOptional<z.ZodNumber>;
90
+ dpi: z.ZodOptional<z.ZodNumber>;
91
+ outputDir: z.ZodOptional<z.ZodString>;
92
+ }, z.core.$strict>;
93
+ export type VisualInspectInput = z.infer<typeof VisualInspectSchema>;
94
+ export declare const VISUAL_INSPECT_DESCRIPTION: string;
95
+ /**
96
+ * Stale seed-table hint (advisory, additive, bounded).
97
+ *
98
+ * Detects tables that still carry untouched `financial`-template seed values
99
+ * (Metric/Previous Q/Current Q/Net Revenue seed figures). A table counts as
100
+ * stale when its concatenated text matches >=2 markers — a single generic
101
+ * word (e.g. "Metric") never fires alone. Present only when stale tables
102
+ * exist; clean docs stay silent (no fields emitted).
103
+ *
104
+ * Limits (honest): matches known financial-template seed strings only;
105
+ * custom templates and paraphrased stale content are NOT covered; an edited
106
+ * table still matches until ALL seed strings are replaced. Capped at
107
+ * STALE_SEED_TABLE_MAX ids (staleTruncated:true when capped).
108
+ */
109
+ export declare const STALE_SEED_TABLE_MARKERS: readonly ["Net Revenue", "Operating Profit", "$1,250,000", "$1,520,000", "$340,000", "$415,000", "Previous Q", "Current Q", "Growth (%)"];
110
+ /** Cap on stale table ids listed in one visual_inspect response. */
111
+ export declare const STALE_SEED_TABLE_MAX = 10;
112
+ type StaleAst = {
113
+ sections?: Array<{
114
+ nodes?: Array<{
115
+ id?: unknown;
116
+ type?: unknown;
117
+ metadata?: Record<string, unknown>;
118
+ }>;
119
+ }>;
120
+ };
121
+ /** Table node ids whose text still matches known template seed values (bounded). */
122
+ export declare function findStaleSeedTables(ast: StaleAst): {
123
+ ids: string[];
124
+ truncated: boolean;
125
+ };
126
+ /** One-line advisory hint naming stale table ids (call only when ids non-empty). */
127
+ export declare function buildStaleContentHint(ids: readonly string[], truncated: boolean): string;
128
+ /**
129
+ * Pure telemetry enrichment for `inspect_document` (no MCP store needed).
130
+ * Returns the wireframe + warnings + token count, budget-enforced <500.
131
+ */
132
+ export declare function buildInspectVisualTelemetry(ast: Parameters<typeof buildVisualTelemetry>[0], opts?: {
133
+ page?: number;
134
+ pageMap?: VisualPageMap | null;
135
+ renderTotalPages?: number;
136
+ }): {
137
+ telemetry: VisualTelemetry;
138
+ promptLaw: string;
139
+ verifyRule: string;
140
+ };
141
+ /** Capability probe passthrough (respects PATH at call time). */
142
+ export declare function visualBackendStatus(): ReturnType<typeof hasPdfBackend>;
143
+ /** Artifacts dir passthrough (session workspace folder). */
144
+ export declare function visualArtifactsDir(subDir?: string): string;
145
+ export declare function visualTelemetryBudget(): number;
146
+ export declare function estimateVisualTokens(text: string): number;
147
+ /**
148
+ * Moves rendered images into the caller's folder as `<document>-page-<n>.<ext>`.
149
+ * The folder was already checked against the allowed roots. The write refuses a
150
+ * symlink anywhere on the path and opens the name with O_NOFOLLOW, so a link
151
+ * planted before or during the write cannot redirect it. A file already under
152
+ * that name is replaced: it is the previous render of the same page.
153
+ */
154
+ export declare function placeImages(images: VisualImageRef[], dir: string, docPath: string): VisualImageRef[];
155
+ /**
156
+ * Store-aware handler: telemetry always, file-path images only when
157
+ * `withVisual:true`. Never throws — maps every failure to the
158
+ * `{ok:false, code, remedy}` contract (E_DEPENDENCY for missing binaries).
159
+ */
160
+ export declare function handleVisualInspect(store: McpSessionStore, input: unknown): Promise<VisualInspectOk | McpVisualError>;
161
+ export {};
package/package.json CHANGED
@@ -1,6 +1,71 @@
1
1
  {
2
2
  "name": "@attentionform/astra-mcp-server",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Official Model Context Protocol (MCP) server for ASTra document IDE",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "astra-mcp-server": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE",
14
+ "NOTICE",
15
+ "!dist/**/*.map"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "license": "BUSL-1.1",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/Attentionform/astra.git",
24
+ "directory": "packages/mcp-server"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "astra",
30
+ "ooxml",
31
+ "docx",
32
+ "word",
33
+ "ai-agent"
34
+ ],
35
+ "type": "commonjs",
36
+ "scripts": {
37
+ "build": "node ../../scripts/check-adm-zip-imports.mjs && tsc --noEmit -p tsconfig.json && esbuild src/index.ts --bundle --packages=external --platform=node --target=node20 --format=cjs --outfile=dist/index.js --log-level=warning && tsc -p tsconfig.dts.json && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
38
+ "typecheck": "tsc --noEmit -p tsconfig.json",
39
+ "test": "vitest run",
40
+ "start": "node dist/index.js",
41
+ "adm-zip-gate": "node ../../scripts/check-adm-zip-imports.mjs"
42
+ },
43
+ "dependencies": {
44
+ "@attentionform/astra-engine": "^0.1.0",
45
+ "@attentionform/ooxml-validator": "^0.1.0",
46
+ "@modelcontextprotocol/sdk": "^1.32.2",
47
+ "@xmldom/xmldom": "0.8.15",
48
+ "adm-zip": "0.6.1",
49
+ "isomorphic-git": "^1.25.0",
50
+ "marked": "18.0.5",
51
+ "p-limit": "^3.1.0",
52
+ "zod": "4.6.7"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^25.9.1",
56
+ "esbuild": "^0.25.12",
57
+ "typescript": "^5.2.2",
58
+ "vitest": "^4.1.7"
59
+ },
60
+ "engines": {
61
+ "node": ">=22.19.0"
62
+ },
63
+ "homepage": "https://attentionform.com",
64
+ "bugs": {
65
+ "url": "https://github.com/Attentionform/astra/issues"
66
+ },
67
+ "author": {
68
+ "name": "Attentionform",
69
+ "url": "https://attentionform.com"
70
+ }
71
+ }