Skip to content

Releases: Consiliency/pmcp

v1.19.3

Choose a tag to compare

@github-actions github-actions released this 12 Jul 00:23
v1.19.3
a76bc54

Security

  • No cross-server credential bleed. The gateway loads every PMCP-stored
    credential into its own os.environ, and the subprocess-spawn paths copied
    that whole environment — so each downstream MCP server received every other
    server's credentials (e.g. @brightdata/mcp got the OpenAI key). Downstream
    subprocesses now inherit the gateway environment minus PMCP-managed secret
    keys (the keys in the user pmcp.env + project .env.pmcp stores), then get
    only their own resolved credential re-applied. This covers both the server
    spawn (_connect_stdio) and the paths that execute a server's package code
    (start_install/install_server, and the update_server / verify_installation
    --help probes). Non-secret ambient vars (PATH/HOME/NODE_*/proxy/locale)
    are preserved. (#96)

    Scope: only PMCP-managed secrets are stripped — not secrets the operator
    exported into the shell or a plain .env. Behavior change: a server that
    relied on ambient inheritance of a secret it does not declare (no config
    env block, no manifest credential) no longer receives it. Follow-ups tracked
    in #96: sanitizing the trusted-CLI probes as defense-in-depth, and the durable
    fix of not loading secrets into the global os.environ at all.

v1.19.2

Choose a tag to compare

@github-actions github-actions released this 11 Jul 23:37
v1.19.2
a031f42

Fixed

  • Per-server credential storage-key namespacing. A server can now store its
    credential under a namespaced key (manifest secret_key, e.g. Bright Data's
    BRIGHTDATA_API_TOKEN) while the downstream process still receives the generic
    runtime env_var it reads (API_TOKEN). This removes the collision risk of
    two servers sharing a generic name like API_TOKEN in the flat secret store.
    Every credential path resolves through credential_lookup_keys (namespaced key
    first, legacy env_var as a backward-compatible fallback — no migration
    required): the auth_connect write path, the provision auth gate
    (check_api_key), manifest/configured/eager/lazy/refresh startup-config
    resolution, the install-and-run subprocess environment (adopted npx servers),
    and the connect/describe availability checks. Configured .mcp.json entries
    that match a manifest api-key server inherit the resolved credential (including
    dead ${VAR}/$VAR placeholders that local stdio env never expands), and the
    pmcp secrets check / pmcp init diagnostics are namespace-aware. (#95)

v1.19.1

Choose a tag to compare

@github-actions github-actions released this 06 Jul 10:37
v1.19.1
cc57dc4

Fixed

  • gateway.describe now exposes nested array/object item schemas. Array and
    object arguments were collapsed to a bare "array"/"object" type, hiding
    item shape and required item fields, so agents wasted calls guessing at the
    payload (e.g. brightdata::search_engine_batch needs
    {"queries": [{"query": "..."}]}). ArgInfo gains an optional item_schema
    with a compact one-level summary, and the invoke_template placeholder now
    shows the nested shape (e.g. [{"query": "<string>"}]). Scalar-arg output is
    unchanged. (issue #87)
  • index-it-mcp manifest entry now launches the stdio transport. The
    shipped entry ran serve (the HTTP/admin surface) where PMCP's local process
    path needs a stdio MCP child; command/args and all four install platforms
    now end in stdio. (issue #89)

Docs

  • README pilot config for provisioning index-it-mcp via .mcp.json with a
    pinned version and the operational env block, noting that per-entry env is
    honored only from .mcp.json (the manifest/overlay schema has no env:).

v1.19.0

Choose a tag to compare

@github-actions github-actions released this 04 Jul 08:33
v1.19.0
f49cc83

Remediation of the v1.18.0 code review (roadmap specs/phase-plans-v10.md).

Fixed

  • Downstream servers now actually recover from failure. A crashed stdio
    server never came back: _cleanup_client cancelled the very connect task
    driving the reconnect (a gather() cancelling itself → RecursionError).
    _cancel_background_tasks now excludes the current task and _cleanup_client
    cancels only the client's own read/stderr tasks. Remote (SSE/HTTP) servers now
    auto-reconnect on an unexpected drop (parity with stdio). Failed connects no
    longer leave a stale ERROR client or a leaked stderr reader task. Proven by a
    real-subprocess integration test.
  • Transport DoS bounds: pre-session keepalive SSE streams are capped
    (PMCP_MAX_KEEPALIVE_STREAMS, default 64) with an absolute lifetime
    (PMCP_KEEPALIVE_MAX_SECONDS, default 300); POST bodies are enforced against
    the size cap during read so chunked/unadvertised-length bodies can't bypass
    it (413), with a request timeout closing slow-trickle connections.
  • Robustness: terminal task records are evicted past a cap (was unbounded);
    disconnect_server re-cancels pending requests under the lifecycle lock
    (orphaned-future window); malformed .mcp.json is surfaced (path + reason)
    instead of silently disabling its servers; find_project_root no longer
    resolves to $HOME; version-check URLs are quote()-escaped; the two flaky
    monitor tests are now deterministic.

Security

  • OAuth 2.1 resource-server auth mode and Origin/DNS-rebinding validation are
    now reachable.
    They were fully implemented and tested but never passed to the
    running server. New CLI flags/env (--auth-mode, --oauth-issuer,
    --oauth-jwks-url, --oauth-audience, --required-scope, --allowed-origin;
    PMCP_AUTH_MODE/PMCP_OAUTH_*/PMCP_ALLOWED_ORIGINS) thread them through
    GatewayServer. The Origin check now runs by default: a cross-origin browser
    Origin is rejected (loopback/same-origin/allowlisted pass; no-Origin clients
    unaffected). Host validation is opt-in when origins are configured.
  • Provisioning input validation: a discovered/registered package name is now
    validated (rejects leading-dash flag injection, path separators, shell/URL
    metachars) before it can reach npx -y <name>, and the resolved install
    command is echoed for confirmation. auth_connect refuses to persist/export an
    env var that isn't the target server's declared credential variable (hard
    denylist for LD_*/DYLD_*/NODE_OPTIONS/PATH/PYTHON*), closing an
    LD_PRELOAD-into-subprocess code-exec path.
  • Outbound-fetch hardening: JWKS and auth-metadata fetches no longer follow
    redirects to internal hosts; the registry response is size-capped during a
    streamed read (no OOM); the private registry endpoint requires https and
    rejects link-local/metadata hosts; the registry cache is written atomically at
    0600.
  • Local credentials: pmcp secrets set reads the value via prompt/--stdin
    (never argv/shell history); the secret directory is created 0700;
    submit_feedback scrubs the title and all fields (not just the description)
    before posting to a public issue.

Changed

  • Policy allow/deny matching is now case-sensitive (matching server-ID
    semantics elsewhere in the gateway).
  • pmcp status no longer eagerly connects every server as a side effect of a
    read-only query — it reports the lazy view by default; use --probe to connect.
  • Explicit --max-concurrent-spawns / --rate-limit / --request-timeout flags
    now take precedence over the matching env var (previously a flag equal to the
    default was silently overridden).

v1.18.0

Choose a tag to compare

@github-actions github-actions released this 29 Jun 09:09
v1.18.0
1c907db

Added

  • Private/custom manifest overlay: define your own provisionable MCP servers in
    ~/.pmcp/manifest.yaml (user), <project>/.pmcp/manifest.yaml (project), or a
    file pointed to by PMCP_MANIFEST_PATH, merged over the shipped manifest
    without editing it. Precedence is shipped < user < project < PMCP_MANIFEST_PATH
    (same-named entries are replaced whole). Overlay parsing is fail-soft — a
    missing file is skipped, and a malformed file or a single bad entry logs a
    warning and is skipped without crashing the gateway. Merged servers
    participate identically in gateway.request_capability, gateway.catalog_search,
    gateway.provision, and startup refresh resolution, gated by the same
    policy/auth checks.

v1.17.1

Choose a tag to compare

@github-actions github-actions released this 29 Jun 07:31
v1.17.1
1ed7a7c

Fixed

  • Native Windows gateway startup no longer crashes with No module named 'fcntl'
    (issue #84). acquire_singleton_lock/release_singleton_lock imported the
    Unix-only fcntl unconditionally; they now take the per-user single-instance
    lock via msvcrt.locking on Windows and fcntl.flock on POSIX (selected by a
    literal sys.platform check so type checkers narrow the platform-only
    imports). WSL is unaffected. (resource was already import-guarded.)

v1.17.0

Choose a tag to compare

@github-actions github-actions released this 28 Jun 11:36
v1.17.0
e9a287f

Fixed

  • A single downstream stdout line larger than the read limit (default 10 MiB,
    PMCP_STDIO_READ_LIMIT) no longer disconnects the whole server (issue #79,
    symptom 1b). The stdout reader now reads in chunks and splits on newlines
    itself: an oversized line is dropped — failing only the request it belongs to,
    with an actionable "output too large" message — while the connection and other
    pending requests stay alive, so the next call no longer fails. Large browser
    responses (full-page snapshots, screenshots) were a common trigger of the
    reported "session expired"/instability. A reproduction harness lives in
    diagnostics/issue-79-1b/.
  • Downstream tool calls are no longer killed by a fixed wall-clock deadline
    (issue #79, symptom 1a). timeout_ms is now an inactivity (idle) timeout:
    a call survives as long as the downstream MCP server keeps producing output
    (including JSON progress notifications, which now count toward per-request
    liveness in both the stdio and SSE readers). An absolute backstop caps total
    wall-clock time so a chatty-but-never-completing call cannot hang forever —
    configurable via PMCP_REQUEST_CEILING_MS (default 600000ms / 10 min). The
    long ceiling applies only to tool invocations; control-plane requests
    (initialize, list calls) keep the tighter idle deadline so one stuck server
    can't stall startup/refresh. This unblocks legitimately long browser/
    automation operations driven through the gateway.
  • Stdio servers are now spawned in their own session/process group
    (start_new_session=True) and reaped as a whole tree on disconnect (issue
    #79, symptom 1c). Previously, killing a stdio server (e.g. @playwright/mcp)
    left the browser it launched orphaned to init, holding the profile's
    SingletonLock and breaking the next launch. A new group-aware
    _terminate_process_tree helper (SIGTERM the group, wait, then SIGKILL, with
    a single-process fallback when the process is not a group leader, or on
    Windows where process groups are unavailable) now backs all four downstream
    shutdown paths.
  • gateway.refresh is now diff-based and non-destructive (issue #79, symptom
    2). Servers whose resolved config is unchanged are left connected and
    running; only servers that were removed or whose config changed are
    disconnected, and only newly-added eager servers are connected. Previously
    refresh tore down every server and reconnected only the eager set, which
    dropped previously-running lazy/provisioned servers to offline (the reported
    "105 seen, 0 online") and needlessly respawned unchanged processes (e.g. a
    live browser) on every refresh. The diff keeps only servers that are actually
    ONLINE — a crashed eager server is reconnected (recovery path preserved);
    reconciles the lazy registry to the resolved keep-set so removed/policy-denied
    servers can no longer be lazily started; and reconnects a remote server when
    its ${VAR} auth token has rotated in the env store (compared against the
    connect-time resolved headers), instead of keeping stale/revoked auth.
  • Process-tree reaping now escalates to a group SIGKILL when the leader exits
    but a grandchild (e.g. a SIGTERM-ignoring browser) survives the SIGTERM
    grace period, and reaps servers concurrently at shutdown so multiple hung
    servers can't exceed the shutdown budget and orphan browsers (issue #79/1c).

Added

  • gateway.catalog_search with include_offline=true now surfaces
    manifest-only provisionable servers in a dedicated manifest_candidates field
    when the query matches a manifest server by name or keyword but no cached
    tools exist yet (issue #78). Candidates carry machine-readable next-action
    metadata (provisionable, provision_tool, request_capability_tool,
    auth_tool, requires_api_key, api_key_available, env_var) so an agent
    can provision the exact server instead of falling back to a plain web search.
  • Manifest: brightdata keywords extended with web research, current web,
    page fetch, and external research so research-oriented prompts match
    without the exact brand name.

Changed

  • gateway.request_capability tool description now states it recommends a
    server to provision (and that gateway.provision does the actual install/
    start), matching the implementation — it previously claimed to auto-provision
    (issue #78).

v1.16.0

Choose a tag to compare

@github-actions github-actions released this 25 Jun 11:23
v1.16.0
57eac97

Added

  • Manifest: 2026 vendor-official servers — Okta (identity/IAM), Zapier
    (automation meta-connector), Shopify Dev and Square (commerce), Snowflake
    Cortex (data platform), Pinecone (vector DB), Azure DevOps, and the GitLab Duo
    remote MCP. Adds Identity, Automation, E-commerce, and Data-Platform discovery
    coverage.
  • Manifest (Tier 2): Elasticsearch, Chroma, Redis, Databricks (managed remote),
    Storybook, and Cloudinary — rounding out search/vector, data-platform,
    frontend, and media coverage.

Changed

  • Manifest: mongodb now points at the official mongodb-mcp-server
    (mongodb-js) instead of the community mongodb-lens, covering Atlas admin in
    addition to queries.

v1.15.0

Choose a tag to compare

@github-actions github-actions released this 25 Jun 04:23
v1.15.0
bf7e54e

Added

  • SPEC_COMPLIANCE.md tracks PMCP against the current stable MCP revision
    (2025-11-25) with a per-requirement compliance table, a draft-revision
    migration assessment (stateless transport, the io.modelcontextprotocol/tasks
    extension, server/discover, CacheableResult, DCR→Client ID Metadata
    Documents, SSE resumability), and a next-stable tracking checklist. PMCP is
    confirmed compliant with the folded-in current-stable items (403 on invalid
    Origin per PR #1439, insufficient_scope 403 step-up per SEP-835,
    input-validation as tool-execution errors per SEP-1303, JSON Schema 2020-12
    default dialect per SEP-1613, tool/resource/prompt icon passthrough per
    SEP-973).
  • MCP Registry incremental sync. The registry client persists last_synced_at
    and accepts updated_since to fetch only changed servers
    (?version=latest&updated_since=… with cursor pagination), merging deltas into
    the cache via merge_registry_delta. A failed incremental attempt degrades to
    a full fetch, and a failed full fetch degrades to the prior cache. Default
    full-fetch callers are unchanged.
  • Opt-in private-registry support (PMCP_REGISTRY_ALLOW_PRIVATE, default off).
    When enabled with PMCP_REGISTRY_PRIVATE_ENDPOINT, PMCP discovers from a
    private/custom registry and tolerates draft/non-GA server.json schema fields,
    surfacing all versions — a debugging aid for developers building their own
    private MCP servers, not for production discovery. With the flag off,
    discovery behavior is unchanged.

v1.14.2

Choose a tag to compare

@github-actions github-actions released this 24 Jun 05:53
v1.14.2
3c19f3e

Removed

  • Removed the unused BAML/LLM machinery entirely. Outbound LLM calls were retired
    long ago in favor of a pure-Python capability router, leaving the baml-py
    dependency, the generated baml_client, baml_src/, the retired
    llm_summarizer stub, and the dead use_llm / use_llm_fallback code paths as
    vestigial. Dropping them removes a heavy dependency (no more native binary) and
    the per-release client-regeneration burden. Capability summaries and code
    snippets are unchanged: cache → template for summaries, static templates for
    snippets. The llm optional-dependency extra is gone.