Skip to main content

prmcp

Watch any Python SDK, auto-synthesize FastMCP tools for new resources, validate each generated tool with an LLM, and open a PR on the target MCP repo.

prmcp is a self-contained pipeline. Give it four things — an LLM API key, a GitHub PAT, the SDK repo to watch, and the MCP repo to PR into — and it handles everything else: AST-walking the SDK, diffing against a snapshot, rendering FastMCP tool wrappers, calling an LLM to validate them, and opening PRs.


Install

pip install prmcp

Or from source:

git clone <this-repo>
cd <this-repo>
pip install -e .

Requirements: Python 3.11+, git on PATH (for cloning remote SDKs), and gh CLI on PATH if you enable the optional GitHub Actions watcher.

Quickstart

In a fresh directory:

prmcp init

You'll be prompted for four values:

Prompt Example
OpenAI API key sk-…
GitHub PAT (scopes: repo) ghp_…
SDK source a local path like ./my-sdk or an owner/repo slug to clone
MCP target repo myorg/my-mcp

prmcp init writes:

  • prmcp.toml — the project config (committed; see template below)
  • .env — OPENAI_API_KEY + PAT_TOKEN (added to .gitignore)
  • .prmcp/ — workspace dir for the cloned SDK and the snapshot baseline (gitignored)

It auto-detects the resource directory and base classes by sampling the SDK, and lets you confirm or edit each value.

Once initialized:

prmcp up         # watcher in the foreground; Ctrl-C to stop
prmcp run        # one-shot pass
prmcp tail       # colored terminal view of the trace JSONL

The first prmcp run seeds .prmcp/sdk-snapshot.json as the baseline. Subsequent runs diff against it — any new (resource, method) pair triggers the render → validate → PR pipeline. prmcp run --reseed resets the baseline to the current SDK state.

How it works

SDK source                                MCP target repo
   │                                          ▲
   │ file change                              │ PR opens
   ▼                                          │
prmcp.daemon  →  prmcp.run orchestrator       │
                   │                          │
                   ├─ diff_sdk     (AST walk)
                   ├─ synth_tool   (Jinja2 render)
                   ├─ shadow_agent (OpenAI function-calling: valid|invalid)
                   └─ open_pr      (PyGithub) ┘

                 every step → /tmp/prmcp-trace.jsonl
                              (tailed by `prmcp tail`)

prmcp.toml reference

[sdk]
# Local path OR "owner/repo" GitHub slug (cloned into .prmcp/sdk-source/)
source = "stripe/stripe-python"

# Glob (relative to the resolved SDK root) for the resource modules
resources_glob = "stripe/api_resources/*.py"

# Class names that mark "this is a resource". Empty list ⇒ every public
# class with public methods is treated as a resource.
resource_base_classes = ["APIResource", "ListableAPIResource"]

# Python import name of the SDK package (used inside generated tools)
import_module = "stripe"

# The expression that builds a client inside each generated tool
client_expression = "stripe"

# Exception class to catch around each SDK call
exception_class = "stripe.error.StripeError"

# Optional: file inside the SDK whose Client.__init__ assigns each resource
# class to a `self.<attr>` — used to translate ClassName → client attribute.
# client_path = "stripe/stripe_client.py"

[mcp]
target_repo = "myorg/my-mcp"
base_branch = "main"
tool_dir    = "tools"

[llm]
model = "gpt-4o-mini"
# base_url = "https://api.openai.com/v1"   # set for OpenAI-compatible endpoints

[ci]
# watched_repo = "owner/repo"               # optional: enable the CI watcher
workflow = "prmcp.yml"
poll_interval_seconds = 30

[daemon]
poll_interval_seconds = 2.0
debounce_seconds      = 3.0

[pipeline]
trace_path = "/tmp/prmcp-trace.jsonl"
dry_run    = true

dry_run = true (default) prints the PR that would be opened without touching GitHub. Flip to false when you're ready for live PRs.

Console scripts

Command What it does
prmcp init Interactive bootstrap of prmcp.toml + .env. Auto-detects SDK conventions.
prmcp up Daemon + (optional) CI watcher in one process. Ctrl-C tears all down.
prmcp run Single pipeline pass. --reseed resets the snapshot baseline.
prmcp daemon SDK file watcher only.
prmcp ci-watcher GitHub-Actions → local-trace bridge only. Requires [ci] watched_repo.
prmcp tail Real-time terminal view of the trace JSONL. ANSI-colored, groups runs by 30s gaps.

Environment variables

Variable Purpose
OPENAI_API_KEY Required. Used by the shadow validator.
PAT_TOKEN Required for live PR mode. Personal access token with repo scope.
PRMCP_DRY_RUN Overrides [pipeline] dry_run (1/0).
PRMCP_TRACE_PATH Overrides [pipeline] trace_path.
PRMCP_LOG_LEVEL Python logging level (default INFO).
PRMCP_INJECT_429 1 → simulate a single 429 from the LLM to exercise the retry path.

Layout

your-project/
├── prmcp.toml          # config, committed
├── .env                # secrets, gitignored
└── .prmcp/             # gitignored
    ├── sdk-source/     # cloned SDK (if `source` was a GitHub slug)
    ├── sdk-snapshot.json
    └── ci-watcher.state

License

MIT.

Metadata

Release files for prmcp 0.1.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 prmcp 0.1.0
File Size Uploaded Provenance
prmcp-0.1.0.tar.gz 34.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for prmcp 0.1.0
File Interpreter ABI Platform
prmcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 73.5 kB

Release files / prmcp-0.1.0.tar.gz

Download URL prmcp-0.1.0.tar.gz
Size 34.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f7a44a4919c2fa7d3ea75daf5a1774ffcf7caa7b784fcfcf939ef613e722e680
BLAKE2b-256 checksum
How to use checksums
46c8d4211589df4242fc676f56a10ac35187de9fff9f82d80b0cf12115a1445b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / prmcp-0.1.0-py3-none-any.whl

Download URL prmcp-0.1.0-py3-none-any.whl
Size 39.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d056818ba50521f248f5c9c7500830a2a153c0b7e120299f1844c268ef858e42
BLAKE2b-256 checksum
How to use checksums
55fb0367b368abf0793efbffd69b4f87ff9c1103b5b950d262f1a75f106db4dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Security for prmcp 0.1.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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