@papermark/mcp-server 0.2.0 → 0.4.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/dist/{chunk-S3ALJ4YG.js → chunk-IMW5GZSO.js} +413 -5
- package/dist/chunk-IMW5GZSO.js.map +1 -0
- package/dist/index.js +123 -53
- package/dist/index.js.map +1 -1
- package/dist/tools-contract.d.ts +1151 -5
- package/dist/tools-contract.js +65 -3
- package/package.json +1 -1
- package/dist/chunk-S3ALJ4YG.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
SHARED_TOOL_OUTPUT_SCHEMAS,
|
|
3
4
|
addDocumentVersionContract,
|
|
4
5
|
attachDataroomDocumentContract,
|
|
5
6
|
createDataroomContract,
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
deleteDocumentContract,
|
|
12
13
|
deleteFolderContract,
|
|
13
14
|
deleteLinkContract,
|
|
15
|
+
documentOutputSchema,
|
|
14
16
|
getDataroomAnalyticsContract,
|
|
15
17
|
getDataroomContract,
|
|
16
18
|
getDataroomFolderContract,
|
|
@@ -42,7 +44,7 @@ import {
|
|
|
42
44
|
updateDocumentContract,
|
|
43
45
|
updateFolderContract,
|
|
44
46
|
updateLinkContract
|
|
45
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-IMW5GZSO.js";
|
|
46
48
|
|
|
47
49
|
// src/index.ts
|
|
48
50
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -298,10 +300,74 @@ var api = {
|
|
|
298
300
|
};
|
|
299
301
|
|
|
300
302
|
// src/tools.ts
|
|
303
|
+
var readTool = (openWorldHint = false) => ({ readOnlyHint: true, destructiveHint: false, openWorldHint });
|
|
304
|
+
var writeTool = (openWorldHint = false) => ({ readOnlyHint: false, destructiveHint: false, openWorldHint });
|
|
305
|
+
var destructiveTool = (openWorldHint = false) => ({ readOnlyHint: false, destructiveHint: true, openWorldHint });
|
|
306
|
+
var TOOL_ANNOTATIONS = {
|
|
307
|
+
list_documents: readTool(),
|
|
308
|
+
get_document: readTool(),
|
|
309
|
+
search_documents: readTool(),
|
|
310
|
+
upload_document: writeTool(true),
|
|
311
|
+
create_link: writeTool(),
|
|
312
|
+
list_links: readTool(),
|
|
313
|
+
list_link_views: readTool(),
|
|
314
|
+
list_datarooms: readTool(),
|
|
315
|
+
search_datarooms: readTool(),
|
|
316
|
+
get_dataroom: readTool(),
|
|
317
|
+
create_dataroom: writeTool(),
|
|
318
|
+
list_dataroom_documents: readTool(),
|
|
319
|
+
list_visitors: readTool(),
|
|
320
|
+
list_visitor_views: readTool(),
|
|
321
|
+
get_document_analytics: readTool(),
|
|
322
|
+
get_link_analytics: readTool(),
|
|
323
|
+
get_dataroom_analytics: readTool(),
|
|
324
|
+
get_view_analytics: readTool(),
|
|
325
|
+
update_document: destructiveTool(),
|
|
326
|
+
delete_document: destructiveTool(),
|
|
327
|
+
list_document_versions: readTool(),
|
|
328
|
+
get_document_version: readTool(),
|
|
329
|
+
add_document_version: destructiveTool(true),
|
|
330
|
+
promote_document_version: destructiveTool(),
|
|
331
|
+
list_folders: readTool(),
|
|
332
|
+
get_folder: readTool(),
|
|
333
|
+
create_folder: writeTool(),
|
|
334
|
+
update_folder: destructiveTool(),
|
|
335
|
+
delete_folder: destructiveTool(),
|
|
336
|
+
move_folder: destructiveTool(),
|
|
337
|
+
get_link: readTool(),
|
|
338
|
+
update_link: destructiveTool(),
|
|
339
|
+
delete_link: destructiveTool(),
|
|
340
|
+
update_dataroom: destructiveTool(),
|
|
341
|
+
delete_dataroom: destructiveTool(),
|
|
342
|
+
attach_dataroom_document: writeTool(),
|
|
343
|
+
list_dataroom_folders: readTool(),
|
|
344
|
+
get_dataroom_folder: readTool(),
|
|
345
|
+
create_dataroom_folder: writeTool(),
|
|
346
|
+
update_dataroom_folder: destructiveTool(),
|
|
347
|
+
delete_dataroom_folder: destructiveTool(),
|
|
348
|
+
move_dataroom_folder: destructiveTool(),
|
|
349
|
+
get_visitor: readTool()
|
|
350
|
+
};
|
|
351
|
+
var TOOL_OUTPUT_SCHEMAS = {
|
|
352
|
+
...SHARED_TOOL_OUTPUT_SCHEMAS,
|
|
353
|
+
upload_document: documentOutputSchema
|
|
354
|
+
};
|
|
355
|
+
function toStructuredContent(result) {
|
|
356
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
return { result };
|
|
360
|
+
}
|
|
301
361
|
async function run(fn, label) {
|
|
302
362
|
try {
|
|
303
363
|
const result = await fn();
|
|
304
|
-
|
|
364
|
+
const structuredContent = toStructuredContent(result);
|
|
365
|
+
return {
|
|
366
|
+
structuredContent,
|
|
367
|
+
content: [
|
|
368
|
+
{ type: "text", text: JSON.stringify(structuredContent, null, 2) }
|
|
369
|
+
]
|
|
370
|
+
};
|
|
305
371
|
} catch (err) {
|
|
306
372
|
if (err instanceof ApiError) {
|
|
307
373
|
const detail = err.details !== void 0 && err.details !== null ? `
|
|
@@ -330,7 +396,10 @@ Docs: ${err.docUrl}` : "";
|
|
|
330
396
|
return {
|
|
331
397
|
isError: true,
|
|
332
398
|
content: [
|
|
333
|
-
{
|
|
399
|
+
{
|
|
400
|
+
type: "text",
|
|
401
|
+
text: `${label} failed: ${err instanceof Error ? err.message : String(err)}`
|
|
402
|
+
}
|
|
334
403
|
]
|
|
335
404
|
};
|
|
336
405
|
}
|
|
@@ -348,41 +417,27 @@ function filenameFromUrl(rawUrl) {
|
|
|
348
417
|
return "document";
|
|
349
418
|
}
|
|
350
419
|
}
|
|
351
|
-
function summarizeDocument(d) {
|
|
352
|
-
return {
|
|
353
|
-
id: d.id,
|
|
354
|
-
object: d.object,
|
|
355
|
-
name: d.name,
|
|
356
|
-
content_type: d.content_type,
|
|
357
|
-
num_pages: d.num_pages,
|
|
358
|
-
created: d.created
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
function summarizeLink(l) {
|
|
362
|
-
return {
|
|
363
|
-
id: l.id,
|
|
364
|
-
object: l.object,
|
|
365
|
-
url: l.url,
|
|
366
|
-
name: l.name,
|
|
367
|
-
target_type: l.target_type,
|
|
368
|
-
document_id: l.document_id,
|
|
369
|
-
dataroom_id: l.dataroom_id,
|
|
370
|
-
expires_at: l.expires_at,
|
|
371
|
-
is_password_protected: l.is_password_protected,
|
|
372
|
-
email_protected: l.email_protected,
|
|
373
|
-
allow_download: l.allow_download
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
function summarizeView(v) {
|
|
377
|
-
return {
|
|
378
|
-
id: v.id,
|
|
379
|
-
link_id: v.link_id,
|
|
380
|
-
viewer_email: v.viewer_email,
|
|
381
|
-
viewed_at: v.viewed_at,
|
|
382
|
-
downloaded_at: v.downloaded_at
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
420
|
function registerTools(server) {
|
|
421
|
+
const baseRegisterTool = server.registerTool.bind(server);
|
|
422
|
+
server.registerTool = ((name, config, cb) => {
|
|
423
|
+
const annotations = TOOL_ANNOTATIONS[name];
|
|
424
|
+
if (!annotations) {
|
|
425
|
+
throw new Error(`MCP tool "${name}" has no annotations entry`);
|
|
426
|
+
}
|
|
427
|
+
const outputSchema = TOOL_OUTPUT_SCHEMAS[name];
|
|
428
|
+
if (!outputSchema) {
|
|
429
|
+
throw new Error(`MCP tool "${name}" has no output schema entry`);
|
|
430
|
+
}
|
|
431
|
+
return baseRegisterTool(
|
|
432
|
+
name,
|
|
433
|
+
{
|
|
434
|
+
...config,
|
|
435
|
+
annotations: { ...annotations, ...config.annotations },
|
|
436
|
+
outputSchema: config.outputSchema ?? outputSchema
|
|
437
|
+
},
|
|
438
|
+
cb
|
|
439
|
+
);
|
|
440
|
+
});
|
|
386
441
|
server.registerTool(
|
|
387
442
|
listDocumentsContract.name,
|
|
388
443
|
{
|
|
@@ -397,7 +452,7 @@ function registerTools(server) {
|
|
|
397
452
|
query: args.query
|
|
398
453
|
});
|
|
399
454
|
return {
|
|
400
|
-
documents: list.data
|
|
455
|
+
documents: list.data,
|
|
401
456
|
next_cursor: list.next_cursor
|
|
402
457
|
};
|
|
403
458
|
}, "list_documents")
|
|
@@ -420,7 +475,10 @@ function registerTools(server) {
|
|
|
420
475
|
},
|
|
421
476
|
async (args) => run(async () => {
|
|
422
477
|
const list = await api.searchDocuments(args.query, args.limit);
|
|
423
|
-
return {
|
|
478
|
+
return {
|
|
479
|
+
documents: list.data,
|
|
480
|
+
next_cursor: list.next_cursor
|
|
481
|
+
};
|
|
424
482
|
}, "search_documents")
|
|
425
483
|
);
|
|
426
484
|
server.registerTool(
|
|
@@ -441,7 +499,9 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
441
499
|
),
|
|
442
500
|
source_url: z.string().url().refine((s) => s.startsWith("https://"), {
|
|
443
501
|
message: "source_url must use https:// (http is rejected by the API)"
|
|
444
|
-
}).optional().describe(
|
|
502
|
+
}).optional().describe(
|
|
503
|
+
"Public HTTPS URL the server should fetch (alternative to file_path)"
|
|
504
|
+
),
|
|
445
505
|
name: z.string().optional().describe("Display name; defaults to the filename"),
|
|
446
506
|
content_type: z.string().optional().describe("MIME type; inferred from extension when omitted"),
|
|
447
507
|
folder_id: z.string().optional().describe(
|
|
@@ -452,7 +512,9 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
452
512
|
},
|
|
453
513
|
async (args) => run(async () => {
|
|
454
514
|
if (!args.file_path && !args.source_url) {
|
|
455
|
-
throw new Error(
|
|
515
|
+
throw new Error(
|
|
516
|
+
"Provide either file_path (local) or source_url (remote)."
|
|
517
|
+
);
|
|
456
518
|
}
|
|
457
519
|
if (args.file_path && args.source_url) {
|
|
458
520
|
throw new Error("Provide only one of file_path or source_url.");
|
|
@@ -465,7 +527,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
465
527
|
folder_id: args.folder_id,
|
|
466
528
|
create_link: args.create_link
|
|
467
529
|
});
|
|
468
|
-
return { document:
|
|
530
|
+
return { document: doc2 };
|
|
469
531
|
}
|
|
470
532
|
const filePath = args.file_path;
|
|
471
533
|
const stats = await stat(filePath);
|
|
@@ -473,9 +535,9 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
473
535
|
const contentType = args.content_type ?? guessContentType(fileName);
|
|
474
536
|
const body = await readFile(filePath);
|
|
475
537
|
const presigned = await api.uploadUrl({
|
|
476
|
-
fileName,
|
|
477
|
-
contentType,
|
|
478
|
-
|
|
538
|
+
file_name: fileName,
|
|
539
|
+
content_type: contentType,
|
|
540
|
+
content_length: stats.size
|
|
479
541
|
});
|
|
480
542
|
const putController = new AbortController();
|
|
481
543
|
const putTimer = setTimeout(() => putController.abort(), 5 * 6e4);
|
|
@@ -498,7 +560,9 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
498
560
|
clearTimeout(putTimer);
|
|
499
561
|
}
|
|
500
562
|
if (!put.ok) {
|
|
501
|
-
throw new Error(
|
|
563
|
+
throw new Error(
|
|
564
|
+
`Storage PUT failed: HTTP ${put.status} ${put.statusText}`
|
|
565
|
+
);
|
|
502
566
|
}
|
|
503
567
|
const doc = await api.createDocument({
|
|
504
568
|
name: args.name ?? fileName,
|
|
@@ -506,7 +570,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
506
570
|
folder_id: args.folder_id,
|
|
507
571
|
create_link: args.create_link
|
|
508
572
|
});
|
|
509
|
-
return { document:
|
|
573
|
+
return { document: doc };
|
|
510
574
|
}, "upload_document")
|
|
511
575
|
);
|
|
512
576
|
server.registerTool(
|
|
@@ -528,7 +592,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
528
592
|
);
|
|
529
593
|
}
|
|
530
594
|
const link = await api.createLink(args);
|
|
531
|
-
return { link
|
|
595
|
+
return { link };
|
|
532
596
|
}, "create_link")
|
|
533
597
|
);
|
|
534
598
|
server.registerTool(
|
|
@@ -540,7 +604,10 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
540
604
|
},
|
|
541
605
|
async (args) => run(async () => {
|
|
542
606
|
const list = await api.listLinks(args);
|
|
543
|
-
return {
|
|
607
|
+
return {
|
|
608
|
+
links: list.data,
|
|
609
|
+
next_cursor: list.next_cursor
|
|
610
|
+
};
|
|
544
611
|
}, "list_links")
|
|
545
612
|
);
|
|
546
613
|
server.registerTool(
|
|
@@ -555,7 +622,10 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
555
622
|
limit: args.limit,
|
|
556
623
|
cursor: args.cursor
|
|
557
624
|
});
|
|
558
|
-
return {
|
|
625
|
+
return {
|
|
626
|
+
views: list.data,
|
|
627
|
+
next_cursor: list.next_cursor
|
|
628
|
+
};
|
|
559
629
|
}, "list_link_views")
|
|
560
630
|
);
|
|
561
631
|
server.registerTool(
|
|
@@ -718,7 +788,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
718
788
|
throw new Error("Provide at least one of `name` or `folder_id`.");
|
|
719
789
|
}
|
|
720
790
|
const doc = await api.updateDocument(args.document_id, body);
|
|
721
|
-
return { document:
|
|
791
|
+
return { document: doc };
|
|
722
792
|
}, "update_document")
|
|
723
793
|
);
|
|
724
794
|
server.registerTool(
|
|
@@ -873,7 +943,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
873
943
|
},
|
|
874
944
|
async (args) => run(async () => {
|
|
875
945
|
const link = await api.getLink(args.link_id);
|
|
876
|
-
return { link
|
|
946
|
+
return { link };
|
|
877
947
|
}, "get_link")
|
|
878
948
|
);
|
|
879
949
|
server.registerTool(
|
|
@@ -889,7 +959,7 @@ Don't upload any file the user didn't explicitly point at. Requires scope \`docu
|
|
|
889
959
|
throw new Error("Provide at least one field to update.");
|
|
890
960
|
}
|
|
891
961
|
const link = await api.updateLink(link_id, rest);
|
|
892
|
-
return { link
|
|
962
|
+
return { link };
|
|
893
963
|
}, "update_link")
|
|
894
964
|
);
|
|
895
965
|
server.registerTool(
|