@papermark/mcp-server 0.2.0 → 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/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-S3ALJ4YG.js";
47
+ } from "./chunk-QTHIJVM3.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
- return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
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
- { type: "text", text: `${label} failed: ${err instanceof Error ? err.message : String(err)}` }
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.map(summarizeDocument),
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 { documents: list.data.map(summarizeDocument), next_cursor: list.next_cursor };
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("Public HTTPS URL the server should fetch (alternative to file_path)"),
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("Provide either file_path (local) or source_url (remote).");
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: summarizeDocument(doc2) };
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
- contentLength: stats.size
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(`Storage PUT failed: HTTP ${put.status} ${put.statusText}`);
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: summarizeDocument(doc) };
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: summarizeLink(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 { links: list.data.map(summarizeLink), next_cursor: list.next_cursor };
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 { views: list.data.map(summarizeView), next_cursor: list.next_cursor };
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: summarizeDocument(doc) };
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: summarizeLink(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: summarizeLink(link) };
962
+ return { link };
893
963
  }, "update_link")
894
964
  );
895
965
  server.registerTool(