Skip to content

Launcher API

Package

doc_processing_std_tools

doc-processing-std-tools — Standard MCP tool servers for doc-processing-toolkit agents.

Each server is a FastMCP instance that can be passed directly to Agent(tools=[...]) in doc-processing-toolkit.

Example::

from doc_processing_std_tools import file_system_server, memory_server
from doc_processing_toolkit import Agent

agent = Agent(
    model="claude-sonnet-5",
    tools=[file_system_server, memory_server],
)

For consumers that want all 8 servers exposed through a single MCP endpoint, run python -m doc_processing_std_tools (see __main__.py).

Server attributes are imported lazily (PEP 562 __getattr__): importing this package, or one server, never force-imports the others. So a minimal install (e.g. only the docs extra) can from doc_processing_std_tools import document_processing_server without the absence of an unrelated server's optional dependency breaking the import.

__getattr__(name)

Import the owning module on first access (PEP 562).

Composed Launcher

doc_processing_std_tools.__main__

Multi-server launcher for doc-processing-std-tools.

Running python -m doc_processing_std_tools composes all 8 sub-servers into a single FastMCP service and runs it over stdio (default) or HTTP. The browser server is added only when DPTTOOLS_ENABLE_BROWSER=true and the computer (desktop) server only when DPTTOOLS_ENABLE_COMPUTER=true: a server that drives a browser or a desktop should not appear just because the package is installed.

Composition model

The bundled mcp SDK does not expose a high-level composition API (no import_server / mount / compose on FastMCP). We therefore compose by manually re-registering each sub-server's tools on a single parent FastMCP instance via parent.add_tool(). Each tool's underlying function, name, description, annotations, icons and metadata are copied over verbatim — there are no behavioural differences between calling a tool through the composed parent and calling it through its original sub-server.

Tool-name namespacing (no prefix)

We do not prefix tool names. The 8 sub-servers ship with 56 globally-unique names today (verified at composition time). If a future addition introduces a collision, this module raises RuntimeError at startup with the colliding tool name and the two owning sub-servers — fail fast rather than silently shadow.

If you ever need to add prefixing (e.g. because two sub-servers genuinely need to expose tools with the same short name), add a prefix parameter to compose_servers() and apply it inside the add_tool loop. Keep the no-prefix default for backward compatibility with consumers that import the individual sub-servers.

Configuration

All DPTTOOLS_* environment variables are honoured exactly as when running individual sub-servers. Each is read through _config the first time it is needed and cached for the life of the process, and main() validates them at start-up so a bad value stops the launcher at once.

Optional servers

enabled_sub_servers() returns the always-on eight plus the browser server when DPTTOOLS_ENABLE_BROWSER is true and the computer server when DPTTOOLS_ENABLE_COMPUTER is true. Their settings (DPTTOOLS_BROWSER_*, DPTTOOLS_COMPUTER_*) are validated at start-up only in that case, so a bad setting for an optional server cannot stop the others.

Blocking tools run on worker threads

FastMCP calls a synchronous tool function directly on its event loop, so one slow call (an OCR job, a LibreOffice conversion, a long command) would freeze every other request and the transport itself. The parent therefore registers each synchronous tool as an async wrapper that runs it on a worker thread (anyio.to_thread.run_sync). The wrapper uses functools.wraps, so the tool's name, description and JSON schema are unchanged. Tools that are already async are registered as-is. Individual sub-servers and in-process use are not affected.

CLI

::

python -m doc_processing_std_tools                # stdio (default)
python -m doc_processing_std_tools --transport http --port 8000
HTTP transport security

The HTTP transport binds to 127.0.0.1 by default (loopback only). The composed server performs no authentication of its own, so do not bind it to a public interface (--host 0.0.0.0) unless it sits behind an authenticating reverse proxy / network policy. This is a network posture note (separate from the filesystem container model).

compose_servers(sub_servers=None, name=PARENT_SERVER_NAME)

Compose the given sub-servers into a single parent FastMCP server.

Parameters:

Name Type Description Default
sub_servers list[tuple[str, FastMCP]] | None

Optional list of (label, server) tuples to compose. Defaults to enabled_sub_servers(): the 8 always-on sub-servers, plus the browser and computer servers when enabled.

None
name str

Parent server name.

PARENT_SERVER_NAME

Returns:

Type Description
FastMCP

A new FastMCP with every sub-server's tools re-registered

FastMCP

on it.

Raises:

Type Description
RuntimeError

If two sub-servers register a tool with the same name — fail fast rather than silently shadow.

enabled_sub_servers()

The always-on sub-servers plus any optional server switched on by env.

Raises:

Type Description
ConfigError

DPTTOOLS_ENABLE_BROWSER or DPTTOOLS_ENABLE_COMPUTER is not a boolean.