Skip to content

Installation

gitea edited this page Aug 14, 2026 · 2 revisions

Installation

pp-mcp is a single Python process. It can run directly with python, or inside Docker. Files are always mounted/opened read-only — pp-mcp never writes to your .portfolio file.

Requirements

  • Python 3.11+ (matches the vendored protobuf-generated parser code)
  • Dependencies from requirements.txt: mcp, uvicorn, httpx, pydantic-settings, python-dotenv, protobuf>=6.31.1,<7, pycryptodome==3.20.0
  • One (or more) Portfolio Performance .portfolio file(s), optionally AES-encrypted (password-protected)

Running locally (without Docker)

pip install -r requirements.txt
export PP_FILE_PATH=/path/to/file.portfolio
# optional: export PP_PASSWORD=... ; export MCP_TRANSPORT=streamable-http
python -m src.main   # from the repo root!

Run it as a module (python -m src.main) from the repository root. Running python src/main.py directly fails with ModuleNotFoundError: No module named 'src', because the package needs to be importable as src.

By default the server listens on http://localhost:8080 using the streamable-http transport.

stdio mode (no resident server)

Set MCP_TRANSPORT=stdio and the server skips the HTTP layer entirely — no port, no bearer token, nothing to keep running in the background. Instead, the MCP client (e.g. Claude Desktop) launches pp-mcp itself as a subprocess for each session and talks MCP over stdin/stdout. This is the simplest option if you don't want an always-on process. See Configuring AI Tools for client-side config examples.

Running with Docker (recommended for always-on use)

Two Compose files cover the two typical deployment shapes:

File Scenario
docker-compose.dev.yml Simple local setup: a single .portfolio file, no auth required, no external Docker networks.
docker-compose.yml Production/multi-source (e.g. Synology NAS): a directory of .portfolio files + portfolios.json, MCP_AUTH_TOKEN required, port bound only to 127.0.0.1, external networks for a shared reverse proxy (e.g. nginx-proxy-manager) and other backend containers.
cp .env.example .env      # adjust for the compose file you're using
docker-compose -f docker-compose.dev.yml up -d --build   # local, single-source
# or
docker-compose up -d --build                              # production, multi-source

The container always exposes port 8080 internally; MCP_SERVER_PORT controls the host-side port mapping. Both compose files explicitly set MCP_SERVER_HOST=0.0.0.0 inside the container — required so the port mapping (and, in the production file, the nginx network) can actually reach the process. This does not weaken the app's own default (127.0.0.1, see below); it's the standard "bind to all interfaces inside an isolated container" pattern.

Files are mounted :ro (read-only) into the container in both variants.

Single-source vs. multi-source configuration

Single-source (default): one instance serves exactly one file, configured via PP_FILE_PATH (+ optional PP_PASSWORD). All tools accept source as an optional parameter, but it can be omitted — there's nothing to disambiguate.

Multi-source: set PP_PORTFOLIOS_CONFIG to the path of a JSON file listing multiple sources (this takes precedence over PP_FILE_PATH/PP_PASSWORD, which are then ignored). Each entry needs an id, label, path, and optional password:

[
  {"id": "example1", "label": "Example1", "path": "/data/portfolios/Example1.portfolio", "password": null},
  {"id": "example2", "label": "Example2", "path": "/data/portfolios/Example2.portfolio", "password": null}
]

See portfolios.json.example in the repo. With multiple sources configured, tools require the source parameter (the id from this config) to know which file to use; list_data_sources returns the configured id + label pairs (never paths or passwords) so a client can look them up. Each source keeps its own independent mtime-based cache.

Verifying the installation

  • Call the ping tool — it should return "pong".
  • A TCP healthcheck on port 8080 is enough to confirm the process is up (both Compose files already define one via healthcheck:).

Configuration reference (environment variables)

Variable Default Meaning
PP_FILE_PATH Path to the .portfolio file (single-source fallback; /data/portfolio.portfolio inside the container). Ignored if PP_PORTFOLIOS_CONFIG is set.
PP_PASSWORD empty Password for an encrypted file (single-source).
PP_PORTFOLIOS_CONFIG empty Path to the multi-source JSON config. Takes precedence over PP_FILE_PATH/PP_PASSWORD.
MCP_TRANSPORT streamable-http streamable-http, sse, or stdio (no resident HTTP server).
MCP_SERVER_HOST 127.0.0.1 Interface HTTP transports bind to (unused for stdio). Least-exposure default for local/non-Docker runs; both Compose files override it to 0.0.0.0 since the container needs it to be reachable via the port mapping. For non-Docker use, only raise this to 0.0.0.0 if you actually need LAN reachability — and set MCP_AUTH_TOKEN if you do.
MCP_SERVER_PORT 8080 Listening port for HTTP transports (unused for stdio).
MCP_AUTH_TOKEN empty Optional bearer token; empty = no auth. Required as soon as the server is reachable outside a trusted local network.
MCP_REQUIRE_AUTH false For HTTP transports, the server refuses to start if this is true and MCP_AUTH_TOKEN is empty. Set true in production (already set in docker-compose.yml); ignored for stdio.

Running as a background service (optional)

For an always-on local setup without Docker, pp-mcp can be wrapped in an OS-level service manager (e.g. launchd on macOS with KeepAlive=true). This is an environment-specific detail rather than part of core installation — see the repo's switch-portfolio.sh for an example of restarting such a service after switching the active .portfolio file.


← Introduction · Configuring AI Tools →