@docdigitizer/mcp-server 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/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @docdigitizer/mcp-server
2
+
3
+ MCP (Model Context Protocol) server for the DocDigitizer document processing API. Enables Claude Desktop and Claude Code to process PDFs and extract structured data directly.
4
+
5
+ ## Quick Start
6
+
7
+ ### Claude Desktop
8
+
9
+ Add to your `claude_desktop_config.json`:
10
+
11
+ ```json
12
+ {
13
+ "mcpServers": {
14
+ "docdigitizer": {
15
+ "command": "npx",
16
+ "args": ["-y", "@docdigitizer/mcp-server"],
17
+ "env": {
18
+ "DOCDIGITIZER_API_KEY": "your-api-key"
19
+ }
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ ### Claude Code
26
+
27
+ Add to your Claude Code MCP settings:
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "docdigitizer": {
33
+ "command": "npx",
34
+ "args": ["-y", "@docdigitizer/mcp-server"],
35
+ "env": {
36
+ "DOCDIGITIZER_API_KEY": "your-api-key"
37
+ }
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Tools
44
+
45
+ ### `health_check`
46
+
47
+ Check if the DocDigitizer API is available.
48
+
49
+ **Parameters:** None
50
+
51
+ **Example prompt:** "Check if DocDigitizer is healthy"
52
+
53
+ ### `process_document`
54
+
55
+ Upload and process a PDF document. Extracts structured data from invoices, receipts, contracts, CVs, IDs, and bank statements.
56
+
57
+ **Parameters:**
58
+
59
+ | Parameter | Type | Required | Description |
60
+ |-----------|------|----------|-------------|
61
+ | `file_path` | string | One of file_path or file_content | Absolute path to a local PDF file |
62
+ | `file_content` | string | One of file_path or file_content | Base64-encoded PDF content |
63
+ | `file_name` | string | No | Filename hint |
64
+ | `document_id` | string (UUID) | No | Document UUID for tracking |
65
+ | `context_id` | string (UUID) | No | Context UUID for grouping |
66
+ | `pipeline` | string | No | Processing pipeline name |
67
+ | `request_token` | string | No | Trace token (max 7 chars) |
68
+
69
+ **Example prompts:**
70
+ - "Process the invoice at C:/Documents/invoice.pdf"
71
+ - "Extract data from the PDF at /home/user/receipt.pdf"
72
+
73
+ ## Configuration
74
+
75
+ | Environment Variable | Required | Default | Description |
76
+ |---------------------|----------|---------|-------------|
77
+ | `DOCDIGITIZER_API_KEY` | Yes | — | Your DocDigitizer API key |
78
+ | `DOCDIGITIZER_BASE_URL` | No | `https://apix.docdigitizer.com/sync` | API base URL |
79
+ | `DOCDIGITIZER_TIMEOUT` | No | `300000` (5 min) | Request timeout in ms |
80
+
81
+ ## Development
82
+
83
+ ```bash
84
+ npm install
85
+ npm run build
86
+ npm test
87
+ ```
88
+
89
+ ### Testing with MCP Inspector
90
+
91
+ ```bash
92
+ DOCDIGITIZER_API_KEY=your-key npx @modelcontextprotocol/inspector node dist/index.js
93
+ ```
94
+
95
+ ## License
96
+
97
+ MIT
@@ -0,0 +1,16 @@
1
+ import type { Config } from "./config.js";
2
+ import type { ProcessingResponse } from "./types.js";
3
+ export declare class ApiClient {
4
+ private readonly config;
5
+ constructor(config: Config);
6
+ healthCheck(): Promise<string>;
7
+ processDocument(options: {
8
+ filePath?: string;
9
+ fileContent?: string;
10
+ fileName?: string;
11
+ id?: string;
12
+ contextId?: string;
13
+ pipelineIdentifier?: string;
14
+ requestToken?: string;
15
+ }): Promise<ProcessingResponse>;
16
+ }
@@ -0,0 +1,65 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { parseResponse } from "./types.js";
5
+ import { raiseForStatus } from "./errors.js";
6
+ export class ApiClient {
7
+ config;
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ async healthCheck() {
12
+ const response = await fetch(`${this.config.baseUrl}/`, {
13
+ method: "GET",
14
+ signal: AbortSignal.timeout(this.config.timeout),
15
+ });
16
+ if (response.status >= 400) {
17
+ raiseForStatus(response.status);
18
+ }
19
+ return response.text();
20
+ }
21
+ async processDocument(options) {
22
+ let fileBuffer;
23
+ let fileName;
24
+ if (options.filePath) {
25
+ fileBuffer = await readFile(options.filePath);
26
+ fileName = options.fileName ?? basename(options.filePath);
27
+ }
28
+ else if (options.fileContent) {
29
+ fileBuffer = Buffer.from(options.fileContent, "base64");
30
+ fileName = options.fileName ?? "document.pdf";
31
+ }
32
+ else {
33
+ throw new Error("Either filePath or fileContent (base64) is required");
34
+ }
35
+ const form = new FormData();
36
+ const blob = new Blob([fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength)], { type: "application/pdf" });
37
+ form.append("files", blob, fileName);
38
+ form.append("id", options.id ?? randomUUID());
39
+ form.append("contextID", options.contextId ?? randomUUID());
40
+ if (options.pipelineIdentifier) {
41
+ form.append("pipelineIdentifier", options.pipelineIdentifier);
42
+ }
43
+ if (options.requestToken) {
44
+ form.append("requestToken", options.requestToken);
45
+ }
46
+ const response = await fetch(`${this.config.baseUrl}/`, {
47
+ method: "POST",
48
+ headers: { "X-API-Key": this.config.apiKey },
49
+ body: form,
50
+ signal: AbortSignal.timeout(this.config.timeout),
51
+ });
52
+ let body = {};
53
+ try {
54
+ body = (await response.json());
55
+ }
56
+ catch {
57
+ // Non-JSON response
58
+ }
59
+ if (response.status >= 400) {
60
+ raiseForStatus(response.status, (body.traceId ?? body.TraceId) || undefined, (body.messages ?? body.Messages) || undefined, (body.timers ?? body.Timers) || undefined);
61
+ }
62
+ return parseResponse(body);
63
+ }
64
+ }
65
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface Config {
2
+ apiKey: string;
3
+ baseUrl: string;
4
+ timeout: number;
5
+ }
6
+ export declare function loadConfig(): Config;
package/dist/config.js ADDED
@@ -0,0 +1,14 @@
1
+ const DEFAULT_BASE_URL = "https://apix.docdigitizer.com/sync";
2
+ const DEFAULT_TIMEOUT = 300_000; // 5 minutes
3
+ export function loadConfig() {
4
+ const apiKey = process.env.DOCDIGITIZER_API_KEY ?? "";
5
+ if (!apiKey) {
6
+ throw new Error("DOCDIGITIZER_API_KEY is required. Set it as an environment variable.");
7
+ }
8
+ const baseUrl = (process.env.DOCDIGITIZER_BASE_URL ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
9
+ const timeout = process.env.DOCDIGITIZER_TIMEOUT
10
+ ? parseInt(process.env.DOCDIGITIZER_TIMEOUT, 10)
11
+ : DEFAULT_TIMEOUT;
12
+ return { apiKey, baseUrl, timeout };
13
+ }
14
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,gBAAgB,GAAG,oCAAoC,CAAC;AAC9D,MAAM,eAAe,GAAG,OAAO,CAAC,CAAC,YAAY;AAE7C,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,CACd,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,gBAAgB,CACtD,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAEtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC9C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAChD,CAAC,CAAC,eAAe,CAAC;IAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC"}
@@ -0,0 +1,26 @@
1
+ export declare class DocDigitizerError extends Error {
2
+ readonly statusCode?: number | undefined;
3
+ readonly traceId?: string | undefined;
4
+ readonly messages?: string[] | undefined;
5
+ readonly timers?: Record<string, unknown> | undefined;
6
+ constructor(message: string, statusCode?: number | undefined, traceId?: string | undefined, messages?: string[] | undefined, timers?: Record<string, unknown> | undefined);
7
+ }
8
+ export declare class AuthenticationError extends DocDigitizerError {
9
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
10
+ }
11
+ export declare class ValidationError extends DocDigitizerError {
12
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
13
+ }
14
+ export declare class RateLimitError extends DocDigitizerError {
15
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
16
+ }
17
+ export declare class ServerError extends DocDigitizerError {
18
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
19
+ }
20
+ export declare class ServiceUnavailableError extends DocDigitizerError {
21
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
22
+ }
23
+ export declare class TimeoutError extends DocDigitizerError {
24
+ constructor(...args: ConstructorParameters<typeof DocDigitizerError>);
25
+ }
26
+ export declare function raiseForStatus(statusCode: number, traceId?: string, messages?: string[], timers?: Record<string, unknown>): never;
package/dist/errors.js ADDED
@@ -0,0 +1,64 @@
1
+ export class DocDigitizerError extends Error {
2
+ statusCode;
3
+ traceId;
4
+ messages;
5
+ timers;
6
+ constructor(message, statusCode, traceId, messages, timers) {
7
+ super(message);
8
+ this.statusCode = statusCode;
9
+ this.traceId = traceId;
10
+ this.messages = messages;
11
+ this.timers = timers;
12
+ this.name = "DocDigitizerError";
13
+ }
14
+ }
15
+ export class AuthenticationError extends DocDigitizerError {
16
+ constructor(...args) {
17
+ super(...args);
18
+ this.name = "AuthenticationError";
19
+ }
20
+ }
21
+ export class ValidationError extends DocDigitizerError {
22
+ constructor(...args) {
23
+ super(...args);
24
+ this.name = "ValidationError";
25
+ }
26
+ }
27
+ export class RateLimitError extends DocDigitizerError {
28
+ constructor(...args) {
29
+ super(...args);
30
+ this.name = "RateLimitError";
31
+ }
32
+ }
33
+ export class ServerError extends DocDigitizerError {
34
+ constructor(...args) {
35
+ super(...args);
36
+ this.name = "ServerError";
37
+ }
38
+ }
39
+ export class ServiceUnavailableError extends DocDigitizerError {
40
+ constructor(...args) {
41
+ super(...args);
42
+ this.name = "ServiceUnavailableError";
43
+ }
44
+ }
45
+ export class TimeoutError extends DocDigitizerError {
46
+ constructor(...args) {
47
+ super(...args);
48
+ this.name = "TimeoutError";
49
+ }
50
+ }
51
+ const STATUS_CODE_MAP = {
52
+ 400: ValidationError,
53
+ 401: AuthenticationError,
54
+ 429: RateLimitError,
55
+ 500: ServerError,
56
+ 503: ServiceUnavailableError,
57
+ 504: TimeoutError,
58
+ };
59
+ export function raiseForStatus(statusCode, traceId, messages, timers) {
60
+ const ErrorClass = STATUS_CODE_MAP[statusCode] ?? DocDigitizerError;
61
+ const msg = messages?.join("; ") ?? `HTTP ${statusCode}`;
62
+ throw new ErrorClass(msg, statusCode, traceId, messages, timers);
63
+ }
64
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAGxB;IACA;IACA;IACA;IALlB,YACE,OAAe,EACC,UAAmB,EACnB,OAAgB,EAChB,QAAmB,EACnB,MAAgC;QAEhD,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,eAAU,GAAV,UAAU,CAAS;QACnB,YAAO,GAAP,OAAO,CAAS;QAChB,aAAQ,GAAR,QAAQ,CAAW;QACnB,WAAM,GAAN,MAAM,CAA0B;QAGhD,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,iBAAiB;IACxD,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IACpD,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,iBAAiB;IACnD,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,iBAAiB;IAChD,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,iBAAiB;IAC5D,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,iBAAiB;IACjD,YAAY,GAAG,IAAqD;QAClE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,eAAe,GAA6C;IAChE,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,YAAY;CAClB,CAAC;AAEF,MAAM,UAAU,cAAc,CAC5B,UAAkB,EAClB,OAAgB,EAChB,QAAmB,EACnB,MAAgC;IAEhC,MAAM,UAAU,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,iBAAiB,CAAC;IACpE,MAAM,GAAG,GAAG,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,UAAU,EAAE,CAAC;IACzD,MAAM,IAAI,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { createServer } from "./server.js";
4
+ async function main() {
5
+ const server = createServer();
6
+ const transport = new StdioServerTransport();
7
+ await server.connect(transport);
8
+ console.error("DocDigitizer MCP server running on stdio");
9
+ }
10
+ main().catch((error) => {
11
+ console.error("Fatal error:", error);
12
+ process.exit(1);
13
+ });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function createServer(): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,131 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { loadConfig } from "./config.js";
4
+ import { ApiClient } from "./api-client.js";
5
+ import { DocDigitizerError } from "./errors.js";
6
+ export function createServer() {
7
+ const config = loadConfig();
8
+ const client = new ApiClient(config);
9
+ const server = new McpServer({
10
+ name: "docdigitizer",
11
+ version: "0.1.0",
12
+ });
13
+ server.tool("health_check", "Check if the DocDigitizer API is available and responsive", {}, async () => {
14
+ try {
15
+ const text = await client.healthCheck();
16
+ return {
17
+ content: [
18
+ {
19
+ type: "text",
20
+ text: JSON.stringify({ status: "ok", message: text }),
21
+ },
22
+ ],
23
+ };
24
+ }
25
+ catch (error) {
26
+ return errorResult(error);
27
+ }
28
+ });
29
+ server.tool("process_document", "Upload and process a PDF document through DocDigitizer. " +
30
+ "Extracts structured data from invoices, receipts, contracts, CVs, IDs, and bank statements. " +
31
+ "Provide either file_path (local path) or file_content (base64-encoded PDF).", {
32
+ file_path: z
33
+ .string()
34
+ .optional()
35
+ .describe("Absolute path to a local PDF file"),
36
+ file_content: z
37
+ .string()
38
+ .optional()
39
+ .describe("Base64-encoded PDF content"),
40
+ file_name: z
41
+ .string()
42
+ .optional()
43
+ .describe("Filename hint (defaults to basename of file_path or 'document.pdf')"),
44
+ document_id: z
45
+ .string()
46
+ .uuid()
47
+ .optional()
48
+ .describe("Document UUID for tracking (auto-generated if omitted)"),
49
+ context_id: z
50
+ .string()
51
+ .uuid()
52
+ .optional()
53
+ .describe("Context UUID for grouping related documents (auto-generated if omitted)"),
54
+ pipeline: z
55
+ .string()
56
+ .optional()
57
+ .describe("Processing pipeline (e.g. 'MainPipelineWithOCR')"),
58
+ request_token: z
59
+ .string()
60
+ .optional()
61
+ .describe("Trace token (max 7 chars, auto-generated if omitted)"),
62
+ }, async (params) => {
63
+ if (!params.file_path && !params.file_content) {
64
+ return {
65
+ isError: true,
66
+ content: [
67
+ {
68
+ type: "text",
69
+ text: JSON.stringify({
70
+ error: "ValidationError",
71
+ message: "Either file_path or file_content (base64) is required",
72
+ }),
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ try {
78
+ const result = await client.processDocument({
79
+ filePath: params.file_path,
80
+ fileContent: params.file_content,
81
+ fileName: params.file_name,
82
+ id: params.document_id,
83
+ contextId: params.context_id,
84
+ pipelineIdentifier: params.pipeline,
85
+ requestToken: params.request_token,
86
+ });
87
+ return {
88
+ content: [
89
+ {
90
+ type: "text",
91
+ text: JSON.stringify(result, null, 2),
92
+ },
93
+ ],
94
+ };
95
+ }
96
+ catch (error) {
97
+ return errorResult(error);
98
+ }
99
+ });
100
+ return server;
101
+ }
102
+ function errorResult(error) {
103
+ if (error instanceof DocDigitizerError) {
104
+ return {
105
+ isError: true,
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: JSON.stringify({
110
+ error: error.name,
111
+ message: error.message,
112
+ statusCode: error.statusCode,
113
+ traceId: error.traceId,
114
+ messages: error.messages,
115
+ }),
116
+ },
117
+ ],
118
+ };
119
+ }
120
+ const msg = error instanceof Error ? error.message : String(error);
121
+ return {
122
+ isError: true,
123
+ content: [
124
+ {
125
+ type: "text",
126
+ text: JSON.stringify({ error: "Error", message: msg }),
127
+ },
128
+ ],
129
+ };
130
+ }
131
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface PageRange {
2
+ start: number;
3
+ end: number;
4
+ }
5
+ export interface Extraction {
6
+ documentType: string;
7
+ confidence: number;
8
+ countryCode: string;
9
+ pages: number[];
10
+ pageRange?: PageRange;
11
+ extraction: Record<string, unknown>;
12
+ schema?: string;
13
+ modelSource?: string;
14
+ }
15
+ export interface ProcessingOutput {
16
+ extractions: Extraction[];
17
+ }
18
+ export interface ProcessingResponse {
19
+ state: string;
20
+ traceId: string;
21
+ pipeline?: string;
22
+ numPages?: number;
23
+ output?: ProcessingOutput;
24
+ timers?: Record<string, unknown>;
25
+ messages?: string[];
26
+ }
27
+ export declare function parseResponse(data: Record<string, unknown>): ProcessingResponse;
package/dist/types.js ADDED
@@ -0,0 +1,49 @@
1
+ function get(data, camel, pascal, fallback) {
2
+ if (camel in data)
3
+ return data[camel];
4
+ if (pascal in data)
5
+ return data[pascal];
6
+ return fallback;
7
+ }
8
+ function parseExtraction(raw) {
9
+ const pages = (raw.pages ?? []);
10
+ const pageRangeRaw = raw.pageRange;
11
+ let pageRange;
12
+ if (pageRangeRaw && typeof pageRangeRaw === "object") {
13
+ pageRange = { start: pageRangeRaw.start, end: pageRangeRaw.end };
14
+ }
15
+ else if (pages.length > 0) {
16
+ pageRange = { start: Math.min(...pages), end: Math.max(...pages) };
17
+ }
18
+ return {
19
+ documentType: get(raw, "docType", "documentType", ""),
20
+ confidence: (raw.confidence ?? 0),
21
+ countryCode: get(raw, "country", "countryCode", ""),
22
+ pages,
23
+ pageRange,
24
+ extraction: (raw.extraction ?? {}),
25
+ schema: raw.schema,
26
+ modelSource: raw.modelSource,
27
+ };
28
+ }
29
+ function parseOutput(raw) {
30
+ if (!raw || typeof raw !== "object")
31
+ return undefined;
32
+ const obj = raw;
33
+ const rawExtractions = (obj.extractions ?? []);
34
+ return {
35
+ extractions: rawExtractions.map(parseExtraction),
36
+ };
37
+ }
38
+ export function parseResponse(data) {
39
+ return {
40
+ state: get(data, "stateText", "StateText", ""),
41
+ traceId: get(data, "traceId", "TraceId", ""),
42
+ pipeline: get(data, "pipeline", "Pipeline"),
43
+ numPages: get(data, "numberPages", "NumberPages"),
44
+ output: parseOutput(get(data, "output", "Output")),
45
+ timers: get(data, "timers", "Timers"),
46
+ messages: get(data, "messages", "Messages"),
47
+ };
48
+ }
49
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA8BA,SAAS,GAAG,CACV,IAA6B,EAC7B,KAAa,EACb,MAAc,EACd,QAAkB;IAElB,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CAAC,GAA4B;IACnD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAa,CAAC;IAC5C,MAAM,YAAY,GAAG,GAAG,CAAC,SAEZ,CAAC;IACd,IAAI,SAAgC,CAAC;IAErC,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACrD,SAAS,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC;IACnE,CAAC;SAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,SAAS,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;IACrE,CAAC;IAED,OAAO;QACL,YAAY,EAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,CAAY;QACjE,UAAU,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,CAAW;QAC3C,WAAW,EAAG,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,CAAY;QAC/D,KAAK;QACL,SAAS;QACT,UAAU,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAA4B;QAC7D,MAAM,EAAE,GAAG,CAAC,MAA4B;QACxC,WAAW,EAAE,GAAG,CAAC,WAAiC;KACnD,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAClB,GAAY;IAEZ,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACtD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAA8B,CAAC;IAC5E,OAAO;QACL,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC;KACjD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,IAA6B;IAE7B,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,EAAE,CAAW;QACxD,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAW;QACtD,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAuB;QACjE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,aAAa,CAAuB;QACvE,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAEvB;QACb,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAyB;KACpE,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@docdigitizer/mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for DocDigitizer document processing API",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "docdigitizer-mcp": "./dist/index.js"
9
+ },
10
+ "main": "dist/index.js",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "start": "node dist/index.js",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.27.1",
27
+ "zod": "^3.25.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^18.0.0",
31
+ "typescript": "^5.5.0",
32
+ "vitest": "^3.0.0",
33
+ "yaml": "^2.7.0"
34
+ },
35
+ "author": {
36
+ "name": "DocDigitizer",
37
+ "email": "support@docdigitizer.com"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/DocDigitizer/dd-v3-integrations",
42
+ "directory": "integrations/mcp-server"
43
+ },
44
+ "keywords": [
45
+ "docdigitizer",
46
+ "mcp",
47
+ "model-context-protocol",
48
+ "claude",
49
+ "ocr",
50
+ "document-processing",
51
+ "pdf"
52
+ ]
53
+ }