Skip to content

Commit 0e18fd2

Browse files
Add local MCP tool metadata and docs
1 parent 33f3200 commit 0e18fd2

2 files changed

Lines changed: 146 additions & 38 deletions

File tree

README.md

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ Once configured, you (or your AI agent) can process documents through natural la
3333

3434
## Quick Start
3535

36-
### 1. Get a Nutrient API Key
36+
### 1. Create a Nutrient Account
3737

3838
Sign up for free at [nutrient.io/api](https://dashboard.nutrient.io/sign_up/).
3939

40+
For local desktop use, the recommended path is to omit `NUTRIENT_DWS_API_KEY` and complete the browser sign-in flow on the first DWS-backed tool call. For CI, headless environments, or scripted setups, create an API key in the dashboard and set `NUTRIENT_DWS_API_KEY`.
41+
4042
### 2. Configure Your AI Client
4143

4244
Choose your platform and add the configuration:
@@ -56,12 +58,13 @@ Open Settings → Developer → Edit Config, then add:
5658
"command": "npx",
5759
"args": ["-y", "@nutrient-sdk/dws-mcp-server"],
5860
"env": {
59-
"NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE",
6061
"SANDBOX_PATH": "/your/sandbox/directory",
6162
// "C:\\your\\sandbox\\directory" for Windows
62-
},
63-
},
64-
},
63+
// Optional for CI or headless usage:
64+
// "NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE"
65+
}
66+
}
67+
}
6568
}
6669
```
6770

@@ -79,12 +82,13 @@ Create `.cursor/mcp.json` in your project root:
7982
"command": "npx",
8083
"args": ["-y", "@nutrient-sdk/dws-mcp-server"],
8184
"env": {
82-
"NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE",
8385
"SANDBOX_PATH": "/your/project/documents",
8486
// "C:\\your\\project\\documents" for Windows
85-
},
86-
},
87-
},
87+
// Optional for CI or headless usage:
88+
// "NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE"
89+
}
90+
}
91+
}
8892
}
8993
```
9094

@@ -102,12 +106,13 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
102106
"command": "npx",
103107
"args": ["-y", "@nutrient-sdk/dws-mcp-server"],
104108
"env": {
105-
"NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE",
106109
"SANDBOX_PATH": "/your/sandbox/directory",
107110
// "C:\\your\\sandbox\\directory" for Windows
108-
},
109-
},
110-
},
111+
// Optional for CI or headless usage:
112+
// "NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE"
113+
}
114+
}
115+
}
111116
}
112117
```
113118

@@ -118,16 +123,17 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
118123

119124
Add to `.vscode/settings.json` in your project:
120125

121-
```json
126+
```jsonc
122127
{
123128
"mcp": {
124129
"servers": {
125130
"nutrient-dws": {
126131
"command": "npx",
127132
"args": ["-y", "@nutrient-sdk/dws-mcp-server"],
128133
"env": {
129-
"NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE",
130-
"SANDBOX_PATH": "${workspaceFolder}"
134+
"SANDBOX_PATH": "${workspaceFolder}",
135+
// Optional for CI or headless usage:
136+
// "NUTRIENT_DWS_API_KEY": "YOUR_API_KEY_HERE"
131137
}
132138
}
133139
}
@@ -143,6 +149,9 @@ Add to `.vscode/settings.json` in your project:
143149
Any MCP-compatible client can connect using stdio transport:
144150

145151
```bash
152+
SANDBOX_PATH=/your/path npx @nutrient-sdk/dws-mcp-server
153+
154+
# Optional for CI or headless usage:
146155
NUTRIENT_DWS_API_KEY=your_key SANDBOX_PATH=/your/path npx @nutrient-sdk/dws-mcp-server
147156
```
148157

@@ -154,16 +163,18 @@ Restart the application to pick up the new MCP server configuration.
154163

155164
### 4. Start Processing Documents
156165

157-
Drop documents into your sandbox directory and start giving instructions!
166+
Place documents in your sandbox directory and use explicit file names or paths in prompts. Explicit paths are safer and more reliable than vague file-browsing requests.
158167

159168
## Available Tools
160169

161-
| Tool | Description |
162-
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
163-
| **document_processor** | All-in-one document processing: merge PDFs, convert formats, apply OCR, watermark, rotate, redact, flatten annotations, extract text/tables/key-value pairs, and more |
164-
| **document_signer** | Digitally sign PDFs with PAdES-compliant CMS or CAdES signatures, with customizable visible/invisible signature appearances |
165-
| **sandbox_file_tree** | Browse files in the sandbox directory (when sandbox mode is enabled) |
166-
| **directory_tree** | Browse directory contents (when sandbox mode is disabled) |
170+
| Tool | Description |
171+
| ---- | ----------- |
172+
| `document_processor` | Nutrient DWS document processing tool for conversions, OCR, extraction, watermarking, rotation, annotation flattening, and redaction workflows |
173+
| `document_signer` | Nutrient DWS signing tool for CMS / PKCS#7 and CAdES signatures with visible or invisible appearance options |
174+
| `ai_redactor` | Nutrient DWS AI redaction tool for detecting and permanently removing sensitive content such as names, addresses, SSNs, emails, and custom criteria |
175+
| `check_credits` | Read-only account lookup for current DWS credits and usage. No document content is uploaded |
176+
| `sandbox_file_tree` | Read-only view of files inside the configured sandbox directory |
177+
| `directory_tree` | Read-only view of local files when sandbox mode is disabled. Sandbox mode is strongly recommended |
167178

168179
### Document Processor Capabilities
169180

@@ -179,6 +190,32 @@ Drop documents into your sandbox directory and start giving instructions!
179190
| Annotations | Import XFDF annotations, flatten annotations |
180191
| Digital Signing | PAdES-compliant CMS and CAdES digital signatures (via document_signer tool) |
181192

193+
## Example Prompts
194+
195+
These examples assume your files live inside the configured sandbox and that you use explicit paths.
196+
197+
### HTML -> PDF -> signing
198+
199+
```text
200+
Convert /path/to/sandbox/invoice.html to PDF and save it as /path/to/sandbox/invoice.pdf.
201+
```
202+
203+
```text
204+
Digitally sign /path/to/sandbox/invoice.pdf with a visible signature and save it as /path/to/sandbox/invoice-signed.pdf.
205+
```
206+
207+
### OCR extraction
208+
209+
```text
210+
Run OCR on /path/to/sandbox/scanned-contract.pdf, return the extracted text, and save the OCR'd file as /path/to/sandbox/scanned-contract-ocr.pdf.
211+
```
212+
213+
### Check credits -> process -> inspect output
214+
215+
```text
216+
Check my Nutrient credits, convert /path/to/sandbox/report.docx to PDF, save it as /path/to/sandbox/report.pdf, and then tell me where the output file was written.
217+
```
218+
182219
## Use with AI Agent Frameworks
183220

184221
This MCP server works with any platform that supports the Model Context Protocol:
@@ -215,6 +252,8 @@ export SANDBOX_PATH=/path/to/sandbox/directory
215252
npx @nutrient-sdk/dws-mcp-server
216253
```
217254

255+
Supported CLI flags are `--sandbox <dir>` and `-s <dir>`. Unknown CLI flags fail fast instead of silently disabling sandboxing.
256+
218257
When sandbox mode is enabled:
219258

220259
- Relative paths resolve relative to the sandbox directory
@@ -225,7 +264,7 @@ When sandbox mode is enabled:
225264
226265
### Output Location
227266

228-
Processed files are saved to a location determined by the AI. To guide output placement, use natural language (e.g., "save the result to `output/result.pdf`") or create an `output` directory in your sandbox.
267+
Processed files are saved to a location determined by the AI. To guide output placement, use explicit output paths such as `save the result to /path/to/sandbox/output/result.pdf` or create an `output` directory in your sandbox.
229268

230269
### Authentication
231270

@@ -234,27 +273,52 @@ The server authenticates to the Nutrient DWS API (`https://api.nutrient.io`) usi
234273
| Method | When | Config |
235274
|--------|------|--------|
236275
| **API key** | `NUTRIENT_DWS_API_KEY` is set | Static key passed as Bearer token to DWS API |
237-
| **OAuth browser flow** | No API key set | Opens browser for Nutrient OAuth consent, caches token locally |
276+
| **OAuth browser flow** | No API key set | Opens browser for Nutrient OAuth consent on the first DWS-backed tool call, caches token locally |
238277

239-
When no API key is configured, the server opens a browser-based OAuth flow on the first tool call (similar to `gh auth login`). Tokens are cached at `$XDG_CONFIG_HOME/nutrient/credentials.json` or `~/.config/nutrient/credentials.json` and refreshed automatically.
278+
When no API key is configured, the server stays connected and opens a browser-based OAuth flow on the first DWS-backed tool call (similar to `gh auth login`). Tokens are cached at `$XDG_CONFIG_HOME/nutrient/credentials.json` or `~/.config/nutrient/credentials.json` and refreshed automatically.
240279

241280
### Environment Variables
242281

243282
| Variable | Required | Description |
244283
| ---------------------- | ----------- | -------------------------------------------------------------------------------------------- |
245-
| `NUTRIENT_DWS_API_KEY` | No* | Nutrient DWS API key ([get one free](https://dashboard.nutrient.io/sign_up/)) |
246-
| `SANDBOX_PATH` | Recommended | Directory to restrict file operations to |
247-
| `CLIENT_ID` | No | OAuth client ID. Skips DCR and enables token refresh when set |
248-
| `DWS_API_BASE_URL` | No | DWS API base URL (default: `https://api.nutrient.io`) |
249-
| `LOG_LEVEL` | No | Winston logger level (`info` default). Logs are written to `MCP_LOG_FILE` in stdio mode |
250-
| `MCP_LOG_FILE` | No | Override log file path (default: system temp directory) |
284+
| `NUTRIENT_DWS_API_KEY` | No* | Nutrient DWS API key ([get one free](https://dashboard.nutrient.io/sign_up/)) |
285+
| `SANDBOX_PATH` | Recommended | Directory to restrict file operations to |
286+
| `AUTH_SERVER_URL` | No | OAuth server base URL (default: `https://api.nutrient.io`) |
287+
| `CLIENT_ID` | No | OAuth client ID. Skips DCR and enables refresh token reuse when set |
288+
| `DWS_API_BASE_URL` | No | DWS API base URL (default: `https://api.nutrient.io`) |
289+
| `LOG_LEVEL` | No | Winston logger level (`info` default). Logs are written to `MCP_LOG_FILE` in stdio mode |
290+
| `MCP_LOG_FILE` | No | Override log file path (default: system temp directory) |
251291

252292
\* If omitted, the server uses an OAuth browser flow to authenticate with the Nutrient API.
253293

294+
## Data Handling
295+
296+
### What Stays Local
297+
298+
- The MCP server process, sandbox enforcement, and file path resolution run on the local machine.
299+
- `sandbox_file_tree` and `directory_tree` inspect local files only. They do not upload document contents to Nutrient.
300+
- API keys and OAuth credentials are stored locally on the machine running the MCP server.
301+
302+
### What Gets Sent to Nutrient
303+
304+
- `document_processor`, `document_signer`, and `ai_redactor` send the relevant request metadata and referenced document bytes to the Nutrient DWS API so the requested operation can run.
305+
- `check_credits` sends an authenticated account lookup but does not upload document files.
306+
- Processed results are written back to the local output path you request.
307+
254308
### Security Note: Token Storage
255309

256310
When using the OAuth browser flow, access tokens and refresh tokens are cached in plaintext at `$XDG_CONFIG_HOME/nutrient/credentials.json` or `~/.config/nutrient/credentials.json` (permissions `0600`). This file contains credentials equivalent to your API key. Do not commit it to version control or include it in shared backups.
257311

312+
## Privacy Policy
313+
314+
Nutrient's privacy policy is available at [nutrient.io/legal/privacy](https://www.nutrient.io/legal/privacy/).
315+
316+
## Support
317+
318+
For product or account support, contact Nutrient at [nutrient.io/company/contact](https://www.nutrient.io/company/contact/).
319+
320+
For bugs or feature requests specific to this MCP package, use [GitHub issues](https://github.com/PSPDFKit/nutrient-dws-mcp-server/issues).
321+
258322
## Troubleshooting
259323

260324
### Reset authentication to a clean state
@@ -303,7 +367,7 @@ The server will automatically register a new client and open the browser for con
303367

304368
- Check that `SANDBOX_PATH` points to an existing directory
305369
- Ensure your documents are inside the sandbox directory
306-
- Use the `sandbox_file_tree` tool to verify visible files
370+
- Ask the assistant to inspect the configured sandbox, or inspect the sandbox directory directly
307371

308372
## Contributing
309373

src/index.ts

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function addToolsToServer(options: {
4141

4242
server.tool(
4343
'document_processor',
44-
`Processes documents using Nutrient DWS Processor API. Reads from and writes to file system or sandbox (if enabled).
44+
`Nutrient document processing tool backed by the Nutrient DWS Processor API. Reads input files from the local file system or sandbox (if enabled) and writes results back locally.
4545
4646
Features:
4747
• Import XFDF annotations
@@ -53,6 +53,13 @@ Features:
5353
5454
Output formats: PDF, PDF/A, images (PNG, JPEG, WebP), JSON extraction, Office (DOCX, XLSX, PPTX)`,
5555
BuildAPIArgsSchema.shape,
56+
{
57+
title: 'Nutrient Document Processor',
58+
readOnlyHint: false,
59+
destructiveHint: true,
60+
idempotentHint: false,
61+
openWorldHint: true,
62+
},
5663
async ({ instructions, outputPath }) => {
5764
try {
5865
return await performBuildCall(instructions, outputPath, apiClient)
@@ -64,7 +71,7 @@ Output formats: PDF, PDF/A, images (PNG, JPEG, WebP), JSON extraction, Office (D
6471

6572
server.tool(
6673
'document_signer',
67-
`Digitally signs PDF files using Nutrient DWS Sign API. Reads from and writes to file system or sandbox (if enabled).
74+
`Nutrient PDF signing tool backed by the Nutrient DWS Sign API. Reads input files from the local file system or sandbox (if enabled) and writes signed output back locally.
6875
6976
Signature types:
7077
• CMS/PKCS#7 (standard digital signatures)
@@ -80,6 +87,13 @@ Positioning:
8087
• Place on specific page coordinates
8188
• Use existing signature form fields`,
8289
SignAPIArgsSchema.shape,
90+
{
91+
title: 'Nutrient Document Signer',
92+
readOnlyHint: false,
93+
destructiveHint: true,
94+
idempotentHint: false,
95+
openWorldHint: true,
96+
},
8397
async ({ filePath, signatureOptions, watermarkImagePath, graphicImagePath, outputPath }) => {
8498
try {
8599
return await performSignCall(
@@ -98,7 +112,7 @@ Positioning:
98112

99113
server.tool(
100114
'ai_redactor',
101-
`AI-powered document redaction using Nutrient DWS AI Redaction API. Reads from and writes to file system or sandbox (if enabled).
115+
`Nutrient AI redaction tool backed by the Nutrient DWS AI Redaction API. Reads input files from the local file system or sandbox (if enabled) and writes redacted output back locally.
102116
103117
Automatically detects and permanently removes sensitive information from documents using AI analysis.
104118
Detected content types include:
@@ -110,6 +124,13 @@ Detected content types include:
110124
111125
By default (when neither stage nor apply is set), redactions are detected and immediately applied. Set stage to true to detect and stage redactions without applying them. Set apply to true to apply previously staged redactions.`,
112126
AiRedactArgsSchema.shape,
127+
{
128+
title: 'Nutrient AI Redactor',
129+
readOnlyHint: false,
130+
destructiveHint: true,
131+
idempotentHint: false,
132+
openWorldHint: true,
133+
},
113134
async ({ filePath, criteria, outputPath, stage, apply }) => {
114135
try {
115136
return await performAiRedactCall(filePath, criteria, outputPath, apiClient, stage, apply)
@@ -123,8 +144,17 @@ By default (when neither stage nor apply is set), redactions are detected and im
123144
'check_credits',
124145
`Check your Nutrient DWS API credit balance and usage for the current billing period.
125146
147+
This is a read-only account lookup. It does not upload any document content.
148+
126149
Returns: subscription type, total credits, used credits, and remaining credits.`,
127150
CheckCreditsArgsSchema.shape,
151+
{
152+
title: 'Nutrient Credit Balance',
153+
readOnlyHint: true,
154+
destructiveHint: false,
155+
idempotentHint: true,
156+
openWorldHint: true,
157+
},
128158
async () => {
129159
try {
130160
return await performCheckCreditsCall(apiClient)
@@ -137,15 +167,29 @@ Returns: subscription type, total credits, used credits, and remaining credits.`
137167
if (sandboxEnabled) {
138168
server.tool(
139169
'sandbox_file_tree',
140-
'Returns the file tree of the sandbox directory. It will recurse into subdirectories and return a list of files and directories.',
170+
'Browse files already available in the configured sandbox directory. This is a read-only local filesystem operation and does not upload documents to Nutrient.',
141171
{},
172+
{
173+
title: 'Nutrient Sandbox Files',
174+
readOnlyHint: true,
175+
destructiveHint: false,
176+
idempotentHint: true,
177+
openWorldHint: false,
178+
},
142179
async () => performDirectoryTreeCall('.'),
143180
)
144181
} else {
145182
server.tool(
146183
'directory_tree',
147-
'Returns the directory tree of a given path. All paths are resolved relative to root directory.',
184+
'Browse local files when sandbox mode is disabled. This is a read-only local filesystem operation, but it can inspect any path visible to the current user. Sandbox mode is strongly recommended.',
148185
DirectoryTreeArgsSchema.shape,
186+
{
187+
title: 'Nutrient Directory Tree',
188+
readOnlyHint: true,
189+
destructiveHint: false,
190+
idempotentHint: true,
191+
openWorldHint: false,
192+
},
149193
async ({ path }) => performDirectoryTreeCall(path),
150194
)
151195
}

0 commit comments

Comments
 (0)