@exactpdf/mcp 0.2.8 → 0.2.10
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 +6 -4
- package/dist/run.js +45 -5
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -51,16 +51,18 @@ For a local checkout of this monorepo:
|
|
|
51
51
|
Safe first run:
|
|
52
52
|
|
|
53
53
|
```text
|
|
54
|
-
1.
|
|
55
|
-
2.
|
|
56
|
-
3.
|
|
57
|
-
4.
|
|
54
|
+
1. exactpdf_first_run_checklist
|
|
55
|
+
2. exactpdf_account
|
|
56
|
+
3. exactpdf_pdf_info(path="/absolute/path/document.pdf")
|
|
57
|
+
4. exactpdf_voice_preview(text="Short sample...", voice_style="professional")
|
|
58
|
+
5. exactpdf_estimate_speech_cost(path="/absolute/path/document.pdf", mode="audiobook")
|
|
58
59
|
```
|
|
59
60
|
|
|
60
61
|
Document outputs are saved to `EXACTPDF_API_OUTPUT_DIR` or your OS temp directory. Paid document tools consume credits only on successful output. Async speech jobs are metered by generated minutes.
|
|
61
62
|
|
|
62
63
|
| Tool | Endpoint | Credits |
|
|
63
64
|
|------|----------|--------:|
|
|
65
|
+
| `exactpdf_first_run_checklist` | local guidance | 0 |
|
|
64
66
|
| `exactpdf_account` | GET /api/v1/account | 0 |
|
|
65
67
|
| `exactpdf_pdf_info` | POST /api/v1/pdf-info | 0 |
|
|
66
68
|
| `exactpdf_merge_pdfs` | POST /api/v1/merge | 1 |
|
package/dist/run.js
CHANGED
|
@@ -24,8 +24,8 @@ function requireKey() {
|
|
|
24
24
|
}
|
|
25
25
|
return k;
|
|
26
26
|
}
|
|
27
|
-
const server = new McpServer({ name: 'exactpdf', version: '0.2.
|
|
28
|
-
instructions: 'ExactPDF turns local PDFs into production outputs for agents: inspect metadata, merge/split/rotate/compress, extract text/structured Markdown, create voice previews, and queue async PDF speech/audiobook/translation/presentation narration jobs. Free tools: account, pdf-info, voice-preview, speech cost estimate. Standard document tools cost 1 credit on success. Async speech jobs are metered by generated minutes. Use absolute local file paths; binary outputs are saved to EXACTPDF_API_OUTPUT_DIR or the OS temp directory. For async jobs, submit first, then poll exactpdf_get_speech_job, then download with exactpdf_download_audio when succeeded.',
|
|
27
|
+
const server = new McpServer({ name: 'exactpdf', version: '0.2.10' }, {
|
|
28
|
+
instructions: 'ExactPDF turns local PDFs into production outputs for agents: inspect metadata, merge/split/rotate/compress, extract text/structured Markdown, create voice previews, and queue async PDF speech/audiobook/translation/presentation narration jobs. Start with exactpdf_first_run_checklist, then exactpdf_account and exactpdf_pdf_info before paid work. Free tools: first-run checklist, account, pdf-info, voice-preview, speech cost estimate. Standard document tools cost 1 credit on success. Async speech jobs are metered by generated minutes. Use absolute local file paths; binary outputs are saved to EXACTPDF_API_OUTPUT_DIR or the OS temp directory. For async jobs, submit first, then poll exactpdf_get_speech_job, then download with exactpdf_download_audio when succeeded.',
|
|
29
29
|
});
|
|
30
30
|
async function saveBinaryFromResponse(res, prefix, fallbackExt) {
|
|
31
31
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
@@ -47,6 +47,44 @@ function extensionFromContentType(contentType, fallback) {
|
|
|
47
47
|
return 'pdf';
|
|
48
48
|
return fallback;
|
|
49
49
|
}
|
|
50
|
+
server.registerTool('exactpdf_first_run_checklist', {
|
|
51
|
+
description: 'Return the safest first-run sequence for ExactPDF MCP clients, including API key setup, free probe tools, credit rules, output directory behavior, and docs links. Free; no API key required.',
|
|
52
|
+
inputSchema: z.object({}),
|
|
53
|
+
}, async () => ({
|
|
54
|
+
content: [
|
|
55
|
+
{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: JSON.stringify({
|
|
58
|
+
ok: true,
|
|
59
|
+
setup: {
|
|
60
|
+
required_env: 'EXACTPDF_API_KEY=sk_live_...',
|
|
61
|
+
create_key_url: `${BASE}/max/account`,
|
|
62
|
+
optional_output_dir: 'EXACTPDF_API_OUTPUT_DIR=/absolute/output/folder',
|
|
63
|
+
docs: `${BASE}/docs/api`,
|
|
64
|
+
openapi: `${BASE}/openapi.json`,
|
|
65
|
+
},
|
|
66
|
+
safe_first_run: [
|
|
67
|
+
'Call exactpdf_account to verify the key and credit balance.',
|
|
68
|
+
'Call exactpdf_pdf_info with a small absolute PDF path before extraction or conversion.',
|
|
69
|
+
'Call exactpdf_voice_preview with a short text sample before long narration.',
|
|
70
|
+
'Call exactpdf_estimate_speech_cost before audiobook, speech, translation, or presentation narration.',
|
|
71
|
+
],
|
|
72
|
+
credit_model: {
|
|
73
|
+
free: ['exactpdf_first_run_checklist', 'exactpdf_account', 'exactpdf_pdf_info', 'exactpdf_voice_preview', 'exactpdf_estimate_speech_cost', 'job polling'],
|
|
74
|
+
standard_document_tools: '1 credit only after successful output',
|
|
75
|
+
speech_audiobook_presentation: '1 credit per generated minute',
|
|
76
|
+
translate_and_speak: '3 credits per generated minute',
|
|
77
|
+
},
|
|
78
|
+
reliability_rules: [
|
|
79
|
+
'Use absolute local file paths; relative paths are client-dependent.',
|
|
80
|
+
'Never paste API keys into prompts, screenshots, commits, or logs.',
|
|
81
|
+
'Async jobs return a job_id first; poll until succeeded, then download.',
|
|
82
|
+
'If a tool returns isError, show the HTTP status and response body to the user.',
|
|
83
|
+
],
|
|
84
|
+
}, null, 2),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
}));
|
|
50
88
|
server.registerTool('exactpdf_account', {
|
|
51
89
|
description: 'Check whether the ExactPDF API key works and return credit balance/key metadata. Free; does not consume credits. Use this before any paid tool.',
|
|
52
90
|
inputSchema: z.object({}),
|
|
@@ -781,7 +819,7 @@ server.registerTool('exactpdf_estimate_speech_cost', {
|
|
|
781
819
|
characters: z.number().int().positive().optional().describe('Known narration character count, if already extracted.'),
|
|
782
820
|
minutes: z.number().positive().optional().describe('Known generated minutes, if already estimated.'),
|
|
783
821
|
mode: z.enum(['speech', 'audiobook', 'presentation', 'translate']).optional().describe('Default: audiobook.'),
|
|
784
|
-
target_language: z.string().optional().describe('
|
|
822
|
+
target_language: z.string().optional().describe('Only set when mode is translate. Leave empty for English speech/audiobook/presentation estimates.'),
|
|
785
823
|
}),
|
|
786
824
|
}, async ({ path, characters, minutes, mode, target_language }) => {
|
|
787
825
|
let estimatedChars = characters ?? 0;
|
|
@@ -792,7 +830,7 @@ server.registerTool('exactpdf_estimate_speech_cost', {
|
|
|
792
830
|
estimatedChars = Math.max(1_000, Math.round(info.size / 8));
|
|
793
831
|
}
|
|
794
832
|
const estimatedMinutes = minutes ?? Math.max(1, Math.ceil(estimatedChars / 900));
|
|
795
|
-
const selectedMode =
|
|
833
|
+
const selectedMode = mode === 'translate' ? 'translate' : (mode ?? 'audiobook');
|
|
796
834
|
const creditsPerMinute = selectedMode === 'translate' ? 3 : 1;
|
|
797
835
|
const credits = Math.max(1, estimatedMinutes * creditsPerMinute);
|
|
798
836
|
return {
|
|
@@ -808,7 +846,9 @@ server.registerTool('exactpdf_estimate_speech_cost', {
|
|
|
808
846
|
generated_minutes: estimatedMinutes,
|
|
809
847
|
credits_per_minute: creditsPerMinute,
|
|
810
848
|
current_credit_cost: credits,
|
|
811
|
-
|
|
849
|
+
target_language_applied: selectedMode === 'translate' ? (target_language ?? null) : null,
|
|
850
|
+
ignored_target_language: selectedMode !== 'translate' && target_language ? target_language : null,
|
|
851
|
+
note: 'ExactPDF charges async speech jobs by estimated generated minutes: 1 credit/minute for standard speech/audiobook/presentation, 3 credits/minute for translate-and-speak. A target language only changes pricing when mode is translate. Path-based estimates are rough until the API extracts PDF text.',
|
|
812
852
|
},
|
|
813
853
|
}, null, 2),
|
|
814
854
|
},
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"name": "com.exactpdf/mcp",
|
|
4
4
|
"title": "ExactPDF",
|
|
5
5
|
"description": "Agent-facing PDF API: merge, split, rotate, compress, images, metadata, text, Markdown, voice previews, async speech/audiobook, multilingual speech, and presentation narration jobs.",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.10",
|
|
7
7
|
"websiteUrl": "https://exactpdf.com/docs/api",
|
|
8
8
|
"packages": [
|
|
9
9
|
{
|
|
10
10
|
"registryType": "npm",
|
|
11
11
|
"identifier": "@exactpdf/mcp",
|
|
12
|
-
"version": "0.2.
|
|
12
|
+
"version": "0.2.10",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|
|
15
15
|
}
|