Recipe: The Launcher with Other MCP Clients¶
Goal¶
Register the composed launcher, python -m doc_processing_std_tools, with MCP clients other than
the toolkit: a desktop assistant, an IDE, or your own code using an MCP SDK. Pass it the
configuration it needs, and check the connection.
Prerequisites¶
-
std-tools installed with the extras you need, in its own virtual environment, so the client runs a known interpreter:
python -m venv /opt/std-tools /opt/std-tools/bin/pip install "doc-processing-std-tools[all] @ git+https://github.com/rzoeb/doc-processing-std-tools.git@v0.6.1"On Windows the interpreter is
C:\opt\std-tools\Scripts\python.exe. -
Any software the tools use, installed where the server runs: LibreOffice for Office conversion, and Chromium (
playwright install chromium) if you enable the browser.
Steps¶
1. Decide what the server needs¶
A client starts a stdio server with only the environment you give it. Most clients pass a short
allow-list such as PATH and HOME, and nothing from your shell. So write every setting into the
client's configuration:
| Setting | Why |
|---|---|
DPTTOOLS_MEMORY_DIR, DPTTOOLS_SKILLS_DIR |
Their defaults are relative (./agent_memory, ./.agent_skills), and a client chooses the working directory. Use absolute paths |
DPTTOOLS_WEB_SEARCH_PROVIDER, DPTTOOLS_WEB_SEARCH_API_KEY |
web_search returns an error without them |
LLMWHISPERER_API_KEY |
For ocr_pdf and ocr_image |
DPTTOOLS_ENABLE_BROWSER, DPTTOOLS_ENABLE_COMPUTER |
Only if you want the optional servers |
The file tools also resolve a relative path against the server's working directory. Give absolute
paths in prompts, or use a client that lets you set the working directory (cwd).
Configuration lists every variable.
2. Register it with the client¶
JSON configuration with mcpServers (Claude Desktop's claude_desktop_config.json, and many
other clients):
{
"mcpServers": {
"std-tools": {
"command": "/opt/std-tools/bin/python",
"args": ["-m", "doc_processing_std_tools"],
"env": {
"DPTTOOLS_MEMORY_DIR": "/home/me/agent/memory",
"DPTTOOLS_SKILLS_DIR": "/home/me/agent/skills",
"DPTTOOLS_WEB_SEARCH_PROVIDER": "tavily",
"DPTTOOLS_WEB_SEARCH_API_KEY": "tvly-xxx"
}
}
}
}
In JSON on Windows, write paths with forward slashes (C:/opt/std-tools/Scripts/python.exe) or
doubled backslashes.
Claude Code, from the command line:
claude mcp add std-tools \
-e DPTTOOLS_MEMORY_DIR=/home/me/agent/memory \
-e DPTTOOLS_WEB_SEARCH_PROVIDER=tavily -e DPTTOOLS_WEB_SEARCH_API_KEY=tvly-xxx \
-- /opt/std-tools/bin/python -m doc_processing_std_tools
VS Code (.vscode/mcp.json) can prompt for a key instead of storing it in the file, and can
set the working directory:
{
"inputs": [
{"type": "promptString", "id": "tavily-key", "description": "Tavily API key", "password": true}
],
"servers": {
"std-tools": {
"type": "stdio",
"command": "/opt/std-tools/bin/python",
"args": ["-m", "doc_processing_std_tools"],
"cwd": "${workspaceFolder}",
"env": {
"DPTTOOLS_WEB_SEARCH_PROVIDER": "tavily",
"DPTTOOLS_WEB_SEARCH_API_KEY": "${input:tavily-key}"
}
}
}
}
Each client's own documentation has the details: where its file lives, and how it handles secrets.
3. Or serve it over HTTP¶
For a client that connects to a URL, or several clients sharing one server, run the launcher with streamable HTTP. It reads its configuration from its own environment, since no client passes one:
export DPTTOOLS_MEMORY_DIR=/home/me/agent/memory
python -m doc_processing_std_tools --transport http --port 8000
The endpoint is http://127.0.0.1:8000/mcp. For Claude Code:
claude mcp add --transport http std-tools http://127.0.0.1:8000/mcp.
The HTTP transport has no authentication
It binds to 127.0.0.1 by default. Anyone who can reach the port can run every tool, including
execute_command. Bind another interface (--host 0.0.0.0) only behind an authenticating proxy
or a network policy (Architecture).
4. Check the connection¶
The launcher checks its settings before serving. A bad value stops it with a message naming the variable, which the client shows as a server that failed to start:
doc-processing-std-tools failed to start: ConfigError: DPTTOOLS_SANDBOX_TIMEOUT must be an integer (got 'soon').
Once it is connected, the client should list 56 tools, or 75 with the browser, 73 with the computer server and 92 with both. A short script with the MCP Python SDK checks the same thing without a client:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import get_default_environment, stdio_client
async def main():
env = get_default_environment()
env["DPTTOOLS_MEMORY_DIR"] = "/home/me/agent/memory"
params = StdioServerParameters(
command="/opt/std-tools/bin/python", args=["-m", "doc_processing_std_tools"], env=env
)
async with stdio_client(params) as (read, write), ClientSession(read, write) as session:
await session.initialize()
print(len((await session.list_tools()).tools)) # 56
result = await session.call_tool("write_memory", {"key": "report-folder",
"value": "Reports go to /finance."})
print(result.content[0].text) # Memory key 'report-folder' saved.
asyncio.run(main())
For HTTP, use streamablehttp_client("http://127.0.0.1:8000/mcp") from mcp.client.streamable_http
in the same way. The MCP Inspector (npx @modelcontextprotocol/inspector) does the same check
interactively.
5. Keep the tool list small¶
56 tool descriptions cost tokens on every turn, and some clients limit how many tools they show. To serve fewer tools, run one server on its own:
python -m doc_processing_std_tools.document_processing # the 13 Documents tools
python -m doc_processing_std_tools.file_system
A server run this way skips the launcher's start-up check, so a bad setting shows up as an Error:
from the first tool that reads it. Many clients can also hide tools you don't use.
What to validate¶
- The client lists 56 tools (more with the optional servers), with names unchanged and not prefixed.
- A memory written through one connection is in
DPTTOOLS_MEMORY_DIR, at the absolute path you set. web_searchworks; without the provider settings in the client'senv, it returns anError:naming them.- A bad setting stops the launcher with a message naming the variable.
- Over HTTP, the server answers at
/mcpon127.0.0.1only.
Test sources¶
tests/integration/test_multi_server_launcher.py: composition, the 56-tool count, no duplicate names, a call through each server, settings passed through.tests/unit/test_launcher_offload.py: blocking tools run on worker threads in the launcher.tests/integration/test_toolkit_compat.py: a stdio session started withenv, as in step 4.
Related pages¶
- Quickstart: the launcher's options.
- Architecture: how the launcher composes the servers.
- Using with the Toolkit:
the same
envrule, for toolkit agents.