Skip to content
getnextpdf.com

Enterprise edition

MCP tools

NextPDF Enterprise adds eleven MCP tools to the NextPDF Connect server. They give AI assistants and agent frameworks direct, typed access to the Enterprise engine: compliance policy checks, PDF forensics, LTV health checks, AI-readiness stamping, AST-aware chunking, and RAG ingestion and search. Every tool declares its own risk level and read-only posture, so your MCP host can gate, log, and audit agent activity with confidence. Failures never surface as exceptions; agents always receive a structured, parseable result.

This capability ships in NextPDF Enterprise (nextpdf/enterprise) and activates with an Enterprise-tier license envelope. A deployment without that entitlement does not load the capability’s classes. Compare editions and get a license.

Terminal window
composer require nextpdf/enterprise:^3

The MCP host itself is NextPDF Connect, shipped in the nextpdf/server package; see Connect install. When both packages are present, the server’s tool registry discovers NextPDF\Enterprise\McpToolProvider automatically and registers the eleven Enterprise tools. No wiring code is required. If nextpdf/server is absent, the provider file returns early and nothing loads.

The batch and RAG tools additionally require the Spectrum sidecar. Configure it through environment variables read by NextPDF\Enterprise\Mcp\SpectrumClientFactory: SPECTRUM_URL (default http://127.0.0.1:7800), SPECTRUM_TIMEOUT (default 30.0 seconds), SPECTRUM_AUTH_TOKEN, and SPECTRUM_APP_SECRET.

The Model Context Protocol (MCP) is an open protocol that lets AI assistants and agent frameworks call typed tools exposed by a server. Instead of pasting PDF bytes into a prompt and hoping, an agent calls a named tool with a JSON-schema-validated payload and receives a deterministic, structured result. NextPDF Connect is that server for PDFs; the Enterprise package extends its catalog with the tools below. Each tool is a thin wrapper over the same Enterprise APIs your PHP code calls directly, so an agent-run check and a code-run check produce the same verdict.

MCP toolClassWhat it doesRiskRead-only
compliance_checkComplianceCheckToolValidates one PDF against a named policy: pdfa4, pdfa4e, pdfa4f, pades-baseline, ltv-health, eidas-qualified, zugferd, fda-part11, and four sec-17a4 variants.Reviewyes
batch_compliance_checkBatchComplianceCheckToolChecks many PDFs against pdfa, pades, or zugferd policies in one Spectrum sidecar batch.Safeyes
forensic_analyzeForensicAnalyzeToolReports revision history, incremental updates, and modification events for tamper detection.Safeyes
batch_forensic_analyzeBatchForensicAnalyzeToolRuns forensic analysis over many PDFs in one sidecar batch.Safeyes
ltv_health_checkLtvHealthCheckToolChecks a signed PDF for long-term validation material: DSS dictionary, OCSP responses, CRL entries, VRI entries, and certificate stores.Safeyes
ai_ready_certifyAiReadyCertifyToolRead-only product-defined AI-readiness verdict over four criteria: forensic integrity, signature presence, LTV validity, no encryption.Reviewyes
certify_ai_readyCertifyAiReadyToolProduct-defined readiness verdict over three criteria (the read-only tool’s four minus forensic integrity - by design, since this tool rewrites the file it stamps) and appends an XMP provenance stamp; returns the stamped PDF as base64.Reviewno
ast_aware_chunkAstAwareChunkToolSplits a PDF into citation-anchored chunks along heading boundaries, with node ID, page index, and bounding box per chunk.Reviewyes
audit_ast_mutationsAuditAstMutationsToolRetrieves the AST mutation audit trail for a document by SHA-256 source hash.Reviewyes
embed_documentsEmbedDocumentsToolIngests PDFs into a RAG collection: parse, chunk, embed, index. Modifies collection state.Cautionno
search_documentsSearchDocumentsToolHybrid retrieval (BM25 keyword plus semantic) over an ingested collection, with ranked, scored chunks.Safeyes

The “certify” tools issue a product-defined readiness verdict (certified, partial, or not_certified). That verdict is a technical check result, not a certification by any accreditation body.

Every tool declares a risk level from the four-tier Connect model. Safe tools auto-execute. Caution tools auto-execute with an audit-log entry. Review tools carry a warning for the calling agent’s instructions. ApprovalRequired tools demand human confirmation; no Enterprise MCP tool currently declares this level, because none is destructive. Runtime configuration can only raise a tool’s risk level, never lower it. Tools also publish MCP behavior annotations (readOnlyHint, idempotentHint), so a conforming client can apply its own gating on top. See HITL risk tiers for the full model.

The load-bearing decision is that tools are thin, deterministic wrappers with self-declared governance: each tool states its own risk level and tier as a domain invariant, never inferred from namespace or packaging. This keeps the gating decision auditable at the host without trusting the transport. Tools contain no document intelligence of their own; they delegate to the same Enterprise APIs your code calls, so there is exactly one behavior to test and one verdict to trust. Errors return on the MCP error channel instead of escaping as exceptions, because an agent cannot catch a PHP exception but can always branch on isError. Input that could touch the filesystem is fail-closed by default, since MCP arguments are attacker-reachable by definition.

Design background: An API that refuses to guess.

All eleven tools implement the NextPDF\Server\Tools\ToolInterface contract from nextpdf/server and share the same public surface. Signatures below are shown once on NextPDF\Enterprise\Mcp\ComplianceCheckTool as the representative:

public function name(): string
public function description(): string
public function inputSchema(): array
public function annotations(): array
public function riskLevel(): RiskLevel
public function tier(): ToolTier
public function category(): string
public function execute(array $arguments, InMemoryDocumentStore $store): ToolResult

Throws or fails with: execute() never throws. It catches Throwable internally and returns ToolResult::error() with isError = true. Invalid arguments (missing workspace_token, malformed documents entries, unknown document_id, unsafe source) surface as InvalidArgumentException messages on that error channel.

The audit-trail tool takes its storage backend by constructor injection:

public function __construct(private readonly AstAuditTrailInterface $auditTrail)

The provider that registers the catalog:

public function getTier(): string
public function getTools(): array

getTier() returns 'enterprise'. getTools() returns the eleven tool instances; audit_ast_mutations is wired with NextPDF\Enterprise\Ast\InMemoryAstAuditTrail by default.

The Spectrum sidecar client factory, which is also a PSR-17 request and stream factory:

public static function create(): SpectrumClient
public static function reset(): void
public function createRequest(string $method, $uri): RequestInterface
public function createStream(string $content = ''): StreamInterface
public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
public function createStreamFromResource($resource): StreamInterface

Throws or fails with: create() throws InvalidArgumentException when SPECTRUM_URL is malformed or when the configured endpoint targets a known private or reserved address (except localhost). This is a configuration-time gate, not a network-layer control: still enforce egress policy, redirect handling, and DNS pinning in the host environment. createStreamFromFile() throws NextPDF\Enterprise\Mcp\McpStreamException (a RuntimeException subclass, per the PSR-17 contract) when the file cannot be opened.

Run a PDF/A-4 compliance check exactly as an agent would, using the in-memory data: URI channel:

quick-compliance-check.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Mcp\ComplianceCheckTool;
use NextPDF\Enterprise\Mcp\McpStreamException;
use NextPDF\Enterprise\Mcp\SpectrumClientFactory;
use NextPDF\Server\Document\InMemoryDocumentStore;
$streams = new SpectrumClientFactory(); // PSR-17 stream factory from this module
try {
$pdfBytes = (string) $streams->createStreamFromFile(__DIR__ . '/invoice.pdf');
} catch (McpStreamException $e) {
fwrite(STDERR, 'Cannot read PDF: ' . $e->getMessage() . PHP_EOL);
exit(1);
}
$tool = new ComplianceCheckTool();
$result = $tool->execute(
[
'source' => 'data:application/pdf;base64,' . base64_encode($pdfBytes),
'policy' => 'pdfa4',
],
new InMemoryDocumentStore(),
);
// Tool failures arrive on the MCP error channel, never as exceptions.
if ($result->isError) {
fwrite(STDERR, $result->content[0]['text'] . PHP_EOL);
exit(1);
}
echo $result->content[0]['text'] . PHP_EOL;

Expected output for a conformant file (finding counts vary per document):

Compliance check (PDF/A-4): PASS — 0 finding(s)

The full machine-readable report, including per-finding severity, rule ID, clause, and suggestion, is available on $result->structured.

Preflight the sidecar, enforce the declared risk posture, then run a batch compliance check:

gated-batch-compliance.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Mcp\BatchComplianceCheckTool;
use NextPDF\Enterprise\Mcp\SpectrumClientFactory;
use NextPDF\Server\Document\InMemoryDocumentStore;
// 1. Fail fast on sidecar misconfiguration before accepting agent traffic.
// The factory validates SPECTRUM_URL and rejects private/reserved targets.
try {
SpectrumClientFactory::create();
} catch (InvalidArgumentException $e) {
fwrite(STDERR, 'Spectrum sidecar rejected: ' . $e->getMessage() . PHP_EOL);
exit(1);
}
$tool = new BatchComplianceCheckTool();
$risk = $tool->riskLevel();
// 2. Enforce the declared risk posture before execution.
if ($risk->requiresHumanConfirmation()) {
// Route to your approval queue instead of executing.
exit(0);
}
if ($risk->requiresAuditLog()) {
error_log(sprintf('[mcp-audit] tool=%s risk=%s', $tool->name(), $risk->label()));
}
// 3. Execute the batch.
$result = $tool->execute(
[
'workspace_token' => (string) getenv('SPECTRUM_WORKSPACE_TOKEN'),
'documents' => [
['id' => 'contract-001', 'path' => '/var/pdf-inbox/contract-001.pdf'],
['id' => 'contract-002', 'path' => '/var/pdf-inbox/contract-002.pdf'],
],
'policies' => ['pdfa', 'pades'],
],
new InMemoryDocumentStore(),
);
echo $result->content[0]['text'] . PHP_EOL;

Expected output (counts reflect your documents):

Batch compliance check complete: 1 compliant, 1 non-compliant
  • Filesystem source paths are disabled by default. Without the NEXTPDF_MCP_INPUT_DIR environment variable, a path-shaped source is rejected with an error result. Use document_id, a data: URI, or raw base64 instead.
  • Raw base64 is recognized only above 256 characters. A shorter base64 blob is treated as a file path and rejected. Wrap small payloads in a data:application/pdf;base64, URI.
  • Unknown document_id values fail with guidance. The error text is Unknown document_id: ... Call create_pdf first. Documents in the in-memory store also expire on the store’s TTL, so a stale ID fails the same way.
  • compliance_check rejects unknown policy keys and lists the supported set in the error message.
  • Batch and RAG tools need the sidecar. batch_compliance_check, batch_forensic_analyze, embed_documents, and search_documents require a reachable Spectrum endpoint and a workspace_token. The factory caches one client per process; call SpectrumClientFactory::reset() in tests.
  • search_documents clamps top_k to 1–100; non-integer values fall back to the server default of 10.
  • ast_aware_chunk defaults are 1500 characters per chunk with 150 characters of overlap.
  • certify_ai_ready omits the stamped bytes when return_stamped_pdf is false or the verdict is not_certified. When present, the base64 payload is about one third larger than the PDF itself.
  • The default AST audit trail is in-memory. Entries recorded through the stock provider wiring do not persist across processes; inject a persistent AstAuditTrailInterface implementation for durable audit trails.
  • Fail-closed source resolution. MCP callers fully control tool arguments, so the resolver treats them as hostile. Stream wrappers (phar://, php://, file://, and any scheme) and null bytes are rejected before any filesystem call. Path traversal is rejected. Raw file paths work only when NEXTPDF_MCP_INPUT_DIR is set, and the realpath-canonicalized target must resolve strictly inside that directory, compared on a separator boundary to block prefix-confusion escapes.
  • SSRF guard on the sidecar endpoint. SpectrumClientFactory allows localhost for the local-sidecar mode and validates every other SPECTRUM_URL against private, reserved, link-local, and cloud-metadata ranges, throwing InvalidArgumentException on a blocked address. This is a configuration-time gate on the configured endpoint, not a network-layer control - keep egress policy, redirect handling, and DNS pinning in the host environment.
  • Secrets stay in the environment. The sidecar bearer token (SPECTRUM_AUTH_TOKEN) and HMAC signing secret (SPECTRUM_APP_SECRET) are read from environment variables and never appear in tool payloads or results.
  • Non-reflective errors. Path-rejection messages are generic by design (Source path is not permitted.), so a probing caller learns nothing about the host filesystem.
  • Risk overrides only go up. Operator configuration can raise a tool’s declared risk level but can never lower it below the tool’s own declaration.

The compliance tools check document structure against the named policy profiles and report findings with clause references; the compliance_check report additionally carries the engine’s own disclaimer that it is a technical structure check for reference, not legal advice or a compliance endorsement. The ai_ready_certify and certify_ai_ready verdicts are product-defined readiness levels. MCP is an open protocol published by its vendor steward.

  • Tool failures are returned as error results (isError = true with a message); exceptions never cross the MCP boundary.
  • Successful results carry a one-line human-readable summary plus a structured JSON payload with a stable, documented field set per tool.
  • Every tool reports tier() = ToolTier::Enterprise and a declared RiskLevel; risk cannot be lowered at runtime.
  • Read-only tools declare readOnlyHint: true and do not modify the document store, the source PDF, or any collection.
  • certify_ai_ready never alters the input document in place; the stamp is applied to a returned copy.
  • Compliance and LTV reports include a validation timestamp and finding counts by severity; the compliance_check payload additionally includes the engine’s legal disclaimer string.

The MCP host itself does not require Enterprise. NextPDF Connect (nextpdf/server, Apache-2.0) runs with the open Core engine and serves its core-tier tool catalog: document creation, text and content operations, and extraction. See the tool catalog. Core alone does not provide compliance policy checks, forensic analysis, LTV health checks, AI-readiness stamping, AST-aware chunking, mutation audit trails, or the batch and RAG tools; those eleven tools register only with nextpdf/enterprise installed and licensed.

This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.