@pageindex/sdk 0.3.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,133 @@
1
+ # @pageindex/sdk
2
+
3
+ TypeScript SDK for [PageIndex](https://pageindex.ai) document processing.
4
+
5
+ Get your API Key at [dash.pageindex.ai](https://dash.pageindex.ai/api-keys). For full API documentation, see [docs.pageindex.ai](https://docs.pageindex.ai).
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add @pageindex/sdk
11
+ ```
12
+
13
+ Requires Node.js >= 18.0.0
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { PageIndexClient } from '@pageindex/sdk';
19
+
20
+ const client = new PageIndexClient({
21
+ apiKey: 'your-api-key',
22
+ });
23
+
24
+ // Upload a document
25
+ const { doc_id } = await client.api.submitDocument(fileBuffer, 'report.pdf');
26
+
27
+ // List recent documents
28
+ const recent = await client.tools.recentDocuments();
29
+
30
+ // Extract document structure
31
+ const structure = await client.tools.getDocumentStructure({ docName: 'report.pdf' });
32
+
33
+ // Extract page content
34
+ const pages = await client.tools.getPageContent({ docName: 'report.pdf', pages: '1-5' });
35
+ ```
36
+
37
+ With explicit resource management (TypeScript 5.2+):
38
+
39
+ ```typescript
40
+ await using client = new PageIndexClient({ apiKey: 'your-api-key' });
41
+ const recent = await client.tools.recentDocuments();
42
+ // connection closed automatically when scope exits
43
+ ```
44
+
45
+ ## API
46
+
47
+ ### Client
48
+
49
+ ```typescript
50
+ const client = new PageIndexClient({
51
+ apiKey: 'your-api-key',
52
+ apiUrl: 'https://api.pageindex.ai', // optional, this is the default
53
+ folderScope: 'folder-id', // optional
54
+ });
55
+ ```
56
+
57
+ ### Tools
58
+
59
+ All methods via `client.tools`:
60
+
61
+ | Method | Description |
62
+ | -------------------------------------------------------------- | ----------------------------------- |
63
+ | `recentDocuments()` | List recent uploads |
64
+ | `findRelevantDocuments({ nameOrDescriptionFilter?, limit? })` | Search documents |
65
+ | `getDocument({ docName, waitForCompletion? })` | Get document details |
66
+ | `getDocumentStructure({ docName, part?, waitForCompletion? })` | Extract document outline |
67
+ | `getPageContent({ docName, pages, waitForCompletion? })` | Extract page content |
68
+ | `removeDocument({ docNames })` | Delete documents |
69
+ | `createFolder({ name, description?, parentFolderId? })` | Create folder |
70
+ | `listFolders({ parentFolderId? })` | List folders |
71
+
72
+ Page specification formats: `"5"`, `"3,7,10"`, `"5-10"`, `"1-3,7,9-12"`
73
+
74
+ ### API
75
+
76
+ All methods via `client.api`:
77
+
78
+ ```typescript
79
+ // Submit a document
80
+ const result = await client.api.submitDocument(file, 'document.pdf');
81
+
82
+ // Get document metadata
83
+ const doc = await client.api.getDocument(docId);
84
+
85
+ // Get document tree structure
86
+ const tree = await client.api.getTree(docId, { summary: true });
87
+
88
+ // Get OCR content
89
+ const ocr = await client.api.getOcr(docId, { format: 'page' });
90
+
91
+ // List all documents
92
+ const docs = await client.api.listDocuments({ limit: 20, offset: 0 });
93
+
94
+ // Delete a document
95
+ await client.api.deleteDocument(docId);
96
+
97
+ // Chat completions
98
+ const chat = await client.api.chatCompletions({
99
+ messages: [{ role: 'user', content: 'Summarize the document' }],
100
+ doc_id: docId,
101
+ });
102
+
103
+ ```
104
+
105
+ ### Error Handling
106
+
107
+ ```typescript
108
+ import { PageIndexError } from '@pageindex/sdk';
109
+
110
+ try {
111
+ await client.tools.getDocument({ docName: 'xxx' });
112
+ } catch (e) {
113
+ if (e instanceof PageIndexError) {
114
+ // e.code: 'NOT_FOUND' | 'UNAUTHORIZED' | 'RATE_LIMITED' | 'USAGE_LIMIT_REACHED' | ...
115
+ // e.statusCode: HTTP status code
116
+ }
117
+ }
118
+ ```
119
+
120
+ ## Documentation
121
+
122
+ - [API Quickstart](https://docs.pageindex.ai/quickstart) — Get started with document processing
123
+ - [API Endpoints](https://docs.pageindex.ai/endpoints) — Full REST API reference
124
+ - [Python SDK](https://docs.pageindex.ai/sdk) — Python client (tree, chat, OCR)
125
+ - [MCP Integration](https://docs.pageindex.ai/cookbook/mcp) — Use PageIndex with AI agents
126
+
127
+ ## Examples
128
+
129
+ See [examples/chat-demo](./examples/chat-demo) for Next.js + AI SDK integration.
130
+
131
+ ## License
132
+
133
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,326 @@
1
+ let _modelcontextprotocol_sdk_client_index_js = require("@modelcontextprotocol/sdk/client/index.js");
2
+ let _modelcontextprotocol_sdk_client_streamableHttp_js = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
3
+
4
+ //#region src/errors.ts
5
+ var PageIndexError = class extends Error {
6
+ constructor(message, code, details, statusCode) {
7
+ super(message);
8
+ this.code = code;
9
+ this.details = details;
10
+ this.statusCode = statusCode;
11
+ this.name = "PageIndexError";
12
+ }
13
+ };
14
+
15
+ //#endregion
16
+ //#region src/api/client.ts
17
+ var PageIndexApi = class {
18
+ baseUrl;
19
+ apiKey;
20
+ folderScope;
21
+ constructor(config) {
22
+ this.baseUrl = config.apiUrl.replace(/\/$/, "");
23
+ this.apiKey = config.apiKey;
24
+ this.folderScope = config.folderScope;
25
+ }
26
+ async submitDocument(file, fileName, options) {
27
+ const formData = new FormData();
28
+ const blob = file instanceof Blob ? file : new Blob([file], { type: "application/octet-stream" });
29
+ formData.append("file", blob, fileName);
30
+ if (options?.mode) formData.append("mode", options.mode);
31
+ const folderId = options?.folderId ?? this.folderScope;
32
+ if (folderId) formData.append("folder_id", folderId);
33
+ return this.requestMultipart("/doc/", formData);
34
+ }
35
+ async getDocument(docId) {
36
+ return this.request(`/doc/${encodeURIComponent(docId)}/metadata`);
37
+ }
38
+ async getTree(docId, options) {
39
+ const params = new URLSearchParams({ type: "tree" });
40
+ if (options?.summary !== void 0) params.set("summary", String(options.summary));
41
+ return this.request(`/doc/${encodeURIComponent(docId)}/?${params}`);
42
+ }
43
+ async getOcr(docId, options) {
44
+ const params = new URLSearchParams({ type: "ocr" });
45
+ if (options?.format) params.set("format", options.format);
46
+ return this.request(`/doc/${encodeURIComponent(docId)}/?${params}`);
47
+ }
48
+ async listDocuments(options) {
49
+ const params = new URLSearchParams();
50
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
51
+ if (options?.offset !== void 0) params.set("offset", String(options.offset));
52
+ const folderId = options?.folderId ?? this.folderScope;
53
+ if (folderId) params.set("folder_id", folderId);
54
+ const qs = params.toString();
55
+ return this.request(`/docs${qs ? `?${qs}` : ""}`);
56
+ }
57
+ async deleteDocument(docId) {
58
+ return this.request(`/doc/${encodeURIComponent(docId)}/`, { method: "DELETE" });
59
+ }
60
+ async chatCompletions(params) {
61
+ return this.request("/chat/completions", {
62
+ method: "POST",
63
+ headers: { "Content-Type": "application/json" },
64
+ body: JSON.stringify(params)
65
+ });
66
+ }
67
+ async request(path, init) {
68
+ const url = `${this.baseUrl}${path}`;
69
+ const response = await fetch(url, {
70
+ ...init,
71
+ headers: {
72
+ api_key: this.apiKey,
73
+ ...init?.headers
74
+ }
75
+ });
76
+ return this.handleResponse(response);
77
+ }
78
+ async requestMultipart(path, formData) {
79
+ const url = `${this.baseUrl}${path}`;
80
+ const response = await fetch(url, {
81
+ method: "POST",
82
+ headers: { api_key: this.apiKey },
83
+ body: formData
84
+ });
85
+ return this.handleResponse(response);
86
+ }
87
+ async handleResponse(response) {
88
+ if (!response.ok) {
89
+ const text = await response.text().catch(() => "");
90
+ let message = `API request failed with status ${response.status}`;
91
+ let errorCode = this.mapStatusToErrorCode(response.status);
92
+ let details;
93
+ try {
94
+ const json = JSON.parse(text);
95
+ if (json.error && typeof json.error === "string") message = json.error;
96
+ if (json.errorCode && typeof json.errorCode === "string") errorCode = json.errorCode;
97
+ details = json;
98
+ } catch {
99
+ if (text) message = text;
100
+ }
101
+ throw new PageIndexError(message, errorCode, details, response.status);
102
+ }
103
+ return response.json();
104
+ }
105
+ mapStatusToErrorCode(status) {
106
+ switch (status) {
107
+ case 401: return "UNAUTHORIZED";
108
+ case 404: return "NOT_FOUND";
109
+ case 429: return "RATE_LIMITED";
110
+ case 503: return "SERVICE_UNAVAILABLE";
111
+ default: return "INTERNAL_ERROR";
112
+ }
113
+ }
114
+ };
115
+
116
+ //#endregion
117
+ //#region src/tools/create-folder.ts
118
+ async function createFolder(transport, params) {
119
+ return transport.callTool("create_folder", {
120
+ name: params.name,
121
+ description: params.description,
122
+ parent_folder_id: params.parentFolderId
123
+ });
124
+ }
125
+
126
+ //#endregion
127
+ //#region src/tools/find-relevant-documents.ts
128
+ async function findRelevantDocuments(transport, params) {
129
+ return transport.callTool("find_relevant_documents", {
130
+ name_or_description_filter: params?.nameOrDescriptionFilter,
131
+ cursor: params?.cursor,
132
+ limit: params?.limit
133
+ });
134
+ }
135
+
136
+ //#endregion
137
+ //#region src/tools/get-document-structure.ts
138
+ async function getDocumentStructure(transport, params) {
139
+ return transport.callTool("get_document_structure", {
140
+ doc_name: params.docName,
141
+ part: params.part,
142
+ wait_for_completion: params.waitForCompletion
143
+ });
144
+ }
145
+
146
+ //#endregion
147
+ //#region src/tools/get-document.ts
148
+ async function getDocument(transport, params) {
149
+ return transport.callTool("get_document", {
150
+ doc_name: params.docName,
151
+ wait_for_completion: params.waitForCompletion
152
+ });
153
+ }
154
+
155
+ //#endregion
156
+ //#region src/tools/get-page-content.ts
157
+ async function getPageContent(transport, params) {
158
+ return transport.callTool("get_page_content", {
159
+ doc_name: params.docName,
160
+ pages: params.pages,
161
+ wait_for_completion: params.waitForCompletion
162
+ });
163
+ }
164
+
165
+ //#endregion
166
+ //#region src/tools/list-folders.ts
167
+ async function listFolders(transport, params) {
168
+ return transport.callTool("list_folders", { parent_folder_id: params?.parentFolderId });
169
+ }
170
+
171
+ //#endregion
172
+ //#region src/tools/recent-documents.ts
173
+ async function recentDocuments(transport) {
174
+ return transport.callTool("recent_documents", {});
175
+ }
176
+
177
+ //#endregion
178
+ //#region src/tools/remove-document.ts
179
+ async function removeDocument(transport, params) {
180
+ return transport.callTool("remove_document", { doc_names: params.docNames });
181
+ }
182
+
183
+ //#endregion
184
+ //#region src/tools/index.ts
185
+ var PageIndexTools = class {
186
+ constructor(transport) {
187
+ this.transport = transport;
188
+ }
189
+ recentDocuments = () => recentDocuments(this.transport);
190
+ findRelevantDocuments = (params) => findRelevantDocuments(this.transport, params);
191
+ createFolder = (params) => createFolder(this.transport, params);
192
+ listFolders = (params) => listFolders(this.transport, params);
193
+ getDocument = (params) => getDocument(this.transport, params);
194
+ getDocumentStructure = (params) => getDocumentStructure(this.transport, params);
195
+ getPageContent = (params) => getPageContent(this.transport, params);
196
+ removeDocument = (params) => removeDocument(this.transport, params);
197
+ };
198
+
199
+ //#endregion
200
+ //#region package.json
201
+ var name = "@pageindex/sdk";
202
+ var version = "0.3.0";
203
+
204
+ //#endregion
205
+ //#region src/transport.ts
206
+ var McpTransport = class {
207
+ client = new _modelcontextprotocol_sdk_client_index_js.Client({
208
+ name,
209
+ version
210
+ }, { capabilities: {} });
211
+ transport = null;
212
+ connected = false;
213
+ folderScope;
214
+ idleTimeout;
215
+ idleTimer = null;
216
+ constructor(config) {
217
+ this.config = config;
218
+ this.folderScope = config.folderScope;
219
+ this.idleTimeout = config.idleTimeout ?? 6e4;
220
+ }
221
+ resetIdleTimer() {
222
+ if (this.idleTimer) clearTimeout(this.idleTimer);
223
+ if (this.idleTimeout > 0) this.idleTimer = setTimeout(() => this.close(), this.idleTimeout);
224
+ }
225
+ clearIdleTimer() {
226
+ if (this.idleTimer) {
227
+ clearTimeout(this.idleTimer);
228
+ this.idleTimer = null;
229
+ }
230
+ }
231
+ async setFolderScope(scope) {
232
+ if (this.folderScope === scope) return;
233
+ this.folderScope = scope;
234
+ if (this.connected) {
235
+ await this.close();
236
+ await this.connect();
237
+ }
238
+ }
239
+ isConnected = () => this.connected;
240
+ async connect() {
241
+ if (this.connected) return;
242
+ const url = new URL("/mcp", this.config.apiUrl);
243
+ url.searchParams.set("folder", "1");
244
+ const headers = { Authorization: `Bearer ${this.config.apiKey}` };
245
+ if (this.folderScope) headers["X-Folder-Scope"] = this.folderScope;
246
+ this.transport = new _modelcontextprotocol_sdk_client_streamableHttp_js.StreamableHTTPClientTransport(url, { requestInit: { headers } });
247
+ await this.client.connect(this.transport);
248
+ this.connected = true;
249
+ }
250
+ async callTool(name$1, args) {
251
+ if (!this.connected) await this.connect();
252
+ this.resetIdleTimer();
253
+ const r = await this.client.callTool({
254
+ name: name$1,
255
+ arguments: args
256
+ });
257
+ const textContent = r.content.find((c) => c.type === "text");
258
+ const text = textContent?.type === "text" ? textContent.text : void 0;
259
+ if (!text) throw new PageIndexError("Empty response from server", "INTERNAL_ERROR");
260
+ let data;
261
+ try {
262
+ data = JSON.parse(text);
263
+ } catch {
264
+ throw new PageIndexError(text, "INTERNAL_ERROR");
265
+ }
266
+ if (r.isError) {
267
+ const { error, errorCode, ...details } = data;
268
+ throw new PageIndexError(error, errorCode, details);
269
+ }
270
+ return data;
271
+ }
272
+ async close() {
273
+ this.clearIdleTimer();
274
+ if (this.connected) {
275
+ await this.client.close().catch(() => {});
276
+ this.transport = null;
277
+ this.connected = false;
278
+ }
279
+ }
280
+ };
281
+
282
+ //#endregion
283
+ //#region src/client.ts
284
+ const DEFAULT_API_URL = "https://api.pageindex.ai";
285
+ var PageIndexClient = class {
286
+ transport;
287
+ _api;
288
+ _tools = null;
289
+ constructor(config) {
290
+ const apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\/$/, "");
291
+ this.transport = new McpTransport({
292
+ apiUrl,
293
+ apiKey: config.apiKey,
294
+ folderScope: config.folderScope,
295
+ idleTimeout: config.idleTimeout
296
+ });
297
+ this._api = new PageIndexApi({
298
+ apiUrl,
299
+ apiKey: config.apiKey,
300
+ folderScope: config.folderScope
301
+ });
302
+ }
303
+ get api() {
304
+ return this._api;
305
+ }
306
+ get tools() {
307
+ if (!this._tools) this._tools = new PageIndexTools(this.transport);
308
+ return this._tools;
309
+ }
310
+ setFolderScope(scope) {
311
+ return this.transport.setFolderScope(scope);
312
+ }
313
+ connect = () => this.transport.connect();
314
+ isConnected = () => this.transport.isConnected();
315
+ close = () => this.transport.close();
316
+ async [Symbol.asyncDispose]() {
317
+ await this.close();
318
+ }
319
+ };
320
+
321
+ //#endregion
322
+ exports.PageIndexApi = PageIndexApi;
323
+ exports.PageIndexClient = PageIndexClient;
324
+ exports.PageIndexError = PageIndexError;
325
+ exports.PageIndexTools = PageIndexTools;
326
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["Client","pkg.name","pkg.version","StreamableHTTPClientTransport"],"sources":["../src/errors.ts","../src/api/client.ts","../src/tools/create-folder.ts","../src/tools/find-relevant-documents.ts","../src/tools/get-document-structure.ts","../src/tools/get-document.ts","../src/tools/get-page-content.ts","../src/tools/list-folders.ts","../src/tools/recent-documents.ts","../src/tools/remove-document.ts","../src/tools/index.ts","../package.json","../src/transport.ts","../src/client.ts"],"sourcesContent":["export type PageIndexErrorCode =\n | \"USAGE_LIMIT_REACHED\"\n | \"INVALID_INPUT\"\n | \"NOT_FOUND\"\n | \"UNAUTHORIZED\"\n | \"RATE_LIMITED\"\n | \"SERVICE_UNAVAILABLE\"\n | \"INTERNAL_ERROR\";\n\nexport class PageIndexError extends Error {\n constructor(\n message: string,\n public readonly code?: PageIndexErrorCode,\n public readonly details?: Record<string, unknown>,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"PageIndexError\";\n }\n}\n","import { PageIndexError } from \"../errors.js\";\nimport type {\n ChatCompletionsParams,\n ChatCompletionsResponse,\n DeleteDocumentResponse,\n GetDocumentMetadataResponse,\n GetOcrOptions,\n GetOcrResponse,\n GetTreeOptions,\n GetTreeResponse,\n ListDocumentsOptions,\n ListDocumentsResponse,\n SubmitDocumentOptions,\n SubmitDocumentResponse,\n} from \"./types.js\";\n\nexport interface PageIndexApiConfig {\n apiUrl: string;\n apiKey: string;\n folderScope?: string;\n}\n\nexport class PageIndexApi {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly folderScope?: string;\n\n constructor(config: PageIndexApiConfig) {\n this.baseUrl = config.apiUrl.replace(/\\/$/, \"\");\n this.apiKey = config.apiKey;\n this.folderScope = config.folderScope;\n }\n\n async submitDocument(\n file: Blob | Buffer | ArrayBuffer,\n fileName: string,\n options?: SubmitDocumentOptions,\n ): Promise<SubmitDocumentResponse> {\n const formData = new FormData();\n const blob =\n file instanceof Blob\n ? file\n : new Blob([file], { type: \"application/octet-stream\" });\n formData.append(\"file\", blob, fileName);\n if (options?.mode) {\n formData.append(\"mode\", options.mode);\n }\n const folderId = options?.folderId ?? this.folderScope;\n if (folderId) {\n formData.append(\"folder_id\", folderId);\n }\n return this.requestMultipart<SubmitDocumentResponse>(\"/doc/\", formData);\n }\n\n async getDocument(docId: string): Promise<GetDocumentMetadataResponse> {\n return this.request<GetDocumentMetadataResponse>(\n `/doc/${encodeURIComponent(docId)}/metadata`,\n );\n }\n\n async getTree(\n docId: string,\n options?: GetTreeOptions,\n ): Promise<GetTreeResponse> {\n const params = new URLSearchParams({ type: \"tree\" });\n if (options?.summary !== undefined) {\n params.set(\"summary\", String(options.summary));\n }\n return this.request<GetTreeResponse>(\n `/doc/${encodeURIComponent(docId)}/?${params}`,\n );\n }\n\n async getOcr(\n docId: string,\n options?: GetOcrOptions,\n ): Promise<GetOcrResponse> {\n const params = new URLSearchParams({ type: \"ocr\" });\n if (options?.format) {\n params.set(\"format\", options.format);\n }\n return this.request<GetOcrResponse>(\n `/doc/${encodeURIComponent(docId)}/?${params}`,\n );\n }\n\n async listDocuments(\n options?: ListDocumentsOptions,\n ): Promise<ListDocumentsResponse> {\n const params = new URLSearchParams();\n if (options?.limit !== undefined) {\n params.set(\"limit\", String(options.limit));\n }\n if (options?.offset !== undefined) {\n params.set(\"offset\", String(options.offset));\n }\n const folderId = options?.folderId ?? this.folderScope;\n if (folderId) {\n params.set(\"folder_id\", folderId);\n }\n const qs = params.toString();\n return this.request<ListDocumentsResponse>(`/docs${qs ? `?${qs}` : \"\"}`);\n }\n\n async deleteDocument(docId: string): Promise<DeleteDocumentResponse> {\n return this.request<DeleteDocumentResponse>(\n `/doc/${encodeURIComponent(docId)}/`,\n { method: \"DELETE\" },\n );\n }\n\n async chatCompletions(\n params: ChatCompletionsParams,\n ): Promise<ChatCompletionsResponse> {\n return this.request<ChatCompletionsResponse>(\"/chat/completions\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(params),\n });\n }\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const response = await fetch(url, {\n ...init,\n headers: {\n api_key: this.apiKey,\n ...init?.headers,\n },\n });\n return this.handleResponse<T>(response);\n }\n\n private async requestMultipart<T>(\n path: string,\n formData: FormData,\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: { api_key: this.apiKey },\n body: formData,\n });\n return this.handleResponse<T>(response);\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n let message = `API request failed with status ${response.status}`;\n let errorCode = this.mapStatusToErrorCode(response.status);\n let details: Record<string, unknown> | undefined;\n\n try {\n const json = JSON.parse(text) as Record<string, unknown>;\n if (json.error && typeof json.error === \"string\") {\n message = json.error;\n }\n if (json.errorCode && typeof json.errorCode === \"string\") {\n errorCode = json.errorCode as typeof errorCode;\n }\n details = json;\n } catch {\n if (text) message = text;\n }\n\n throw new PageIndexError(message, errorCode, details, response.status);\n }\n\n return response.json() as Promise<T>;\n }\n\n private mapStatusToErrorCode(status: number) {\n switch (status) {\n case 401:\n return \"UNAUTHORIZED\" as const;\n case 404:\n return \"NOT_FOUND\" as const;\n case 429:\n return \"RATE_LIMITED\" as const;\n case 503:\n return \"SERVICE_UNAVAILABLE\" as const;\n default:\n return \"INTERNAL_ERROR\" as const;\n }\n }\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface CreateFolderParams {\n name: string;\n description?: string;\n parentFolderId?: string;\n}\n\nexport interface FolderItem {\n id: string;\n name: string;\n description: string | null;\n parent_folder_id: string | null;\n created_at: string;\n file_count: number;\n children_count: number;\n}\n\nexport interface CreateFolderResult {\n folder: FolderItem;\n next_steps: NextSteps;\n}\n\nexport async function createFolder(\n transport: McpTransport,\n params: CreateFolderParams,\n): Promise<CreateFolderResult> {\n return transport.callTool<CreateFolderResult>(\"create_folder\", {\n name: params.name,\n description: params.description,\n parent_folder_id: params.parentFolderId,\n });\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface FindRelevantDocumentsParams {\n nameOrDescriptionFilter?: string;\n cursor?: string;\n limit?: number;\n}\n\nexport interface SearchDocumentItem {\n id: string;\n name: string;\n description: string;\n status: string;\n pageNum: number;\n createdAt: string;\n folderId: string | null;\n}\n\nexport interface FindRelevantDocumentsResult {\n docs: SearchDocumentItem[];\n cursor?: string;\n has_more: boolean;\n next_steps: NextSteps;\n}\n\nexport async function findRelevantDocuments(\n transport: McpTransport,\n params?: FindRelevantDocumentsParams,\n): Promise<FindRelevantDocumentsResult> {\n return transport.callTool<FindRelevantDocumentsResult>(\n \"find_relevant_documents\",\n {\n name_or_description_filter: params?.nameOrDescriptionFilter,\n cursor: params?.cursor,\n limit: params?.limit,\n },\n );\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface GetDocumentStructureParams {\n docName: string;\n part?: number;\n waitForCompletion?: boolean;\n}\n\nexport interface GetDocumentStructureResult {\n doc_name: string;\n structure: unknown;\n total_parts?: number;\n next_steps: NextSteps;\n}\n\nexport async function getDocumentStructure(\n transport: McpTransport,\n params: GetDocumentStructureParams,\n): Promise<GetDocumentStructureResult> {\n return transport.callTool<GetDocumentStructureResult>(\n \"get_document_structure\",\n {\n doc_name: params.docName,\n part: params.part,\n wait_for_completion: params.waitForCompletion,\n },\n );\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface GetDocumentParams {\n docName: string;\n waitForCompletion?: boolean;\n}\n\nexport interface GetDocumentResult {\n id: string;\n name: string;\n description: string;\n status: string;\n createdAt: string;\n pageNum?: number;\n wait_info?: {\n waited: boolean;\n elapsed_seconds?: number;\n final_status?: string;\n };\n next_steps: NextSteps;\n}\n\nexport async function getDocument(\n transport: McpTransport,\n params: GetDocumentParams,\n): Promise<GetDocumentResult> {\n return transport.callTool<GetDocumentResult>(\"get_document\", {\n doc_name: params.docName,\n wait_for_completion: params.waitForCompletion,\n });\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface GetPageContentParams {\n docName: string;\n pages: string;\n waitForCompletion?: boolean;\n}\n\nexport interface PageContentItem {\n page: number;\n text: string;\n block_id?: string;\n image_count?: number;\n image_annotations?: string[];\n}\n\nexport interface GetPageContentResult {\n doc_name: string;\n total_pages: number;\n requested_pages: string;\n returned_pages: string;\n content: PageContentItem[];\n next_steps: NextSteps;\n}\n\nexport async function getPageContent(\n transport: McpTransport,\n params: GetPageContentParams,\n): Promise<GetPageContentResult> {\n return transport.callTool<GetPageContentResult>(\"get_page_content\", {\n doc_name: params.docName,\n pages: params.pages,\n wait_for_completion: params.waitForCompletion,\n });\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { FolderItem } from \"./create-folder.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface ListFoldersParams {\n /**\n * Use \"root\" for root-level folders only, a folder ID for subfolders, or omit for all folders\n */\n parentFolderId?: string;\n}\n\nexport interface ListFoldersResult {\n folders: FolderItem[];\n next_steps: NextSteps;\n}\n\nexport async function listFolders(\n transport: McpTransport,\n params?: ListFoldersParams,\n): Promise<ListFoldersResult> {\n return transport.callTool<ListFoldersResult>(\"list_folders\", {\n parent_folder_id: params?.parentFolderId,\n });\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface RecentDocumentItem {\n id: string;\n name: string;\n description: string;\n status: string;\n createdAt: string;\n pageNum?: number;\n}\n\nexport interface RecentDocumentsResult {\n docs: RecentDocumentItem[];\n total_shown: number;\n processing_count: number;\n ready_count: number;\n failed_count: number;\n next_steps: NextSteps;\n}\n\nexport async function recentDocuments(\n transport: McpTransport,\n): Promise<RecentDocumentsResult> {\n return transport.callTool<RecentDocumentsResult>(\"recent_documents\", {});\n}\n","import type { McpTransport } from \"../transport.js\";\nimport type { NextSteps } from \"./types.js\";\n\nexport interface RemoveDocumentParams {\n docNames: string[];\n}\n\nexport interface RemoveDocumentResult {\n results: {\n successful: number;\n failed: number;\n details: Array<{\n doc_name: string;\n success: boolean;\n error?: string;\n }>;\n };\n next_steps: NextSteps;\n}\n\nexport async function removeDocument(\n transport: McpTransport,\n params: RemoveDocumentParams,\n): Promise<RemoveDocumentResult> {\n return transport.callTool<RemoveDocumentResult>(\"remove_document\", {\n doc_names: params.docNames,\n });\n}\n","import type { McpTransport } from \"../transport.js\";\nimport {\n type CreateFolderParams,\n type CreateFolderResult,\n createFolder,\n} from \"./create-folder.js\";\nimport {\n type FindRelevantDocumentsParams,\n type FindRelevantDocumentsResult,\n findRelevantDocuments,\n} from \"./find-relevant-documents.js\";\nimport {\n type GetDocumentStructureParams,\n type GetDocumentStructureResult,\n getDocumentStructure,\n} from \"./get-document-structure.js\";\nimport {\n type GetDocumentParams,\n type GetDocumentResult,\n getDocument,\n} from \"./get-document.js\";\nimport {\n type GetPageContentParams,\n type GetPageContentResult,\n getPageContent,\n} from \"./get-page-content.js\";\nimport {\n type ListFoldersParams,\n type ListFoldersResult,\n listFolders,\n} from \"./list-folders.js\";\nimport {\n type RecentDocumentsResult,\n recentDocuments,\n} from \"./recent-documents.js\";\nimport {\n type RemoveDocumentParams,\n type RemoveDocumentResult,\n removeDocument,\n} from \"./remove-document.js\";\n\nexport type { NextSteps } from \"./types.js\";\nexport type {\n CreateFolderParams,\n CreateFolderResult,\n FolderItem,\n} from \"./create-folder.js\";\nexport type { ListFoldersParams, ListFoldersResult } from \"./list-folders.js\";\nexport type {\n RecentDocumentItem,\n RecentDocumentsResult,\n} from \"./recent-documents.js\";\nexport type {\n FindRelevantDocumentsParams,\n FindRelevantDocumentsResult,\n SearchDocumentItem,\n} from \"./find-relevant-documents.js\";\nexport type { GetDocumentParams, GetDocumentResult } from \"./get-document.js\";\nexport type {\n GetDocumentStructureParams,\n GetDocumentStructureResult,\n} from \"./get-document-structure.js\";\nexport type {\n GetPageContentParams,\n GetPageContentResult,\n PageContentItem,\n} from \"./get-page-content.js\";\nexport type {\n RemoveDocumentParams,\n RemoveDocumentResult,\n} from \"./remove-document.js\";\n\nexport class PageIndexTools {\n constructor(private transport: McpTransport) {}\n\n recentDocuments = (): Promise<RecentDocumentsResult> =>\n recentDocuments(this.transport);\n\n findRelevantDocuments = (\n params?: FindRelevantDocumentsParams,\n ): Promise<FindRelevantDocumentsResult> =>\n findRelevantDocuments(this.transport, params);\n\n createFolder = (params: CreateFolderParams): Promise<CreateFolderResult> =>\n createFolder(this.transport, params);\n\n listFolders = (params?: ListFoldersParams): Promise<ListFoldersResult> =>\n listFolders(this.transport, params);\n\n getDocument = (params: GetDocumentParams): Promise<GetDocumentResult> =>\n getDocument(this.transport, params);\n\n getDocumentStructure = (\n params: GetDocumentStructureParams,\n ): Promise<GetDocumentStructureResult> =>\n getDocumentStructure(this.transport, params);\n\n getPageContent = (\n params: GetPageContentParams,\n ): Promise<GetPageContentResult> => getPageContent(this.transport, params);\n\n removeDocument = (\n params: RemoveDocumentParams,\n ): Promise<RemoveDocumentResult> => removeDocument(this.transport, params);\n}\n","","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport pkg from \"../package.json\" assert { type: \"json\" };\nimport { PageIndexError, type PageIndexErrorCode } from \"./errors.js\";\n\nexport class McpTransport {\n private client = new Client(\n { name: pkg.name, version: pkg.version },\n { capabilities: {} },\n );\n private transport: StreamableHTTPClientTransport | null = null;\n private connected = false;\n private folderScope: string | undefined;\n private idleTimeout: number;\n private idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(\n private config: {\n apiUrl: string;\n apiKey: string;\n folderScope?: string;\n idleTimeout?: number;\n },\n ) {\n this.folderScope = config.folderScope;\n this.idleTimeout = config.idleTimeout ?? 60_000;\n }\n\n private resetIdleTimer(): void {\n if (this.idleTimer) clearTimeout(this.idleTimer);\n if (this.idleTimeout > 0) {\n this.idleTimer = setTimeout(() => this.close(), this.idleTimeout);\n }\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer);\n this.idleTimer = null;\n }\n }\n\n async setFolderScope(scope: string | undefined): Promise<void> {\n if (this.folderScope === scope) return;\n this.folderScope = scope;\n if (this.connected) {\n await this.close();\n await this.connect();\n }\n }\n\n isConnected = () => this.connected;\n\n async connect(): Promise<void> {\n if (this.connected) return;\n const url = new URL(\"/mcp\", this.config.apiUrl);\n url.searchParams.set(\"folder\", \"1\");\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.config.apiKey}`,\n };\n if (this.folderScope) {\n headers[\"X-Folder-Scope\"] = this.folderScope;\n }\n this.transport = new StreamableHTTPClientTransport(url, {\n requestInit: { headers },\n });\n await this.client.connect(this.transport);\n this.connected = true;\n }\n\n async callTool<T = unknown>(\n name: string,\n args: Record<string, unknown>,\n ): Promise<T> {\n if (!this.connected) await this.connect();\n this.resetIdleTimer();\n\n const r = (await this.client.callTool({\n name,\n arguments: args,\n })) as CallToolResult;\n\n const textContent = r.content.find((c) => c.type === \"text\");\n const text = textContent?.type === \"text\" ? textContent.text : undefined;\n\n if (!text) {\n throw new PageIndexError(\"Empty response from server\", \"INTERNAL_ERROR\");\n }\n\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n // Response is not JSON - treat it as a plain text error\n throw new PageIndexError(text, \"INTERNAL_ERROR\");\n }\n\n if (r.isError) {\n const { error, errorCode, ...details } = data as {\n error: string;\n errorCode?: PageIndexErrorCode;\n [key: string]: unknown;\n };\n throw new PageIndexError(error, errorCode, details);\n }\n\n return data as T;\n }\n\n async close(): Promise<void> {\n this.clearIdleTimer();\n if (this.connected) {\n await this.client.close().catch(() => {});\n this.transport = null;\n this.connected = false;\n }\n }\n}\n","import { PageIndexApi } from \"./api/client.js\";\nimport { PageIndexTools } from \"./tools/index.js\";\nimport { McpTransport } from \"./transport.js\";\n\nexport interface PageIndexClientConfig {\n apiKey: string;\n apiUrl?: string;\n folderScope?: string;\n /** MCP connection idle timeout in ms. Set 0 to disable. Default: 60000 (60s) */\n idleTimeout?: number;\n}\n\nconst DEFAULT_API_URL = \"https://api.pageindex.ai\";\n\nexport class PageIndexClient {\n private transport: McpTransport;\n private _api: PageIndexApi;\n private _tools: PageIndexTools | null = null;\n\n constructor(config: PageIndexClientConfig) {\n const apiUrl = (config.apiUrl || DEFAULT_API_URL).replace(/\\/$/, \"\");\n\n this.transport = new McpTransport({\n apiUrl,\n apiKey: config.apiKey,\n folderScope: config.folderScope,\n idleTimeout: config.idleTimeout,\n });\n\n this._api = new PageIndexApi({\n apiUrl,\n apiKey: config.apiKey,\n folderScope: config.folderScope,\n });\n }\n\n get api(): PageIndexApi {\n return this._api;\n }\n\n get tools(): PageIndexTools {\n if (!this._tools) {\n this._tools = new PageIndexTools(this.transport);\n }\n return this._tools;\n }\n\n setFolderScope(scope: string | undefined): Promise<void> {\n return this.transport.setFolderScope(scope);\n }\n\n connect = () => this.transport.connect();\n isConnected = () => this.transport.isConnected();\n close = () => this.transport.close();\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n"],"mappings":"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"}