PBPK MCP Server

CI DOI License Release Python

Part of ToxMCP Suite → https://github.com/ToxMCP/toxmcp

Public MCP endpoint for physiologically based pharmacokinetic (PBPK) simulation, qualification, and dossier export.
Expose PK-Sim / MoBi .pkml, MCP-ready rxode2 .R, deterministic and population runs, and OECD-oriented validation/reporting to any MCP-aware agent (Codex CLI, Gemini CLI, Claude Code, etc.).

Architecture

flowchart LR
    subgraph Clients["Clients and Agents"]
        Codex["Codex CLI / Desktop"]
        Gemini["Gemini CLI"]
        Claude["Claude Code"]
        Scripts["Scripts / notebooks"]
    end

    subgraph API["FastAPI MCP Service"]
        Router["HTTP entrypoints\n/health and /mcp"]
        Registry["Tool registry\npbpk-mcp.v1 contracts"]
        Tools["Tool handlers\ndiscovery, validation,\nexecution, reporting"]
    end

    subgraph Contracts["Discovery and Qualification Layer"]
        Catalog["Filesystem model catalog\nADAPTER_MODEL_PATHS"]
        Manifest["Static manifest validation\nvalidate_model_manifest"]
        Qualification["Qualification metadata\ncapabilities, profile,\nvalidation, qualificationState"]
        Verification["Executable verification\nrun_verification_checks"]
        Reports["OECD dossier export\nexport_oecd_report"]
    end

    subgraph Backends["Execution Backends"]
        OSPSuite["OSPSuite backend\nPK-Sim / MoBi (.pkml)"]
        Rxode2["rxode2 backend\nMCP-ready R (.R)"]
        Convert["Conversion-only inputs\n.pksim5 and .mmd -> .pkml or .R"]
    end

    subgraph Runtime["Runtime and QA Path"]
        Jobs["Celery + Redis jobs\nasync runs and result handles"]
        Overlay["Source-overlay runtime\nbind mounts + worker image"]
        Tests["Unit + live smoke tests\nrelease readiness checks"]
    end

    Clients --> Router
    Router --> Registry
    Registry --> Tools
    Tools --> Catalog
    Tools --> Manifest
    Tools --> Qualification
    Qualification --> Verification
    Qualification --> Reports
    Tools --> OSPSuite
    Tools --> Rxode2
    Convert --> OSPSuite
    Convert --> Rxode2
    Tools --> Jobs
    Overlay --> Tools
    Qualification --> Tests
    Overlay --> Tests

The current implementation follows a layered model:

  • FastAPI + JSON-RPC expose /mcp and /health, and keep transport concerns separate from PBPK model logic.
  • Tool handlers are the agent-facing API. They validate inputs, call adapters, and emit structured responses with normalized pbpk-mcp.v1 payloads.
  • Discovery and manifest validation make model files visible before load, and keep curation checks separate from runtime execution.
  • Execution backends route .pkml files to ospsuite and MCP-ready .R modules to rxode2, while treating .pksim5 and .mmd as conversion-only inputs.
  • Qualification metadata keeps capabilities, profile, validation, and qualificationState separate so runnable does not get conflated with scientifically qualified.
  • Executable verification adds lightweight but structured runtime checks on top of qualification metadata, including parameter-unit consistency, structural flow/volume consistency, deterministic smoke, result-integrity, and repeat-run reproducibility checks without conflating them with formal qualification evidence.
  • Packaged-default runtime + overlay smoke tests keep the documented tool surface synchronized with the live API while still leaving an explicit maintainer override path for workspace iteration.
  • Release metadata checks now verify that package version markers, compose/env SERVICE_VERSION, README release markers, the top changelog entry, and the matching docs/releases/ note stay aligned.
  • Release artifact evidence now retains a machine-readable report with sdist/wheel hashes and the linked contract-manifest identity during tag builds.

See docs/architecture/dual_backend_pbpk_mcp.md for the fuller architecture narrative, docs/architecture/capability_matrix.md for the published support matrix, docs/architecture/mcp_payload_conventions.md for the response contract, docs/deployment/runtime_patch_flow.md for the operator path behind the current local deployment model, and docs/pbpk_model_onboarding_checklist.md for the recommended trust pipeline when onboarding another chemical model. See docs/architecture/exposure_led_ngra_role.md for the explicit boundary statement on what PBPK MCP does and does not own inside exposure-led NGRA workflows. See docs/architecture/toxmcp_suite_index.md for the shortest cross-service routing guide inside the ToxMCP suite. See benchmarks/regulatory_goldset/regulatory_goldset_summary.md for the current gold-set documentation benchmark summary derived from the fetched public-code PBPK corpus. Internal examples such as the bundled synthetic reference model remain bounded MCP rehearsal models, not benchmark exemplars.

What's new in v0.5.0

  • Enforced single-use replay rejection for bearer tokens that carry jti claims, so repeated presentation of the same token identifier is now treated as an auth failure instead of silently succeeding.
  • Upgraded /mcp to the MCP 2025-11-25 JSON-RPC behavior, including clean success/error response shapes, standard tool schemas, structured tool results, and standard MCP resources exposed through pbpk:// URIs.
  • Moved canonical PBPK tool modules to mcp_bridge.pbpk_tools while keeping a temporary deprecated mcp.* compatibility shim for existing internal scripts.
  • Aligned REST and MCP parameter writes on one governance path, so snapshots, audit-backed sweep detection, and the returned governance payload now behave consistently across both transports.
  • Fixed set_parameter_value(updateMode="relative") so relative deltas are applied against the current parameter value before validation, audit, and persistence.
  • Completed the v0.5.0 release alignment across package metadata, compose/runtime version markers, the README, and the dedicated release-note entry, while moving the remaining legacy env-alias removal target to v0.6.0.

Why this project exists

PBPK workflows often juggle PK-Sim or MoBi transfer files, R-authored mechanistic models, runtime-specific scripts, and incomplete qualification notes. That makes them difficult for coding agents to automate safely and difficult for reviewers to inspect consistently.

The PBPK MCP server wraps those workflows in a single, programmable interface:

  • Unified MCP surface – discovery, manifest checks, load, validation, execution, results, and dossier export share one tool catalog.
  • Dual-backend execution.pkml models run on ospsuite; MCP-ready .R models run on rxode2.
  • Qualification-aware workflows – runtime capability, scientific profile, preflight validation, and derived qualificationState stay separate.
  • NGRA-ready PBPK objects – validation and dossier export expose PBPK-side typed objects such as assessmentContext, pbpkQualificationSummary, uncertaintySummary, uncertaintyHandoff, internalExposureEstimate, a typed external uncertainty-register reference, and a typed external PoD reference handoff, now with explicit boundary/support metadata plus additive semanticCoverage for PBPK-side uncertainty semantics, without collapsing PBPK MCP into a full decision engine.
  • Exposure-led boundary clarityassessmentContext.workflowRole, assessmentContext.populationSupport, pbpkQualificationSummary.evidenceBasis, pbpkQualificationSummary.workflowClaimBoundaries, and pbpkQualificationSummary.reviewStatus now make IVIVE/exposure dependencies, supported population contexts, no-direct-in-vivo status, reviewer-attention requirements, and claim boundaries explicit.
  • Static curation feedback for NGRA gapsvalidate_model_manifest now exposes manifest.ngraCoverage plus a compact curationSummary, so missing workflow-role, population-support, evidence-basis, and claim-boundary declarations are visible before load in both machine-readable and reviewer-facing form; that summary now also carries an anti-misread block, explicit summary-transport risk for thin/forwarded views, a normalized cautionSummary with advisory-versus-blocking handling, a machine-readable exportBlockPolicy, and rendering guardrails for analyst-facing clients.
  • Regulatory benchmark bar – the workspace now also ships a gold-set benchmark dossier under benchmarks/regulatory_goldset/ plus an advisory curationSummary.regulatoryBenchmarkReadiness block, so MCP reviewers can compare a model dossier to public regulatory-grade PBPK packaging without promoting research models to regulatory-ready status. That advisory block now also carries per-dimension evaluation paths, benchmark examples, and concrete next-artifact guidance for closing documentation gaps.
  • Reviewer-friendly discovery summariesdiscover_models and /mcp/resources/models now surface manifestStatus, qualificationState, and a compact curationSummary so curated illustrative examples can be distinguished from exploratory or partially declared models at discovery time, with explicit anti-misread guidance and no official “bare label only” rendering path.
  • Human-review summary – OECD report export now includes a compact humanReviewSummary block that pulls those boundary fields into one reviewer-facing surface, including reviewer-status, unresolved-dissent context, normalized cautionSummary, summary-transport risk, exportBlockPolicy, and rendering guardrails, without creating a second hidden score or decision engine.
  • Anti-misread report section – OECD report export now also includes a mandatory misreadRiskSummary block so common over-interpretations are stated explicitly next to the primary report summary instead of being left implicit.
  • Audit-backed operator sign-off – trust-bearing outputs now surface an additive operatorReviewSignoff summary plus an explicit operatorReviewGovernance block derived from the real workflow contract, and the REST surface now exposes viewer-readable /review_signoff/history so recorded acknowledgement, bounded-use sign-off, rejection, and revocation remain auditable without being mistaken for a second qualification score, override path, or decision authority.
  • Explicit audit-storage boundary – the default local stack keeps reviewer-readable hash-chained audit history on the local filesystem, while stronger off-host immutability depends on the S3/Object-Lock backend and external retention discipline documented for operators.
  • Conservative PK/NCA output surfacecalculate_pk_parameters and the internal deterministic-result summaries now expose additive auc0Inf, lambdaZ, halfLife, extrapolated-AUC share, terminal-phase point counts, and screening-oriented ncaStatus/ncaWarnings, while clearance and volume distribution remain withheld unless explicit dose context is declared.
  • No bundled analyst UI in the current release – trust-bearing review remains on the MCP and REST surfaces for now; /console and /console/api/* are intentionally absent until a stronger reviewer-facing client exists.
  • Thin-client trust-surface contract – trust-bearing MCP tool results now also expose a top-level trustSurfaceContract so thin clients can find the nested summary surfaces, required adjacent caveats, and primary block reasons they must carry together instead of rediscovering those paths tool by tool.
  • Traceable predictive evidence – performance bundles can now carry traceability supplements, and the report path now warns when bundled benchmark rows do not actually line up with the declared datasets, target outputs, or acceptance criteria.
  • Objective performance-evidence metrics – observed-versus-predicted rows now retain additive objectiveEvidence metrics such as fold error, row-level RMSE, and simple acceptance-criterion evaluation when the criterion is machine-interpretable, without replacing the original evidence row semantics.
  • Reviewer-facing dossier improvement signals – verification and OECD report export now attach an advisory dossierImprovementSignals block sourced from the regulatory benchmark comparison so maintainers can see the highest-leverage dossier/documentation gaps without changing qualification state.
  • Discovery before execution – models are discoverable from disk before they are loaded into a live session.
  • Release-tested local deployment – the packaged local runtime and the explicit source-overlay maintainer profile are both exercised with unit tests, live-stack tests, and a readiness check.
  • Model-specific executable qualification checks – MCP-ready models can add runtime verification hooks for checks such as flow/volume consistency, mass balance, or numerical stability without overstating regulatory qualification.

rxode2 is a native PBPK execution engine in this project. It is not limited to Berkeley Madonna conversion workflows.


Feature snapshot

Capability Description
🧬 Dual-backend PBPK execution Route .pkml models to ospsuite and MCP-ready .R models to rxode2 through one MCP surface.
🗂️ Model discovery and curation Discover supported model files from ADAPTER_MODEL_PATHS, inspect unloaded models, and run static manifest checks before load.
🛡️ OECD-oriented qualification Keep capabilities, profile, validation, and qualificationState explicit; expose applicability, provenance, uncertainty, implementation verification, software-platform qualification, and qualification gaps.
🧱 NGRA-ready PBPK objects Emit typed PBPK-side objects such as assessmentContext, pbpkQualificationSummary, uncertaintySummary, uncertaintyHandoff, internalExposureEstimate, a typed uncertaintyRegisterReference, a typed pointOfDepartureReference, and a thin BER-ready reference bundle in dossier export, with explicit boundary/support flags plus additive uncertainty semanticCoverage for downstream NGRA orchestration and without embedding BER decision logic in PBPK MCP.
📐 Published object schemas Publish machine-readable JSON Schemas and example payloads for the PBPK-side NGRA handoff object family under schemas/ so downstream tooling can validate the public object layer directly.
🔌 External PBPK normalization Normalize externally generated PBPK outputs, qualification metadata, and optional PoD references through ingest_external_pbpk_bundle without pretending PBPK MCP executed the upstream engine.
Executable verification Run run_verification_checks to capture preflight validation, parameter coverage, parameter-unit consistency, structural flow/volume consistency, deterministic smoke, deterministic result integrity, repeat-run reproducibility, optional population smoke, and verification-evidence summaries in one payload.
📈 Deterministic and population jobs Submit asynchronous deterministic and population simulations, then retrieve result handles, stored results, and PK summaries.
🧾 Dossier export Export a structured OECD-style report with model metadata, validation context, checklist state, parameter provenance, performance evidence, uncertainty evidence, verification evidence, and software-platform qualification evidence when declared.
⚙️ Source-overlay deployment hygiene Recreate the local stack through the documented compose entrypoints and validate the live contract with readiness and smoke gates.
🤖 Agent friendly Verified through MCP HTTP surfaces such as /mcp/list_tools, /mcp/call_tool, and /mcp/resources/models, with live-stack regression checks.

Table of contents

  1. Architecture
  2. Published schemas
  3. Capability matrix
  4. Quick start
  5. Configuration
  6. Tool catalog
  7. Running the server
  8. Integrating with coding agents
  9. Output artifacts
  10. Security checklist
  11. Current limitations
  12. Development notes
  13. Contributing
  14. Security policy
  15. Code of conduct
  16. Citation
  17. Roadmap
  18. License

Quickstart TL;DR

# 1) build the worker image
git clone https://github.com/ToxMCP/pbpk-mcp.git
cd pbpk-mcp

# 2) start the local stack
./scripts/build_rxode2_worker_image.sh
./scripts/deploy_rxode2_stack.sh

# 3) verify
curl -s http://localhost:8000/health | jq .
curl -s http://localhost:8000/mcp/list_tools | jq '.tools[].name'

Published schemas

The PBPK-side NGRA handoff objects are now published as machine-readable JSON Schemas under schemas/, with matching examples under schemas/examples/.

Published object family:

  • schemas/assessmentContext.v1.json
  • schemas/pbpkQualificationSummary.v1.json
  • schemas/uncertaintySummary.v1.json
  • schemas/uncertaintyHandoff.v1.json
  • schemas/uncertaintyRegisterReference.v1.json
  • schemas/internalExposureEstimate.v1.json
  • schemas/pointOfDepartureReference.v1.json
  • schemas/berInputBundle.v1.json

Design intent:

  • require the stable core fields only
  • allow additive convenience fields
  • keep BER calculation and final decision policy outside PBPK MCP
  • keep exposure assessment, IVIVE policy, reverse dosimetry, and direct regulatory dose derivation outside PBPK MCP
  • make the PBPK-side handoff layer consumable by downstream validators and orchestrators without scraping examples out of tests

See schemas/README.md for the short schema guide and tests/test_ngra_object_schemas.py for the validation gate that keeps the published schemas aligned with live payload generation. The same schema family is also exposed through the live MCP resource surface at /mcp/resources/schemas. In the current local packaged runtime, the live schema/capability/contract-manifest resources treat the packaged mcp_bridge.contract content as authoritative rather than depending on copied JSON under /app/var/contract. scripts/check_installed_package_contract.py is the maintainer gate that proves the generated package fallback still matches the published JSON artifacts after a non-editable local install. When you explicitly opt into the workspace source-overlay profile, scripts/runtime_src_overlay.pth promotes /app/src ahead of the installed package.

PBPK MCP now also publishes a machine-readable contract manifest in:

  • docs/architecture/contract_manifest.json
  • /mcp/resources/contract-manifest

That manifest inventories the published PBPK-side schema family, the capability matrix, the legacy artifacts intentionally excluded from the PBPK-side object family, and the stable resource endpoints that expose the contract. The live schema, capability-matrix, and contract-manifest resources now also expose SHA-256 values so downstream clients can verify that the running API matches the published artifact inventory. The shared schema/capability/contract-manifest route logic now lives in packaged src/mcp_bridge/routes/resources_base.py, and packaged src/mcp_bridge/routes/resources.py now owns the full generic /mcp/resources surface including /mcp/resources/models. The same is now true for tools as well: packaged src/mcp_bridge/tools/registry_base.py and src/mcp_bridge/tools/registry.py now own the generic discovery/static-manifest/result/import descriptors alongside the rest of the documented PBPK workflow surface. The next 0.4.x debt-reduction slices are now live too: generic discovery, manifest, load/session-status, preflight validation, executable verification, dossier export, deterministic-result retrieval, external-import normalization, population workflow tools, the shared model_catalog / model_manifest helpers, the top-level mcp namespace, and the generic adapter contract/runtime now live in packaged src/. The default local runtime no longer needs a patch-copy step or a source overlay for code: the worker image bakes scripts/ospsuite_bridge.R and the bundled reference .R model into their runtime locations, docker-compose.celery.yml runs the packaged baseline, and docker-compose.overlay.yml is now the explicit maintainer profile when workspace src/ and scripts/ should override the image.

Capability matrix

PBPK MCP now publishes a dedicated capability matrix for adopters in:

  • docs/architecture/capability_matrix.md
  • docs/architecture/capability_matrix.json

The machine-readable matrix is also exposed from the running server at /mcp/resources/capability-matrix. For the cross-service routing view rather than the per-input capability boundary, read docs/architecture/toxmcp_suite_index.md.

This matrix is the crisp public answer to:

  • what is discoverable
  • what is statically validatable
  • what is loadable
  • what is deterministic-run capable
  • what is population-run capable
  • what is dossier-capable

Current headline boundaries:

  • .pkml is discoverable, loadable, validatable, verification-capable, deterministic-run capable, and dossier-capable through ospsuite
  • contract-complete MCP-ready .R is discoverable, loadable, validatable, verification-capable, deterministic-run capable, and dossier-capable through rxode2
  • population execution is currently rxode2-only and remains conditional on model capability
  • incomplete .R files may still be discoverable before they are runnable
  • .pksim5 and .mmd are conversion-only and do not appear as runtime-supported catalog entries

The machine-readable JSON file is intentionally small and stable so downstream tooling can consume it directly without scraping prose from the README.

scripts/generate_contract_artifacts.py --check is the maintainer gate that keeps the contract manifest and generated packaged fallback aligned with the published JSON artifacts.

Quick start

git clone https://github.com/ToxMCP/pbpk-mcp.git
cd pbpk-mcp

./scripts/build_rxode2_worker_image.sh
./scripts/deploy_rxode2_stack.sh

When you only need to refresh the packaged runtime image from the current workspace contents, without recompiling rxode2, use:

./scripts/refresh_rxode2_worker_image.sh

Heads-up: ./scripts/deploy_rxode2_stack.sh now runs the packaged local runtime by default and waits for stable /health and /mcp/list_tools responses before returning. The deploy helpers use a longer readiness window than before because the packaged import path is heavy on some machines. When you need workspace src/ and scripts/ to override the image for active development, use ./scripts/deploy_source_overlay_stack.sh.

Once the server is running:

  • HTTP MCP endpoint: http://localhost:8000/mcp
  • Health check: http://localhost:8000/health
  • Model discovery resource: http://localhost:8000/mcp/resources/models
  • Architecture docs: docs/architecture/dual_backend_pbpk_mcp.md
  • Runtime operator docs: docs/deployment/runtime_patch_flow.md
  • New-model trust pipeline: docs/pbpk_model_onboarding_checklist.md

Verification (smoke test)

Once the server is running:

# health
curl -s http://localhost:8000/health | jq .

# list MCP tools
curl -s http://localhost:8000/mcp/list_tools | jq .

# discover reference_compound
curl -s -X POST http://localhost:8000/mcp/call_tool \
  -H "Content-Type: application/json" \
  -d '{"tool":"discover_models","arguments":{"search":"reference_compound","limit":10}}' | jq .

# static manifest validation
curl -s -X POST http://localhost:8000/mcp/call_tool \
  -H "Content-Type: application/json" \
  -d '{"tool":"validate_model_manifest","arguments":{"filePath":"/app/var/models/rxode2/reference_compound/reference_compound_population_rxode2_model.R"}}' | jq .

For the full live-stack gate, run:

python3 scripts/release_readiness_check.py

That live readiness gate now also reruns the curated manifest publication check for the bundled synthetic reference model and pregnancy examples, and it fails if those examples regress to implicit NGRA workflow-role, population-support, evidence-basis, or claim-boundary declarations.

For the standalone static gate on that same curated publication set, run:

python3 scripts/validate_model_manifests.py --strict --require-explicit-ngra --curated-publication-set

To smoke-test the actual discovered model inventory in the current workspace, run:

python3 scripts/workspace_model_smoke.py --auth-dev-secret pbpk-local-dev-secret-32bytes-long
python3 scripts/workspace_model_smoke.py --include-population --auth-dev-secret pbpk-local-dev-secret-32bytes-long

The script discovers runtime-supported models through /mcp/resources/models, runs static manifest validation, loads each model, submits a deterministic simulation, retrieves stored results, and optionally runs a small population smoke for rxode2 models that declare population support. It writes a JSON report to var/workspace_model_smoke_report.json. On hardened local stacks, the load/run operations require operator or admin access, so pass --auth-dev-secret pbpk-local-dev-secret-32bytes-long for the default development profile or provide a real bearer token.

For the GitHub-hosted verification path, the repository also carries:

  • a lightweight CI workflow for patch/runtime contract checks on pushes and pull requests, now retaining a validated sdist, wheel, and runtime-contract report as artifacts
  • a heavier Model Smoke workflow that builds the Docker-backed stack, runs the live readiness gate, executes workspace_model_smoke.py --include-population --auth-dev-secret pbpk-local-dev-secret-32bytes-long, and uploads the resulting JSON reports as workflow artifacts

Configuration

The default local packaged stack is defined in docker-compose.celery.yml. An explicit source-overlay development profile is available in docker-compose.overlay.yml, and a stricter operator overlay is available in docker-compose.hardened.yml for deployments that should disable anonymous access and require explicit auth configuration. The source-overlay profile now bind-mounts src/, scripts/, docs/, schemas/, and var/ so the running server stays aligned with regenerated contract artifacts during release-prep. Key environment variables currently shaping the runtime are:

Variable Default Description
ADAPTER_MODEL_PATHS /app/var Filesystem roots scanned by discover_models and /mcp/resources/models.
ADAPTER_BACKEND subprocess Uses the R / OSPSuite subprocess bridge instead of an in-memory mock path.
JOB_BACKEND celery Enables asynchronous job submission through Redis-backed Celery workers.
CELERY_BROKER_URL redis://redis:6379/0 Queue broker for asynchronous jobs.
CELERY_RESULT_BACKEND redis://redis:6379/1 Result storage for job handles and async result chaining.
ADAPTER_R_PATH / ADAPTER_R_HOME container defaults Point the bridge to the R runtime used by rxode2 and OSPSuite tooling.
ADAPTER_TIMEOUT_MS 30000 Default adapter timeout in milliseconds.
AUDIT_ENABLED true in local compose Enables audit-backed sign-off, verification traceability, and readable history surfaces.
R_MAX_VSIZE 2G Caps R virtual memory use inside the current local worker setup.
DOTNET_GCHeapLimitPercent 60 Constrains the .NET heap used by the OSPSuite runtime.
PBPK_ENABLE_SRC_OVERLAY false Keeps /app/src out of import precedence by default; docker-compose.overlay.yml sets it to true for workspace-override development.
SERVICE_VERSION 0.5.0 Exposed through /health and compose-level runtime metadata.
AUTH_ALLOW_ANONYMOUS true Development-friendly local default; do not expose beyond localhost without hardening.
PBPK_BIND_HOST 127.0.0.1 Host/interface used by the hardened overlay when publishing the API port.
PBPK_BIND_PORT 8000 Host port used by the hardened overlay when publishing the API port.
AUTH_ISSUER_URL unset Required by the hardened overlay. OIDC issuer used for token validation.
AUTH_AUDIENCE unset Required by the hardened overlay. Audience expected in bearer tokens.
AUTH_JWKS_URL unset Required by the hardened overlay. JWKS endpoint used to validate bearer tokens.
AUTH_REPLAY_WINDOW_SECONDS 300 Rejects replay of already-seen jti token identifiers; callers must mint fresh jti-bearing tokens when this is enabled.
MCP_ALLOWED_ORIGINS unset Optional comma-separated allow-list for browser-originated MCP streamable HTTP requests. CLI clients without an Origin header remain valid.
MCP_STRICT_TRANSPORT false When true, requires MCP streamable HTTP Accept and MCP-Protocol-Version headers for hardened deployments.

For the default packaged local runtime, use docker-compose.celery.yml through ./scripts/deploy_rxode2_stack.sh. When you need workspace overrides, use ./scripts/deploy_source_overlay_stack.sh, which layers docker-compose.overlay.yml over the same local stack and enables /app/src precedence. For a more production-like local or operator-managed deployment, use ./scripts/deploy_hardened_stack.sh, which layers docker-compose.hardened.yml over the packaged local runtime, forwards the hardened auth plus optional S3/Object-Lock audit env contract, and waits for stable readiness before returning. For a local S3-compatible smoke run, ./scripts/deploy_s3_audit_smoke_stack.sh layers a MinIO-backed audit overlay over the same packaged runtime.

Legacy aliases such as R_PATH, R_HOME, R_LIBS, MCP_MODEL_SEARCH_PATHS, ADAPTER_TIMEOUT_SECONDS, and AUDIT_TRAIL_ENABLED are still accepted for compatibility, but startup now warns that they are scheduled for removal in v0.6.0.

See docker-compose.celery.yml, docker-compose.overlay.yml, docker-compose.hardened.yml, docker-compose.s3-audit-smoke.yml, docs/deployment/runtime_patch_flow.md, and docs/deployment/rxode2_worker_image.md for the current operator-facing deployment surface. For the current audit-storage guarantees and limits, see docs/hardening_migration_notes.md, docs/adr/0001-audit-storage-boundary.md, and docs/deployment/s3_object_lock_audit.md.


Tool catalog

Category Highlight tools Notes
Discovery and curation discover_models, validate_model_manifest, load_simulation Discover models before load, inspect static manifest state, and load supported .pkml or MCP-ready .R files into the live session registry.
Qualification and reporting validate_simulation_request, run_verification_checks, export_oecd_report, ingest_external_pbpk_bundle Run OECD-oriented preflight checks, executable verification with unit/integrity/reproducibility checks, structured dossier export with profile, validation, qualificationState, evidence sections, and a descriptive oecdCoverage map to OECD Tables 3.1/3.2, and normalize externally generated PBPK outputs into the same typed PBPK-side objects.
Simulation control list_parameters, get_parameter_value, set_parameter_value, run_simulation Inspect and modify simulation parameters, then submit deterministic runs asynchronously.
Async status and results get_job_status, get_results, calculate_pk_parameters, cancel_job Track async jobs, retrieve stored deterministic results, compute PK summaries, and cancel queued/running jobs.
Population and exploration run_population_simulation, get_population_results, run_sensitivity_analysis Run population workflows and sensitivity analyses on the backends that declare those capabilities.

The normalized pbpk-mcp.v1 contract currently applies to:

  • load_simulation
  • validate_model_manifest
  • validate_simulation_request
  • run_verification_checks
  • export_oecd_report
  • get_job_status
  • get_results

Example workflow

For the current public workflow:

  1. Call discover_models or inspect /mcp/resources/models.
  2. Call validate_model_manifest before loading a new model.
  3. Call load_simulation.
  4. Call validate_simulation_request for the intended context of use.
  5. Call run_verification_checks when you want a lightweight executable verification summary before broader use or release.
  6. Submit run_simulation or run_population_simulation.
  7. Poll get_job_status, then fetch get_results or get_population_results.
  8. Call export_oecd_report when you need a dossier/report package.

Supported model policy

Supported runtime inputs:

  • .pkml via ospsuite
  • MCP-ready .R via rxode2

Conversion-only inputs:

  • .pksim5 PK-Sim project files
  • Berkeley Madonna .mmd

Both conversion-only formats are rejected early with explicit guidance to export to .pkml or convert to an MCP-ready .R model.

Qualification model:

PBPK MCP keeps these concepts separate:

  • capabilities for operational/runtime support
  • profile for declared scientific metadata
  • validation for preflight applicability and guardrail assessment
  • qualificationState for the derived summary label
  • ngraObjects for PBPK-side typed NGRA-ready objects such as assessmentContext, pbpkQualificationSummary, uncertaintySummary, uncertaintyHandoff, internalExposureEstimate, and uncertaintyRegisterReference
    • uncertaintySummary now also carries additive semanticCoverage so downstream consumers can distinguish declared-only versus quantified PBPK-side variability, sensitivity, and residual uncertainty without inferring that from raw evidence rows alone; it now includes quantifiedRowCount, declaredOnlyRowCount, and a stricter variabilityQuantificationStatus
  • oecdCoverage for a descriptive mapping from exported dossier fields onto OECD reporting-template and evaluation-checklist sections; it does not modify oecdChecklistScore or qualification state

Current derived qualification states include:

  • exploratory
  • illustrative-example
  • research-use
  • regulatory-candidate
  • qualified-within-context

This is the core policy boundary for the server:

  • executable does not mean qualified
  • in-bounds does not mean suitable for regulatory use

For .R models, richer OECD-oriented reporting is enabled by hooks such as:

  • pbpk_model_profile()
  • pbpk_validate_request(...)
  • pbpk_parameter_table(...)
  • pbpk_performance_evidence(...)
  • pbpk_uncertainty_evidence(...)
  • pbpk_verification_evidence(...)
  • pbpk_run_verification_checks(...)
  • pbpk_platform_qualification_evidence(...)

For example, the reference_compound rxode2 model now exports bounded local sensitivity evidence and a compact variability-propagation summary through uncertaintyEvidence, using the currently loaded parameter state rather than a hard-coded placeholder row. Its performanceEvidence is also explicitly classified as runtime-only/internal evidence so executable smoke checks cannot be mistaken for predictive validation.

export_oecd_report now also adds oecdCoverage, an additive coverage map aligned to OECD PBK Guidance Tables 3.1 and 3.2. It is intentionally descriptive: it shows which dossier sections/questions are covered by the current report payload and which remain incomplete, but it does not alter oecdChecklistScore, qualificationState, or any downstream decision boundary.

Researchers can also attach generic companion performance bundles next to either .pkml or .R models without modifying the bridge code. See performance_evidence_bundles.md and the starter template at performance_evidence_bundle.template.json. Those bundles can now carry both row-level evidence and a traceability-only profileSupplement for predictive dataset records, acceptance criteria, and target outputs. The MCP validates row-level claims conservatively and keeps the supplement descriptive rather than silently upgrading the qualification boundary.

modelPerformance can now also declare structured datasetRecords and acceptanceCriteria inside goodnessOfFit, predictiveChecks, or evaluationData. The bridge normalizes those fields and exposes additive traceability counts so predictive support is not reduced to a single status token.

The same pattern now exists for uncertainty evidence. See uncertainty_evidence_bundles.md and uncertainty_evidence_bundle.template.json. The MCP surfaces warnings when uncertainty rows are missing method/summary or scope information, and variability-propagation rows are only treated as quantified propagation evidence when they actually include quantitative outputs such as value, lowerBound, upperBound, mean, or sd.

The same companion-bundle pattern now exists for richer parameter tables. See parameter_table_bundles.md and parameter_table_bundle.template.json. export_oecd_report and validate_model_manifest now surface row-level coverage for sources, citations, distributions, study conditions, and rationale so dossier gaps are visible without custom bridge code.

Structured peer-engagement traceability can now stay inside the existing peerReview profile section. If a model declares reviewRecords, priorRegulatoryUse, revisionStatus, or revisionHistory, the bridge now normalizes those fields and exposes dossier-ready coverage counts instead of treating peer review as a single free-text status flag.

For .pkml models, richer qualification metadata can be supplied with sidecars such as:

  • model.profile.json
  • model.pbpk.json

Running the server

The default local stack is:

  • pbpk_mcp-api-1 on http://127.0.0.1:8000
  • pbpk_mcp-worker-1 on the same pbpk_mcp-worker-rxode2:latest image for execution
  • pbpk_mcp-redis-1 for job brokering and result storage

The preferred local operator entrypoint is:

./scripts/deploy_rxode2_stack.sh

That command recreates the packaged local runtime so the live tool catalog remains aligned with the documented contract.

When you want to iterate against the current workspace source tree instead of the baked image baseline, use:

./scripts/deploy_source_overlay_stack.sh

That profile layers docker-compose.overlay.yml on top of the packaged stack, bind-mounts src/, scripts/, docs/, schemas/, and var/, enables PBPK_ENABLE_SRC_OVERLAY=true, and then waits for stable /health and /mcp/list_tools responses before returning.

When you want the same runtime contract with stricter deployme