Enterprise edition
MCP — Deep Reference
At a glance
Section titled “At a glance”The NextPDF\Enterprise\Mcp namespace ships the Enterprise tier of the NextPDF MCP tool catalog. Its public surface is eleven tool classes, one client factory, and one typed exception. Every tool implements the NextPDF\Server\Tools\ToolInterface contract from the nextpdf/server runtime and declares ToolTier::Enterprise. Six tools analyze a single PDF in-process. Four tools delegate batch and RAG workloads to the Spectrum sidecar through NextPDF\Enterprise\Mcp\SpectrumClientFactory. One tool reads a constructor-injected AST mutation audit trail instead of PDF bytes. Each tool self-describes its MCP name, JSON Schema input, client annotations, RiskLevel, and category.
Availability & licensing
Section titled “Availability & licensing”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.
Public API surface
Section titled “Public API surface”| Symbol | Parameters | Default behavior | Returns | Throws or fails with | Notes |
|---|---|---|---|---|---|
ForensicAnalyzeTool::execute | array $arguments, InMemoryDocumentStore $store; args: document_id or source | Runs forensic analysis: revisions, incremental updates, signatures | ToolResult (JSON report) | Error ToolResult; exceptions are caught, never rethrown | Tool forensic_analyze; RiskLevel::Safe; read-only, idempotent; category document; since 2.0.0 |
BatchForensicAnalyzeTool::execute | args: workspace_token, documents[] (each id + path) | Batch forensic analysis via the Spectrum sidecar | ToolResult with per-document status, succeeded and failed counts | Error ToolResult (missing arguments, sidecar failure) | Tool batch_forensic_analyze; RiskLevel::Safe; category document; since 2.1.0 |
ComplianceCheckTool::execute | args: policy (12-value enum), document_id or source | Assesses the PDF against one named compliance policy | ToolResult with findings, pass/fail, duration_ms, and a disclaimer field | Error ToolResult; unknown policy returns an error listing supported keys | Tool compliance_check; RiskLevel::Review; category document; since 2.0.0 |
BatchComplianceCheckTool::execute | args: workspace_token, documents[], policies (pdfa, pades, zugferd; default ["pdfa"]) | Batch compliance checks via the Spectrum sidecar | ToolResult with compliant / non-compliant counts | Error ToolResult; each documents[] element is validated for non-empty id and path | Tool batch_compliance_check; RiskLevel::Safe; category document; since 2.1.0 |
LtvHealthCheckTool::execute | args: document_id or source | Runs the LTV health policy over a signed PDF | ToolResult with findings and pass/fail | Error ToolResult | Tool ltv_health_check; RiskLevel::Safe; category document; since 2.0.0 |
AiReadyCertifyTool::execute | args: document_id or source | Read-only AI-readiness assessment over four criteria | ToolResult with certification_level (certified, partial, not_certified) and per-criterion booleans | Error ToolResult | Tool ai_ready_certify; RiskLevel::Review; read-only; category document; since 2.0.0 |
CertifyAiReadyTool::execute | args: document_id or source, return_stamped_pdf (default true) | Assesses three criteria and appends an XMP provenance stamp | ToolResult; includes stamped_pdf_base64 unless disabled or not_certified | Error ToolResult | Tool certify_ai_ready; RiskLevel::Review; not read-only; category document; since 3.0.0 |
AstAwareChunkTool::execute | args: document_id or source, max_chunk_chars (default 1500), overlap_chars (default 150) | Builds the AST and emits citation-anchored chunks with provenance | ToolResult with chunk_count and per-chunk node ID, page index, bbox, node type | Error ToolResult | Tool ast_aware_chunk; RiskLevel::Review; category extraction; since 3.0.0 |
AuditAstMutationsTool::__construct | AstAuditTrailInterface $auditTrail | Injects the audit-trail backend | instance | — | Constructor-injected dependency; since 3.0.0 |
AuditAstMutationsTool::execute | args: document_source_hash (SHA-256 hex, required) | Returns all recorded AST mutation events for that document | ToolResult with entries[] and count | Error ToolResult when the argument is missing or empty | Tool audit_ast_mutations; RiskLevel::Review; category document; since 3.0.0 |
EmbedDocumentsTool::execute | args: collection_id, workspace_token, documents[] (all required) | Ingests PDFs into a RAG collection via the Spectrum sidecar | ToolResult with succeeded / total / failed counts | Error ToolResult | Tool embed_documents; RiskLevel::Caution; not read-only, not idempotent; category extraction; since 2.1.0 |
SearchDocumentsTool::execute | args: collection_id, query (required), top_k (default 10, clamped 1–100), mode (hybrid, bm25, semantic) | Hybrid retrieval over an ingested collection | ToolResult with ranked chunks and relevance scores | Error ToolResult; a mode outside the allowlist is rejected | Tool search_documents; RiskLevel::Safe; category extraction; since 2.1.0 |
SpectrumClientFactory::create | none (reads SPECTRUM_URL, SPECTRUM_TIMEOUT, SPECTRUM_AUTH_TOKEN, SPECTRUM_APP_SECRET) | Builds and caches one process-wide sidecar client | SpectrumClient | InvalidArgumentException when SPECTRUM_URL is malformed or targets a blocked address | Default endpoint http://127.0.0.1:7800; timeout 30.0 s; since 2.1.0 |
SpectrumClientFactory::reset | none | Clears the cached client instance | void | — | Intended for tests |
SpectrumClientFactory::createRequest | string $method, $uri (string or UriInterface) | Builds a PSR-7 request from Core HTTP classes | RequestInterface | — | PSR-17 RequestFactoryInterface implementation |
SpectrumClientFactory::createStream | string $content = '' | Builds an in-memory PSR-7 stream | StreamInterface | — | PSR-17 StreamFactoryInterface implementation |
SpectrumClientFactory::createStreamFromFile | string $filename, string $mode = 'r' | Opens the file and wraps it as a stream | StreamInterface | McpStreamException when the file cannot be opened | McpStreamException extends RuntimeException |
SpectrumClientFactory::createStreamFromResource | $resource (PHP resource) | Wraps an existing resource as a stream | StreamInterface | — | PSR-17 StreamFactoryInterface implementation |
McpStreamException | — | Typed stream-acquisition failure | — | — | final class, extends RuntimeException; source documents PSR-17 §1.5 compatibility; the source annotates it @since 3.2.0 (present in the current 3.1.0-aliased dev line) |
Every tool also exposes the ToolInterface self-description methods: name, description, inputSchema, annotations, riskLevel, tier, and category. Their per-tool values appear in the Notes column above.
Entry-point signatures, verbatim from source:
public function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function __construct(private readonly AstAuditTrailInterface $auditTrail)public function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic function execute(array $arguments, InMemoryDocumentStore $store): ToolResultpublic static function create(): SpectrumClientpublic static function reset(): voidpublic function createRequest(string $method, $uri): RequestInterfacepublic function createStream(string $content = ''): StreamInterfacepublic function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterfacepublic function createStreamFromResource($resource): StreamInterfaceBehavior contract
Section titled “Behavior contract”- Every tool implements
NextPDF\Server\Tools\ToolInterfaceand declaresToolTier::Enterpriseexplicitly. Tier is never inferred from namespace or packaging. executedoes not throw. Every failure is caught and returned as an errorToolResultcarrying the failure message.- Single-document tools resolve PDF bytes with a fixed priority. A
document_idis looked up in theInMemoryDocumentStorefirst. Otherwisesourceis interpreted as adata:URI, then as raw base64 (over 256 characters), then as a file path. - Filesystem
sourcepaths are disabled by default. They activate only when theNEXTPDF_MCP_INPUT_DIRenvironment variable names a confined input directory. The resolved real path must stay inside that directory. Everything else fails closed. - Stream-wrapper schemes (
phar://,php://,file://, and any other scheme) and null bytes in a file-pathsourceare rejected before any filesystem call. Traversal and symlink escapes fail against the real-path confinement check. - Sidecar-backed tools (
embed_documents,search_documents,batch_compliance_check,batch_forensic_analyze) obtain their client fromSpectrumClientFactory::create. The factory validates a non-localhostSPECTRUM_URLagainst private and reserved address ranges before use. Explicit localhost is allowed for the local sidecar mode. ai_ready_certifyderives its level from four criteria: forensic integrity, signature presence, LTV validity, and absence of encryption. All four passing yieldscertified; one to three yieldspartial; zero yieldsnot_certified. Forensic integrity is a structural heuristic over the revision chain, not a cryptographic byte-integrity verification. The encryption check inspects the trailer region only.certify_ai_readyevaluates three criteria and appends an XMP provenance stamp. The stamped bytes are returned base64-encoded unlessreturn_stamped_pdfisfalseor the level isnot_certified.compliance_checkaccepts exactly twelve policy keys:pdfa4,pdfa4e,pdfa4f,pades-baseline,ltv-health,eidas-qualified,zugferd,fda-part11,sec-17a4,sec-17a4-compatible,sec-17a4-structural,sec-17a4-pre-sign. An unknown key returns an error result naming the supported set.audit_ast_mutationsreads only the injectedAstAuditTrailInterface. It records nothing itself.
Edge cases & failure modes
Section titled “Edge cases & failure modes”- Neither
document_idnorsourceprovided: error result instructing the caller to supply one of them. - Unknown
document_id: error result naming the ID and pointing tocreate_pdf. - Filesystem
sourcewithNEXTPDF_MCP_INPUT_DIRunset: rejected with a message naming the supported channels. sourcepath resolving outside the configured input directory, including via symlink: rejected. The comparison happens on a directory-separator boundary, so sibling directories sharing a name prefix cannot pass.data:URI without a comma separator, or invalid base64 payload: error result.search_documentstop_koutside 1–100: clamped, not rejected. A non-integertop_kfalls back to the configured pipeline default.search_documentsmodeoutsidehybrid,bm25,semantic: error result from the pipeline allowlist.batch_compliance_checkdocuments[]element missingidorpath, or carrying empty strings: error result naming the offending index.batch_forensic_analyzevalidates only the outer array shape; element defects surface from the batch layer.SpectrumClientFactory::createwith a malformedSPECTRUM_URL, or one targeting a private, link-local, or metadata address:InvalidArgumentException. Inside a toolexecutethis surfaces as an error result.SpectrumClientFactory::createStreamFromFileon an unreadable path:McpStreamException.- Empty environment variables are treated as unset and fall back to defaults.
Conformance
Section titled “Conformance”The MCP tools report capability-level assessments. The certification_level values returned by ai_ready_certify and certify_ai_ready are the tools’ own reported vocabulary. compliance_check responses include a disclaimer field produced by the underlying report. Policy clause references, such as the LTV policy basis the product source states as ISO 32000-2:2020 §12.8.4.3, are carried in the tool descriptions and per-finding clause fields. Whether a checked document satisfies a regulation is a determination for the operator and their assessors.
Development notes
Section titled “Development notes”SpectrumClientFactory::createcaches one client per process. CallSpectrumClientFactory::resetin test setup to force a fresh client.- Environment reads consult
$_ENV, then$_SERVER, thengetenv, and treat empty strings as absent. RiskLeveldrives host-side handling in the server runtime:Safeauto-executes,Cautionand above are audit-logged, andApprovalRequireddemands human confirmation. No Enterprise MCP tool declaresApprovalRequired. Operator overrides can raise a declared level, never lower it.annotationsvalues (readOnlyHint,idempotentHint) are MCP client hints, not enforcement. Confinement and validation happen server-side regardless of hints.- Tools report
categoryvaluesdocumentorextractionfortools/listfiltering. AuditAstMutationsToolis the only tool requiring constructor injection; register it with a concreteAstAuditTrailInterfaceimplementation.
See also
Section titled “See also”- MCP (capability page)
- Accelerator — Deep Reference — the Spectrum sidecar client surface.
- Forensics — Deep Reference — the analyzer behind
forensic_analyze. - Compliance — Deep Reference — the policies behind
compliance_check. - AST — Deep Reference — chunking and the mutation audit trail.
- Validation — Deep Reference
Publication boundary
Section titled “Publication boundary”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.