Skip to content

Compatibility

Tested versions

std-tools 0.6.0 is tested against doc-processing-toolkit 0.5.1 and 0.5.2, on Python 3.10.11 and 3.12, with mcp 1.26 and 1.30. The standing check is tests/integration/test_toolkit_compat.py: it runs whenever the toolkit is installed next to std-tools, makes no model call, and covers the points on this page. 0.6.1 changes nothing on this page: its changes are to key input, the address check, error wording and the docs.

Python

doc-processing-std-tools requires Python 3.10 or newer (requires-python = ">=3.10").

The mcp SDK

std-tools requires mcp>=1.25,<2, the same range as the toolkit. (0.5.0 declared mcp>=1.0.0,<2; the old floor was never meaningful next to the toolkit.)

The ceiling below 2 is deliberate: the composed launcher reads each server's registered tools through a private FastMCP attribute, because the SDK has no public composition API, and the toolkit also relies on FastMCP internals. A move to mcp 2.x has to be made in both packages together.

doc-processing-toolkit

std-tools does not depend on the toolkit and imports nothing from it; the servers work with any MCP host. The two packages meet at a few points, and these are the contract:

Contract Detail Since
Server objects as tools The toolkit's Agent(tools=[...]) accepts a FastMCP server object directly, which is how std-tools servers attach in-process —
Image results in-process read_image, render_document_page, render_document_thumbnail, read_document_pages_as_images, take_screenshot, fetch_image, the browser's browser_screenshot and browser_zoom, and the computer server's computer_screenshot and computer_zoom return images. Attached in-process, they reach the model as images only from toolkit 0.5.1; earlier versions turned them into the text <...Image object at 0x...>. Out-of-process use works with any toolkit version toolkit 0.5.1
The list_skills payload Each entry in skills has a path (absolute path to its SKILL.md), and non-fatal problems come in a top-level diagnostics array. The toolkit's skills auto-injection reads both std-tools 0.2.0
Skills tool names The toolkit hides load_skill, load_skill_resource and execute_skill_script when the catalog is empty. Renaming any of them would silently break that std-tools 0.2.0
Skills server name The toolkit finds the skills server by its name, which must contain skill. skills_server is named skills-tools, which matches; the composed server is named doc-processing-std-tools, which does not —
allowed_tools Exposing only some of a server's tools with {"type": "fastmcp", "server": ..., "allowed_tools": [...]} toolkit 0.5.1

A stdio server only sees the environment you pass it. The MCP SDK starts a stdio server with a short allow-list of variables (PATH, TEMP, USERPROFILE and a few others). Pass every DPTTOOLS_* variable and API key you use in the session's env, or the server falls back to its defaults — for example ./.agent_skills for skills — and has no keys.

Known toolkit issue: skills auto-injection (toolkit 0.5.2 and earlier)

In toolkit 0.5.2 and earlier, skills auto-injection works only through a pre-built session. The other two routes return an empty catalog, and the toolkit then also hides the activation tools, so the agent never learns about your skills. The only trace is a WARNING in the toolkit's log.

Route What happens
In-process, Agent(tools=[skills_server]) The toolkit calls list_skills with a skills_dir argument the tool has never taken, then misreads the result. Empty catalog
mcp_command or mcp_script config The toolkit passes the server no environment, so it never sees DPTTOOLS_SKILLS_DIR. Empty catalog
Pre-built session whose server was started with env Works

This is a toolkit issue, not a std-tools one; the fixes are planned on the toolkit side. Until a toolkit release fixes it, start the server yourself and hand the toolkit the session:

import os
import sys

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import get_default_environment, stdio_client
from doc_processing_toolkit import Agent

env = get_default_environment()
env.update({k: v for k, v in os.environ.items() if k.startswith("DPTTOOLS_")})
env["LLMWHISPERER_API_KEY"] = os.environ.get("LLMWHISPERER_API_KEY", "")  # if you use OCR

params = StdioServerParameters(
    command=sys.executable, args=["-m", "doc_processing_std_tools"], env=env
)

async with stdio_client(params) as (read, write), ClientSession(read, write) as session:
    await session.initialize()
    agent = Agent(
        model="claude-sonnet-5",
        tools=[{"session": session, "name": "std-tools-skills"}],
    )
    result = await agent.run("Which skills do you have?")

Three details make this work:

  • The session's name contains skill, so the toolkit recognises it as a skills server.
  • env carries DPTTOOLS_SKILLS_DIR, so the server reads the right folder.
  • DPTTOOLS_SKILLS_DIR is also set in your application's own environment, pointing at a folder that exists there: the toolkit skips auto-injection otherwise.

A pre-built session belongs to the event loop that opened it, so use await agent.run(...) inside the async with block, not run_sync. Other in-process servers (file_system_server, memory_server and the rest) are not affected.

Versions and pinning

std-tools is installed from Git, and a tag is the version:

pip install "doc-processing-std-tools @ git+https://github.com/rzoeb/doc-processing-std-tools.git@v0.6.1"

Tags are v<version> and match version in pyproject.toml. A branch name is not a pin. A running deployment can report its version with doc_processing_std_tools.__version__ (new in 0.6.0), which is read from the installed package metadata. After upgrading, reinstall rather than relying on an editable install's metadata, and restart long-running processes, because configuration is read once per process.

See the Changelog for what each release changed.