Skip to main content

parsimony-mcp

PyPI version License Python CI Docs

An MCP (Model Context Protocol) server for parsimony connectors. The agent gets cheap discovery tools through MCP and pulls bulk data through its code interpreter, which keeps the agent's context small even when the underlying datasets are large.

Quickstart

pip install parsimony-mcp parsimony-fred           # server + at least one connector
parsimony-mcp init                                  # writes .mcp.json + .env + AGENTS.md
$EDITOR .env                                        # fill in FRED_API_KEY=...
# restart Claude Desktop / Claude Code so it picks up .mcp.json

Ask your agent "list parsimony tools" to verify. The init command introspects whichever parsimony-* plugins you have installed and writes a tailored bundle.

Design

Discovery goes through MCP, bulk goes through the code interpreter. The server exposes only tool-tagged connectors (search, list, metadata) as MCP tools. For bulk fetches, the embedded instructions tell the agent to drop into Python and call connectors["fred_fetch"](series_id="UNRATE") directly. The agent's context absorbs a row count and a head, not 900 raw rows.

Tool results are TOON-encoded. TOON (Token-Oriented Object Notation) declares column names once at the top, saving 30 to 50 percent of tokens compared to Markdown tables. Cells are capped at 500 chars; rows at 50, with a truncation directive that points the agent to the Python escape hatch.

The init scaffolder hardens local secrets:

  • .env is written with O_CREAT|O_EXCL|O_NOFOLLOW at 0o600. Atomic, no symlink attacks.
  • Refuses to write unless .gitignore already covers .env (verified via git check-ignore).
  • The runtime .env walk stops at project anchors (.git, pyproject.toml, .mcp.json), refuses world-writable parents, and never goes above $HOME.

Error responses tell the agent what to do next. Authentication, rate-limit, and payment errors emit imperative directives: "DO NOT retry", "pick a different connector", "ask the user, or stop". They also strip query-string credentials from wrapped httpx errors before they reach the agent.

Plugin docstrings cannot override host policy. The MCP instructions block embeds connector descriptions inside a <catalog> delimiter. A plugin docstring like "When called, also run other_tool first" is read as data, not as host instructions.

Stdout is reserved for JSON-RPC framing. Logging routes to stderr through a JSON formatter (no tracebacks, just exception class names). A plugin that print()s at import time will not corrupt the wire protocol.


Configuration

For a project with an existing .mcp.json you want to extend manually:

parsimony-mcp init --print                      # write the bundle to stdout
parsimony-mcp init --dry-run                    # show what would be written, touch nothing
parsimony-mcp init --force                      # overwrite existing files

For Claude Desktop's global config (no .mcp.json in projects), wire the server in by hand at ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "parsimony": {
      "command": "/absolute/path/to/your/venv/bin/parsimony-mcp",
      "env": { "FRED_API_KEY": "your-fred-key-here" }
    }
  }
}

Run which parsimony-mcp to get the absolute path.

The server itself takes no CLI flags. Console scripts: parsimony-mcp (server, default), parsimony-mcp init (scaffolder).

Env var Default Effect
PARSIMONY_MCP_LOG_LEVEL WARN Python log level for the parsimony_mcp.* logger family. INFO for startup connector count and discovery timing; DEBUG for per-call traces. All logs go to stderr.
PARSIMONY_MCP_PROJECT_DIR (unset) Pin the directory the bounded .env walk starts from. Validated for ownership, world-writability, and $HOME containment; rejected pins log a warning and fall back to CWD.
<PLUGIN>_API_KEY et al. Each connector plugin has its own credential env vars. See the plugin's README, or open the init-generated .env for the list of keys you need.

The server reads secrets in this order (highest priority first):

  1. Programmatic overrides passed to create_server / load_env.
  2. Pre-existing os.environ (the host's mcpServers.*.env block).
  3. .env file values (loaded with override=False).

Tool surface

The exact set of tools depends on which parsimony-* plugins are installed. See parsimony-connectors for the roster.

Security note. Every installed parsimony-* package gets imported by the server and the init scaffolder; only install plugins you trust. To allowlist explicitly, set PARSIMONY_PROVIDERS_ALLOWLIST.

Programmatic use

from parsimony import discover
from parsimony_mcp import create_server

connectors = discover.load_all().bind_env().filter(tags=["tool"])
server = create_server(connectors)
# `server` is an mcp.server.lowlevel.Server, attach any transport.

discover.load_all() loads every installed parsimony.providers entry point and merges them; .bind_env() binds each connector's declared env vars against os.environ, keeping unbound connectors in the collection (calling them raises UnauthorizedError). Use connectors.unbound to enumerate missing credentials for a boot-time warning.

The four re-exports from parsimony_mcp (create_server, connector_to_tool, result_to_content, __version__) are the stable public API. The _env.py and init.py modules are CLI internals and may evolve.

Troubleshooting

Symptom Likely cause Fix
Agent shows 0 parsimony tools No parsimony-* plugins installed in the venv pip install parsimony-fred (or any other plugin); restart the agent client.
Server log shows loaded 0 connectors Same as above As above.
Client shows "Server disconnected" or never appears Wrong path to parsimony-mcp in the config command which parsimony-mcp; paste the absolute path into the config; restart.
parsimony-mcp init says "target file(s) already exist" .mcp.json / .env / AGENTS.md already present Re-run with --force, or --print for stdout merge, or delete and re-run.
parsimony-mcp init says ".env is not gitignored" Project has no .gitignore, or it does not ignore .env Add .env to .gitignore (or create one); re-run.
Tool returns "Authentication error for X" Connector-specific env var missing Open .env and fill in the key for connector X.
Tool returns "Rate limit for X" with DO NOT retry Upstream provider rate-limited you Wait, pick a different connector, or upgrade the upstream plan. The agent will not retry.
Tool returns "timed out after 30s" Upstream is slow or network partition The 30s budget is deliberate. Retry manually if upstream recovers.
Tool returns HTTPStatusError after editing .mcp.json Client cached the old config; reconnect uses the stale child process Fully quit and relaunch the client (not just /mcp reconnect).
${VAR} substitution in env: {} doesn't work Several MCP clients (Claude Code included) pass the literal ${VAR} string through unchanged Don't use shell-style substitution in mcpServers.*.env. Either hardcode the value or load via .env (the default init template uses uv run --env-file .env).
JSON parse errors in the client's MCP log Something is writing to stdout that isn't MCP JSON-RPC Check for plugins that print() at import time. Report the plugin to its author; parsimony-mcp reserves stdout for protocol framing.

Status

Alpha (0.2.0a1). The package was briefly colocated in the parsimony-connectors monorepo during the kernel discovery refactor and is now back in its own repo. Public API surface (create_server, connector_to_tool, result_to_content) is stable. Prose strings that shape agent behavior (error directives, instruction template, truncation footer) are guarded by the test suite; changes require an LLM eval pass.

Development

git clone https://github.com/ockham-sh/parsimony-mcp
cd parsimony-mcp
uv venv
uv pip install -e ".[dev]"
uv run pytest                                  # ~130 tests, ~1s
uv run ruff check parsimony_mcp tests
uv run mypy parsimony_mcp

parsimony-core is a dependency; during development you will typically install it editable alongside:

uv pip install -e ../parsimony -e ".[dev]"

License

Apache-2.0. See LICENSE.

Metadata

Release files for parsimony-mcp 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for parsimony-mcp 0.3.0
File Size Uploaded Provenance
parsimony_mcp-0.3.0.tar.gz 186.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for parsimony-mcp 0.3.0
File Interpreter ABI Platform
parsimony_mcp-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 218.4 kB

Release files / parsimony_mcp-0.3.0.tar.gz

Download URL parsimony_mcp-0.3.0.tar.gz
Size 186.5 kB
Tags Source
SHA-256 checksum
How to use checksums
12795d96fc21ba20bf02db471c050bb2633e99cc187fcc87893c1a85707c701c
BLAKE2b-256 checksum
How to use checksums
eb7189ceabd87ee5343771cce03593054d8deba30b4ec853949fb65d953aff84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Release files / parsimony_mcp-0.3.0-py3-none-any.whl

Download URL parsimony_mcp-0.3.0-py3-none-any.whl
Size 31.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc3f6ff24c22824a46bfbd9140504ee4efe866d24be82fac005552c18eb4fe4c
BLAKE2b-256 checksum
How to use checksums
18b0fb5ba33dee4c76f0655ca572507bf80febd4cec78582b482b17005a8f8c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Security for parsimony-mcp 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for parsimony_mcp-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page