Skip to content

Add Postman MCP server - #1197

Closed
danbarr wants to merge 2 commits into
mainfrom
add-postman-mcp-server
Closed

danbarr wants to merge 2 commits into
mainfrom
add-postman-mcp-server

Conversation

@danbarr

@danbarr danbarr commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Add Postman MCP server

Closes #1195

Packages Postman's first-party MCP server, @postman/postman-mcp-server 2.14.0 (repo postmanlabs/postman-mcp-server, license Apache-2.0, confirmed from the npm metadata, the LICENSE file in the published tarball, and the GitHub license API). This is a spec-only change: npx/postman-mcp-server/spec.yaml. Nothing under cmd/dockhand/ or internal/skills/ is touched, so it does not trigger a full-catalog rebuild.

Proxy-compatible Node

The ToolHive npx template builds on node:24-alpine (pkg/container/templates/runtime_config.go:169 in toolhive v0.42.1, the version pinned in go.mod), so no Node version change was needed. The spec sets spec.env.NODE_USE_ENV_PROXY: "1", which dockhand bakes into the runtime image. Per the Node docs and changelogs, fetch() has honored NODE_USE_ENV_PROXY since Node 24.0.0 (and 22.21.0), whereas the Docker MCP image in the issue ships Node 22.16.0, which predates that.

Toolsets and auth

No args means Minimal (42 tools). --code and --full pass through as runtime args, for example thv run ... -- --full. POSTMAN_API_KEY is read from the environment as before.

What was validated

  • ./build/dockhand verify-provenance -c npx/postman-mcp-server/spec.yaml -v: reports ATTESTATIONS (npm has a SLSA v1 attestation) but then fails with failed to parse bundle: proto: (line 1:2): unknown field "attestations", so dockhand did not verify it cryptographically. I decoded the attestation by hand: it was built from .github/workflows/pkg-release.yml at ref refs/tags/v2.14.0, commit 94efe91, which matches git ls-remote for the tag. The spec therefore records available: true, verified: false.
  • task build -- npx/postman-mcp-server: pass. The generated Dockerfile contains ENV NODE_USE_ENV_PROXY="1" in the runtime stage.
  • task scan: the Taskfile target does not pass security.mock_env to the scanner (it uses the legacy positional mode), so the server exits on the missing POSTMAN_API_KEY and the task reports "Scan failed to produce output". I ran the same steps CI uses (generate_mcp_config.py, run_scan.py --config, process_scan_results.py) and got 42 tools scanned, 4 blocking YARA findings before triage, 0 after. The four findings are AITech-12.1 (createCollection, putCollection), AITech-1.1 (getTaggedEntities), and AITech-9.1 (runCollection). Each is allowlisted with a specific reason in the spec. I read the tool descriptions: none contain instructions aimed at the model. runCollection does genuinely execute collection scripts through newman, which the reason states. security.insecure_ignore is not set.
  • task test-build: the Taskfile uses podman and the podman machine was not running, so I built the generated Dockerfile with docker build instead. The build succeeds. The image reports Node v24.22.1 and NODE_USE_ENV_PROXY=1 (checked on arm64 only; the amd64 build is left to CI, since the base image is a multi-arch node tag).
  • thv run with network isolation (default), a profile allowing only api.postman.com:443, and POSTMAN_API_KEY=PMAK-dummy-invalid-key:
    • Initialization and discovery: pass, 42 tools (minimal).
    • getAuthenticatedUser: reaches Postman through the egress proxy and returns API request failed: 401 {"error":{"message":"Invalid API Key. Every request requires a valid API Key to be sent.","name":"AuthenticationError"}}.
    • Control run with -e NODE_USE_ENV_PROXY=0, same image and profile: MCP error -32603: AggregateError, which reproduces the failure from the issue.
    • -- --full: server reports 234 tools (full).

Real-account checks

Not done. Everything above used a dummy key. I did not verify any authenticated call, collection fetch, or an end-to-end runCollection against a real account.

File mounts and network access

  • Outbound allow list: api.postman.com:443 (api.eu.postman.com with --region eu). Telemetry is off by default (POSTMAN_MCP_TELEMETRY); enabling it would need additional egress.
  • No file mounts are required. Collections and environments are fetched from the Postman API by ID. The server only tries to write an install id to ~/.postman/mcp-telemetry-id, and failures are swallowed. Mount files only if a collection references local files such as form-data uploads.
  • runCollection runs the collection with newman inside the container, so every host the collection calls must also be in the allow list. I confirmed through the egress proxy that an allowed host returns its real response, and that a non-allowed host is blocked.
  • Reaching a service on the host machine needs both the host and port in the permission profile (host.docker.internal plus the port) and --allow-docker-gateway on thv run. Without the flag, http://host.docker.internal:8080/ returned 403 from the egress proxy. With the profile entry and the flag it returned 200 from a local test server.

Concerns

  • When newman's request goes through a proxy that refuses the HTTPS CONNECT (a host not on the allow list), newman throws Error: Unknown object type "asyncfunction" from object-hash while serialising the request error (serialised-error via newman/lib/run/summary.js:393). I reproduced it in a standalone script with newman from the image on both Node 24 and Node 22, and it does not depend on NODE_USE_ENV_PROXY. A plain connection-refused error does not trigger it. I did not confirm how the MCP server process behaves in that case, because that needs a real collection. It may crash or fail the runCollection call when a collection targets a blocked HTTPS host. This looks like an upstream issue worth reporting to Postman.
  • The scanner only ran against the default Minimal toolset, as in CI.

🤖 Generated with Claude Code

Package @postman/postman-mcp-server 2.14.0 (Apache-2.0) from
postmanlabs/postman-mcp-server. The runtime image is node:24-alpine and
sets NODE_USE_ENV_PROXY=1 so Node fetch honors ToolHive's
HTTP_PROXY/HTTPS_PROXY under network isolation.

Minimal is the default toolset; --code and --full pass through as
runtime args. POSTMAN_API_KEY auth is unchanged. Allowlist three YARA
findings on tool descriptions with specific reasons.

Closes #1195

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com>
@toolhive-release-app

toolhive-release-app Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

🔒 MCP Security Scan Results

✅ postman-mcp-server

  • Status: Passed
  • Tools scanned: 42
  • Result: No security issues detected

Summary: Scanned 1 MCP server(s), all passed security checks. ✅

@toolhive-release-app

toolhive-release-app Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

🛡️ Grype Vulnerability Scan Results

Fixable High and Critical findings block publishing. Review these package versions when evaluating an override.

postman-mcp-server

Severity Vulnerability Package Installed Available fix
High GHSA-r5fr-rjxr-66jc lodash 4.17.21 4.18.0
Critical GHSA-2w6w-674q-4c4q handlebars 4.7.8 4.7.9
Critical GHSA-8r5x-fm3f-whwj handlebars 4.7.8 4.7.10
High GHSA-qpx9-hpmf-5gmw underscore 1.12.1 1.13.8
High GHSA-rf6f-7fwh-wjgh flatted 3.2.6 3.4.2
High GHSA-25h7-pfq9-p65f flatted 3.2.6 3.4.0
High GHSA-3mfm-83xf-c92r handlebars 4.7.8 4.7.9
High GHSA-xhpv-hc6g-r9c6 handlebars 4.7.8 4.7.9
Critical GHSA-p8wg-vrv2-v86f handlebars 4.7.8 4.7.10
High GHSA-9cx6-37pm-9jff handlebars 4.7.8 4.7.9
High GHSA-5gfm-wpxj-wjgq node-forge 1.3.1 1.3.2
High GHSA-5m6q-g25r-mvwx node-forge 1.3.1 1.4.0
High GHSA-q67f-28xg-22rw node-forge 1.3.1 1.4.0
High GHSA-554w-wpv2-vw27 node-forge 1.3.1 1.3.2
High GHSA-ppp5-5v6c-4jwp node-forge 1.3.1 1.4.0
High GHSA-2328-f5f3-gj25 node-forge 1.3.1 1.4.0
High GHSA-mrhx-c7xc-m3w5 zod 3.25.76 4.6.6
High GHSA-xjpj-3mr7-gcpf handlebars 4.7.8 4.7.9
High GHSA-qxc2-j82w-r537 @faker-js/faker 5.5.3 10.5.0

The scan job warms the npm cache with a global install. Packages that
ship a preinstall guard such as "npx only-allow pnpm" fail that step
(exit 127 in CI), which leaves no scan artifact and blocks the build.
This broke the Postman MCP server PR.

Retry with --ignore-scripts only when the normal install fails, so
packages that need their install scripts keep the current behavior.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Signed-off-by: Dan Barr <6922515+danbarr@users.noreply.github.com>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Package Postman with proxy-compatible Node

2 participants