diff --git a/.cursor-plugin/plugin.json b/.cursor-plugin/plugin.json index f3353d6..ea91d9a 100644 --- a/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "postman", - "version": "1.1.0", - "description": "Full API lifecycle management for Cursor. Sync collections, generate client code, discover APIs, run tests, create mocks, improve docs, and audit security. Powered by the Postman MCP Server.", + "version": "1.2.0", + "description": "Full API lifecycle management for Cursor. Sync collections, generate OpenAPI specs, discover APIs, run tests and Flows, create mocks, improve docs, and audit security. Powered by the Postman MCP Server.", "author": { "name": "Postman DevRel", "url": "https://www.postman.com" diff --git a/CHANGELOG.md b/CHANGELOG.md index 739dd29..5767d00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,16 @@ section into a dated, versioned entry when a release is cut — see [RELEASING.m ## [Unreleased] +## [1.2.0] - 2026-08-02 + +### Added + +- Nine commands to reach the canonical **18-command** set shared with the [Claude Code](https://github.com/Postman-Devrel/postman-claude-code-plugin) and Antigravity plugins: `/postman:run-collection`, `/postman:send-request`, `/postman:list-flows`, `/postman:trigger-flow`, `/postman:deploy-flow`, `/postman:get-flow-run`, `/postman:use-local`, and `/postman:use-remote`. The Flow, `run-collection`, and `send-request` commands drive the Postman CLI; `use-local` / `use-remote` toggle `.mcp.json` between the local stdio package and the hosted server (both API-key authenticated). +- `/postman:generate-client` — generate typed client code **from** a Postman collection. This preserves the client-code-generation capability of the pre-rename `codegen` command (distinct from `/postman:generate-spec`, which generates an OpenAPI spec **from** your code). MCP-tool-driven; requires Code or Full MCP mode. + ### Changed +- Renamed `/postman:codegen` to `/postman:generate-spec` and reworked it to generate or update an OpenAPI 3.0 spec from the codebase, matching the canonical command shared across Postman's AI coding plugins. The original client-code-generation capability is preserved as the distinct `/postman:generate-client` command (see Added). Updated the README, routing skill, and knowledge skill references accordingly. - Updated README installation instructions: Postman is now an official [Cursor Marketplace](https://cursor.com/marketplace/postman) plugin. ## [1.1.0] - 2026-07-20 @@ -45,5 +53,6 @@ section into a dated, versioned entry when a release is cut — see [RELEASING.m [1.0.1]: https://github.com/Postman-Devrel/cursor-postman-plugin/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/Postman-Devrel/cursor-postman-plugin/releases/tag/1.0.0 -[Unreleased]: https://github.com/Postman-Devrel/cursor-postman-plugin/compare/1.1.0...HEAD +[Unreleased]: https://github.com/Postman-Devrel/cursor-postman-plugin/compare/1.2.0...HEAD +[1.2.0]: https://github.com/Postman-Devrel/cursor-postman-plugin/compare/1.1.0...1.2.0 [1.1.0]: https://github.com/Postman-Devrel/cursor-postman-plugin/compare/1.0.1...1.1.0 diff --git a/README.md b/README.md index 09809c6..4ec0cba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Postman Plugin for Cursor -Full API lifecycle management inside Cursor. Sync collections, generate typed client code, discover APIs, run tests, create mocks, improve documentation, and audit security. Powered by the [Postman MCP Server](https://github.com/postmanlabs/postman-mcp-server). +Full API lifecycle management inside Cursor. Sync collections, generate OpenAPI specs and typed clients, discover APIs, run tests, create mocks, run Flows, improve documentation, and audit security. Powered by the [Postman MCP Server](https://github.com/postmanlabs/postman-mcp-server). > **Note:** This plugin mirrors the [Postman Plugin for Claude Code](https://github.com/Postman-Devrel/postman-claude-code-plugin), which is the source of truth for Postman's AI coding agent plugins. @@ -8,7 +8,7 @@ Full API lifecycle management inside Cursor. Sync collections, generate typed cl This plugin connects Cursor to your Postman account via the Postman MCP Server and bundles purpose-built commands, skills, and an API readiness analyzer. One install gives you: -- **9 commands** covering the complete API lifecycle +- **18 commands** covering the complete API lifecycle (the canonical command set shared with the [Claude Code](https://github.com/Postman-Devrel/postman-claude-code-plugin) and Antigravity plugins) - **3 auto-loaded skills** that teach the agent how to use Postman effectively - **1 sub-agent** for deep API readiness analysis (48 checks across 8 pillars) - **API design rules** injected into every session @@ -87,12 +87,23 @@ Creating collection "Pet Store API" with 15 endpoints... Collection synced. Environment "Pet Store - Dev" created. ``` -### `/postman:codegen` -- Generate Client Code +### `/postman:generate-spec` -- Generate an OpenAPI Spec -Generate typed client code from any Postman collection. Detects your project language and matches existing conventions. +Generate or update an OpenAPI 3.0 spec by scanning the API routes in your codebase, then validate it with the Postman CLI. ``` -> /postman:codegen +> /postman:generate-spec +Scanned 8 routes in src/routes/ +Wrote postman/specs/openapi.yaml (8 endpoints, 4 schemas) +Validation: passed +``` + +### `/postman:generate-client` -- Generate Client Code + +Generate typed client code from any Postman collection. Detects your project language and matches existing conventions. (The inverse of `generate-spec`: client code **from** a collection, rather than a spec **from** your code.) + +``` +> /postman:generate-client Which collection? "User Management API" Detected: TypeScript project Generated: src/clients/user-management-api.ts (5 endpoints, 8 types) @@ -163,6 +174,71 @@ Ask "how do I..." questions about Postman itself and how to accomplish workflows Source: learning.postman.com/docs/design-apis/mock-apis/... ``` +### `/postman:run-collection` -- Run a Collection (CLI) + +Run a Postman collection with the Postman CLI, then parse the results and diagnose failures. + +``` +> /postman:run-collection +Running collection 12345678-... +Passed: 14/15 -- diagnosing the 1 failure... +``` + +### `/postman:send-request` -- Send an HTTP Request (CLI) + +Send a single ad-hoc HTTP request with the Postman CLI and report the response. + +``` +> /postman:send-request GET https://api.example.com/health +200 OK (82ms) -- {"status":"healthy"} +``` + +### `/postman:list-flows` -- List Flows + +List Postman Flows in a workspace and resolve a flow name to its 24-character ID. + +``` +> /postman:list-flows +Checkout -- 6634a1... (last run: passed) +Onboarding -- 6634b2... (last run: failed) +``` + +### `/postman:trigger-flow` -- Trigger a Flow + +Trigger a deployed Postman Flow with inputs from natural language, and report the Run ID, status, and response. + +``` +> /postman:trigger-flow Checkout with amount 4200 +Run ID: run_abc123 Status: 200 Body: {"ok":true} +``` + +### `/postman:deploy-flow` -- Deploy a Flow + +Deploy a Postman Flow so it becomes triggerable, confirming the trigger path first (deploy is mutating). + +``` +> /postman:deploy-flow Checkout +Proposed path: /checkout -- confirm? (y/n) +Deployed. Trigger URL: https://... Trigger: enabled +``` + +### `/postman:get-flow-run` -- Inspect a Flow Run + +Inspect a Flow run by its Run ID -- per-block logs, the failing block, and status. + +``` +> /postman:get-flow-run run_abc123 +Status: failed Failing block: "Charge Card" (502 from upstream) +``` + +### `/postman:use-local` -- Use the Local MCP Server + +Rewrite this plugin's `.mcp.json` to run the Postman MCP server locally over stdio (`npx @postman/postman-mcp-server@latest`), authenticated with your `POSTMAN_API_KEY`. + +### `/postman:use-remote` -- Use the Remote MCP Server + +Rewrite this plugin's `.mcp.json` back to Postman's hosted MCP server (`https://mcp.postman.com/mcp`), authenticated with your API key. + ## Auto-Routing You don't have to remember command names. The plugin includes a routing skill that maps natural language to the right command: @@ -170,7 +246,11 @@ You don't have to remember command names. The plugin includes a routing skill th | You say | Plugin runs | |---------|------------| | "Sync my API with Postman" | `/postman:sync` | -| "Generate a Python client for the payments API" | `/postman:codegen` | +| "Generate an OpenAPI spec from my API code" | `/postman:generate-spec` | +| "Generate a Python client for the payments API" | `/postman:generate-client` | +| "Run the checkout collection" | `/postman:run-collection` | +| "Trigger the Checkout flow with amount 4200" | `/postman:trigger-flow` | +| "Run the Postman MCP server locally" | `/postman:use-local` | | "What endpoints do we have for orders?" | `/postman:search` | | "Run my API tests" | `/postman:test` | | "I need a mock for frontend dev" | `/postman:mock` | @@ -194,7 +274,7 @@ See `examples/sample-readiness-report.md` for a sample output. ### MCP Server Modes -This plugin defaults to **Code mode** (~45-50 tools), which covers 8 of 9 commands fully. The only gap is documentation publishing (available in Full mode only). +This plugin ships with the Full (`https://mcp.postman.com/mcp`) endpoint in `.mcp.json`, which covers every MCP-based command including documentation publishing. The Flow, `run-collection`, `send-request`, and `generate-spec` commands drive the Postman CLI instead of MCP, so they work regardless of the MCP mode. Use `/postman:use-remote` or `/postman:use-local` to switch the MCP transport at any time. **Code mode (default):** ```json @@ -243,16 +323,25 @@ cursor-postman-plugin/ ├── .cursor-plugin/ │ └── plugin.json # Plugin manifest ├── .mcp.json # Postman MCP server config (Code mode) -├── commands/ +├── commands/ # 18 commands (canonical cross-plugin set) │ ├── setup.md # /postman:setup │ ├── sync.md # /postman:sync -│ ├── codegen.md # /postman:codegen +│ ├── generate-spec.md # /postman:generate-spec +│ ├── generate-client.md # /postman:generate-client │ ├── search.md # /postman:search │ ├── test.md # /postman:test +│ ├── run-collection.md # /postman:run-collection +│ ├── send-request.md # /postman:send-request │ ├── mock.md # /postman:mock │ ├── docs.md # /postman:docs │ ├── security.md # /postman:security -│ └── learn.md # /postman:learn +│ ├── learn.md # /postman:learn +│ ├── list-flows.md # /postman:list-flows +│ ├── trigger-flow.md # /postman:trigger-flow +│ ├── deploy-flow.md # /postman:deploy-flow +│ ├── get-flow-run.md # /postman:get-flow-run +│ ├── use-local.md # /postman:use-local +│ └── use-remote.md # /postman:use-remote ├── skills/ │ ├── postman-routing/ # Auto-routes intent to commands │ ├── postman-knowledge/ # Postman concepts + MCP guidance diff --git a/commands/deploy-flow.md b/commands/deploy-flow.md new file mode 100644 index 0000000..04847c8 --- /dev/null +++ b/commands/deploy-flow.md @@ -0,0 +1,57 @@ +--- +description: Deploy a Postman Flow so it becomes triggerable, proposing and confirming a trigger path. +allowed-tools: Bash, Read +--- + +# /postman:deploy-flow -- Deploy a Flow + +Deploy a Postman Flow with the Postman CLI so it becomes triggerable. Deploy is mutating — always confirm before running it. + +## Prerequisites + +This command drives the Postman CLI (`postman flows ...`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. Reuse the existing CLI session; never authenticate twice. + +## Inputs (from the user's message) + +- The flow (a 24-character ID, or a name to resolve via `/postman:list-flows`) +- Optionally a desired trigger path and whether auth is required + +## Workflow + +### Step 1: Resolve the Flow ID + +Use `/postman:list-flows` if given a name; ask for the workspace if unknown. + +### Step 2: Propose and Confirm + +Propose a trigger path derived from the flow name (e.g. "Checkout" → `/checkout`) and **confirm the path and the deploy action** with the user. Deploy is mutating and MUST NOT run without explicit confirmation. + +### Step 3: Deploy + +Show the command, then run it after confirmation: + +```bash +POSTMAN_CLI_SOURCE=cursor-plugin postman flows deploy --path /checkout +``` + +### Step 4: Report + +Report the **Trigger URL** and whether the **trigger is enabled**. If it's off, offer `postman flows update --trigger on` (confirm first). + +### Step 5: Hand Off + +If this was part of a deploy-then-trigger request, hand back to `/postman:trigger-flow` to run it. + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| Flow not found | "I couldn't find that flow. Run /postman:list-flows to see what's in the workspace." | +| Deploy not confirmed | "Deploy is a mutating action — I'll wait for your explicit go-ahead on the trigger path before deploying." | +| Auth failure | "Postman returned 401. Run `postman login --with-api-key $POSTMAN_API_KEY`, or /postman:setup to reconfigure." | + +## Related Commands + +- Resolve a flow name to an ID -> `/postman:list-flows` +- Run the deployed flow -> `/postman:trigger-flow` diff --git a/commands/codegen.md b/commands/generate-client.md similarity index 91% rename from commands/codegen.md rename to commands/generate-client.md index 49f3508..06d483c 100644 --- a/commands/codegen.md +++ b/commands/generate-client.md @@ -3,14 +3,18 @@ description: Generate typed client code from Postman collections. Reads your pri allowed-tools: Bash, Read, Write, Glob, Grep, mcp__postman__* --- -# /postman:codegen -- Generate Client Code +# /postman:generate-client -- Generate Client Code Generate typed client code from Postman collections. Reads your private APIs and writes production-ready client code that matches your project conventions. +> This is the inverse of `/postman:generate-spec` (which writes an OpenAPI spec **from** your code). This command writes client code **from** a Postman collection. + ## Prerequisites Postman MCP Server must be configured. If MCP tools fail, tell the user to run `/postman:setup`. +**MCP mode:** requires **Code** or **Full** mode — the code-generation tools (`getCodeGenerationInstructions`, etc.) are absent in `minimal`. This plugin's `.mcp.json` points at the Full endpoint (`https://mcp.postman.com/mcp`), so it works out of the box. + ## Workflow ### Step 1: Find the API diff --git a/commands/generate-spec.md b/commands/generate-spec.md new file mode 100644 index 0000000..4be5118 --- /dev/null +++ b/commands/generate-spec.md @@ -0,0 +1,92 @@ +--- +description: Generate or update an OpenAPI 3.0 spec by analyzing the API routes in your codebase. +allowed-tools: Bash, Read, Write, Glob, Grep +--- + +# /postman:generate-spec -- Generate an OpenAPI Spec + +Generate or update an OpenAPI 3.0 specification by analyzing the API routes in your codebase. Scan the project for route definitions, derive schemas from the code, write a valid spec, and validate it. + +## Prerequisites + +The Postman CLI is used to validate the generated spec (`postman spec lint`). If it isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. Validation is optional; if the CLI is unavailable, still write the spec and tell the user to lint it later. + +## Workflow + +### Step 1: Check for an Existing Spec + +```bash +ls postman/specs/**/*.yaml postman/specs/**/*.yml postman/specs/**/*.json 2>/dev/null +ls openapi.yaml openapi.yml swagger.yaml swagger.yml 2>/dev/null +``` + +If a spec exists, read it to understand the current state. You'll update it rather than replace it. + +### Step 2: Discover API Endpoints + +Scan the project for route definitions based on the framework: + +- **Express/Node**: `app.get()`, `router.post()`, `@Get()` (NestJS) +- **Python**: `@app.route()`, `@router.get()` (FastAPI), `path()` (Django) +- **Go**: `http.HandleFunc()`, `r.GET()` (Gin/Echo) +- **Java**: `@GetMapping`, `@PostMapping`, `@RequestMapping` +- **Ruby**: `get`, `post`, `resources` in `routes.rb` + +Read the route files and extract methods, paths, parameters, request bodies, response schemas, and auth requirements. + +### Step 3: Generate or Update the Spec + +Write a valid OpenAPI 3.0.3 YAML spec including: + +- `info` with title, version, and description +- `servers` with a local dev URL +- `paths` with all discovered endpoints +- `components/schemas` with models derived from the code (types, models, structs) +- `components/securitySchemes` if auth is used + +**When updating**: add new endpoints, update changed ones, and remove endpoints no longer in the code. Preserve existing descriptions and examples. + +**When creating**: write to `postman/specs/openapi.yaml`. + +### Step 4: Validate + +```bash +postman spec lint ./postman/specs/openapi.yaml +``` + +Fix any validation errors and re-run until clean. + +### Step 5: Report + +Show what was created or changed: + +``` +Spec written: postman/specs/openapi.yaml + + Endpoints documented: 8 + GET /users + GET /users/{id} + POST /users + ... and 5 more + + Schemas defined: User, CreateUserRequest, UserListResponse, Error + Security schemes: bearerAuth + Validation: passed (0 errors, 0 warnings) +``` + +When updating, also summarize the changes from the previous spec (added / updated / removed endpoints). + +## Error Handling + +| Error | Response | +|-------|----------| +| No routes found | "I couldn't find API route definitions in this project. Tell me where your routes live, or which framework you're using." | +| Can't detect framework | "I can't tell which web framework this project uses. Point me at the routing file and I'll take it from there." | +| Validation errors | "The generated spec has validation issues — I'll fix them and re-lint until it's clean." | +| Postman CLI not installed | "I wrote the spec but couldn't validate it — the Postman CLI isn't installed. Install it, then run `postman spec lint ./postman/specs/openapi.yaml`." | +| Auth failure | "Postman returned 401. Your API key may be expired. Run /postman:setup to reconfigure." | + +## Related Commands + +- Push the generated spec to Postman as a collection -> `/postman:sync` +- Run the collection's tests -> `/postman:test` diff --git a/commands/get-flow-run.md b/commands/get-flow-run.md new file mode 100644 index 0000000..31cc7e0 --- /dev/null +++ b/commands/get-flow-run.md @@ -0,0 +1,52 @@ +--- +description: Inspect a Postman Flow run by its Run ID — per-block logs, the failing block, and status. +allowed-tools: Bash, Read +--- + +# /postman:get-flow-run -- Inspect a Flow Run + +Inspect a specific Postman Flow run with the Postman CLI. Read-only — no confirmation needed. + +## Prerequisites + +This command drives the Postman CLI (`postman flows ...`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. Reuse the existing CLI session; never authenticate twice. + +## Inputs (from the user's message) + +- The Run ID (the `x-run-id` that `/postman:trigger-flow` reported; ask if unknown) +- Optionally a block ID to focus on + +## Workflow + +### Step 1: Take the Run ID + +If you don't have it, ask for it — it's the `x-run-id` returned when the flow was triggered. + +### Step 2: Get the Run + +Run a summary first, then add `--logs` for detail: + +```bash +POSTMAN_CLI_SOURCE=cursor-plugin postman flows get-run --run-id +POSTMAN_CLI_SOURCE=cursor-plugin postman flows get-run --run-id --logs +``` + +Narrow to a block with `--filter `. + +### Step 3: Report + +Report **which block failed and why**, and the **run status**. + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| No Run ID | "What's the Run ID? It's the `x-run-id` returned when the flow was triggered." | +| Run not found | "I couldn't find a run with that ID. Double-check the Run ID from the trigger output." | +| Auth failure | "Postman returned 401. Run `postman login --with-api-key $POSTMAN_API_KEY`, or /postman:setup to reconfigure." | + +## Related Commands + +- Trigger a flow and get a Run ID -> `/postman:trigger-flow` +- List flows in a workspace -> `/postman:list-flows` diff --git a/commands/list-flows.md b/commands/list-flows.md new file mode 100644 index 0000000..f4a732b --- /dev/null +++ b/commands/list-flows.md @@ -0,0 +1,49 @@ +--- +description: List Postman Flows in a workspace and resolve a flow name to its 24-character ID. +allowed-tools: Bash, Read +--- + +# /postman:list-flows -- List Flows + +List Postman Flows in a workspace with the Postman CLI, and resolve a flow name to its 24-character ID. + +## Prerequisites + +This command drives the Postman CLI (`postman flows ...`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. Reuse the existing CLI session; never authenticate twice. + +## Inputs (from the user's message) + +- The workspace ID (ask if unknown) +- Optionally a name/pattern to filter by + +## Workflow + +### Step 1: Ensure a Workspace ID + +If you don't have one, ask which workspace to list Flows from. + +### Step 2: List Flows + +```bash +POSTMAN_CLI_SOURCE=cursor-plugin postman flows list --workspace +``` + +Narrow with `--filter ""` when resolving a specific flow; use `--sort name` / `--paginate` as needed. Always show the exact command before running it. + +### Step 3: Report + +Report flow **names + IDs** (and recent status where shown). When resolving a name for another action, return the single matching ID; on multiple matches, present the candidates and ask the user to choose — never guess. + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| No workspace ID | "Which workspace should I list Flows from? I need its ID." | +| No flows found | "No Flows found in that workspace. Double-check the workspace ID." | +| Auth failure | "Postman returned 401. Run `postman login --with-api-key $POSTMAN_API_KEY`, or /postman:setup to reconfigure." | + +## Related Commands + +- Trigger a resolved flow -> `/postman:trigger-flow` +- Deploy a flow so it becomes triggerable -> `/postman:deploy-flow` diff --git a/commands/run-collection.md b/commands/run-collection.md new file mode 100644 index 0000000..603270d --- /dev/null +++ b/commands/run-collection.md @@ -0,0 +1,82 @@ +--- +description: Run a Postman collection with the Postman CLI to verify your API endpoints, then parse and report results. +allowed-tools: Bash, Read, Glob, Grep +--- + +# /postman:run-collection -- Run a Collection + +Run a Postman collection with the Postman CLI to verify your API endpoints. Parse the results, and diagnose failures. + +## Prerequisites + +This command drives the Postman CLI (`postman collection run`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. + +## Workflow + +### Step 1: Find Collections and IDs + +List local collection folders and look up their cloud IDs: + +```bash +ls postman/collections/ +cat .postman/resources.yaml +``` + +The `cloudResources.collections` section maps local collection paths to cloud IDs. + +- If no collections are found, tell the user and stop. +- If there is one collection, use it directly. +- If there are multiple, list them and ask which to run. + +### Step 2: Run the Collection + +Run by **collection ID** (from `.postman/resources.yaml`): + +```bash +postman collection run +``` + +Common options: + +```bash +# Stop on first failure +postman collection run --bail + +# With request timeout +postman collection run --timeout-request 10000 + +# With an environment +postman collection run -e ./postman/environments/.json + +# Override an environment variable +postman collection run --env-var "base_url=http://localhost:3000" +``` + +Always show the exact command before running it. + +### Step 3: Parse and Report Results + +Parse the CLI output for pass/fail counts, failed test names, error messages, and status codes. + +### Step 4: Handle Failures + +If tests fail: + +1. Analyze the error messages. +2. Read the relevant source code. +3. Suggest fixes. +4. After fixes are applied, re-run to verify. + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| No collections found | "I didn't find any collections under `postman/collections/`. Run /postman:sync to create one, or /postman:search to find one in Postman." | +| Run failed to start | "The collection run failed to start. Check that the collection has at least one request with a valid URL." | +| Auth failure | "Postman returned 401. Your API key may be expired — run `postman login --with-api-key $POSTMAN_API_KEY`, or /postman:setup to reconfigure." | + +## Related Commands + +- Diagnose failures against your Postman collection with MCP tools -> `/postman:test` +- Send a single ad-hoc request -> `/postman:send-request` diff --git a/commands/search.md b/commands/search.md index 7596407..75d969d 100644 --- a/commands/search.md +++ b/commands/search.md @@ -59,7 +59,7 @@ Yes, you can get a user's email via the API. "created_at": "2026-01-15T10:30:00Z" } - Want me to generate a client for this API? (/postman:codegen) + Want me to generate a typed client for this API? (/postman:generate-client) ``` **When the answer is not found:** @@ -93,7 +93,7 @@ Found 3 collections related to "payments": - GET /revenue/summary -- Revenue dashboard ... and 7 more - Want details on any of these? Or /postman:codegen to generate a client. + Want details on any of these? Or /postman:generate-client to generate a typed client. ``` ## Error Handling diff --git a/commands/send-request.md b/commands/send-request.md new file mode 100644 index 0000000..f3f4d3d --- /dev/null +++ b/commands/send-request.md @@ -0,0 +1,56 @@ +--- +description: Send a single HTTP request with the Postman CLI, then report the response. +allowed-tools: Bash, Read, Glob, Grep +--- + +# /postman:send-request -- Send an HTTP Request + +Send an HTTP request with the Postman CLI. Ask the user for the URL and method, or detect them from context. + +## Prerequisites + +This command drives the Postman CLI (`postman request`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. + +## Workflow + +### Step 1: Determine Request Details + +Ask the user for: + +- The URL to send the request to +- The HTTP method (default: GET) +- Any headers, body, or auth needed + +If the user wants to send a request from a collection, find collection folders under `postman/collections/` and read the `*.request.yaml` files to extract the method and URL. Collections use the v3 folder format. + +### Step 2: Build and Execute + +```bash +postman request "" +``` + +- **With headers:** add `-H "Header: value"` +- **With a body:** add `-d '{"key": "value"}'` +- **With bearer auth:** add `--auth-bearer-token ""` +- **With API key:** add `--auth-apikey-key "" --auth-apikey-value ""` +- **With basic auth:** add `--auth-basic-username "" --auth-basic-password ""` +- **With an environment:** add `-e ./postman/environments/.json` + +Always show the exact command before running it. + +### Step 3: Report Results + +Parse the response and report the status code, response time, and body. Suggest fixes for errors (auth issues, connection problems, invalid URLs). + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| Missing URL | "What URL should I send the request to, and which HTTP method?" | +| Connection error | "I couldn't reach that URL. Check the host, port, and that the service is running." | +| Auth failure | "The request returned 401/403. Check the auth flags (bearer token, API key, or basic auth)." | + +## Related Commands + +- Run a full collection's tests -> `/postman:run-collection` diff --git a/commands/setup.md b/commands/setup.md index 6b49eb5..2b759a4 100644 --- a/commands/setup.md +++ b/commands/setup.md @@ -74,7 +74,8 @@ You're all set. Postman is connected and ready. Try these commands: /postman:search -- Find APIs across your workspaces /postman:sync -- Create or update collections from your code - /postman:codegen -- Generate typed client code from a collection + /postman:generate-spec -- Generate or update an OpenAPI spec from your code + /postman:generate-client -- Generate a typed client from a collection /postman:test -- Run collection tests /postman:mock -- Create a mock server /postman:docs -- Analyze and improve API documentation diff --git a/commands/trigger-flow.md b/commands/trigger-flow.md new file mode 100644 index 0000000..0083561 --- /dev/null +++ b/commands/trigger-flow.md @@ -0,0 +1,63 @@ +--- +description: Trigger (run) a deployed Postman Flow with inputs, and deploy-then-trigger it if it isn't deployed yet. +allowed-tools: Bash, Read +--- + +# /postman:trigger-flow -- Trigger a Flow + +Trigger a deployed Postman Flow from natural language, using the Postman CLI. + +## Prerequisites + +This command drives the Postman CLI (`postman flows ...`). If the CLI isn't installed, see https://learning.postman.com/docs/postman-cli/postman-cli-installation/. The CLI authenticates with the same `POSTMAN_API_KEY` this plugin uses — if it's not logged in, run `postman login --with-api-key $POSTMAN_API_KEY`. Reuse the existing CLI session; never authenticate twice. + +## Inputs (from the user's message) + +- The flow (a 24-character ID, or a name to resolve via `/postman:list-flows`) +- Any inputs / query params / headers / scenario +- The workspace ID (ask if a name needs resolving and you don't have it) + +## Workflow + +### Step 1: Resolve the Flow ID + +Use `/postman:list-flows` if given a name; disambiguate multiple matches; ask for the workspace if unknown. + +### Step 2: Build the Flags + +Translate natural language into flags: `-i k=v` (inputs), `-q k=v` (query params), `--headers k=v`, `-s ""`. + +### Step 3: Trigger + +Show the command, then run it: + +```bash +POSTMAN_CLI_SOURCE=cursor-plugin postman flows trigger -i amount=4200 +``` + +### Step 4: Report + +Report the **Run ID**, **HTTP status**, and **response body**. + +### Step 5: Handle Edge Cases + +- If the flow **is not deployed** → explain and offer to deploy it (via `/postman:deploy-flow`, explicit confirmation required), then re-trigger. +- If the trigger is **disabled** → offer `postman flows update --trigger on` (confirm first), then trigger. +- On a **non-2xx** response → surface the status + body and offer `/postman:get-flow-run --run-id ` for per-block detail. + +Confirm before any mutating action (deploy, enable trigger). + +## Error Handling + +| Error | Response | +|-------|----------| +| Postman CLI not installed | "This command needs the Postman CLI. Install it from https://learning.postman.com/docs/postman-cli/postman-cli-installation/ and try again." | +| Flow not found | "I couldn't find that flow. Run /postman:list-flows to see what's in the workspace." | +| Flow not deployed | "That flow isn't deployed yet. Want me to deploy it first with /postman:deploy-flow?" | +| Auth failure | "Postman returned 401. Run `postman login --with-api-key $POSTMAN_API_KEY`, or /postman:setup to reconfigure." | + +## Related Commands + +- Resolve a flow name to an ID -> `/postman:list-flows` +- Deploy a flow first -> `/postman:deploy-flow` +- Inspect a failed run -> `/postman:get-flow-run` diff --git a/commands/use-local.md b/commands/use-local.md new file mode 100644 index 0000000..4cfde83 --- /dev/null +++ b/commands/use-local.md @@ -0,0 +1,66 @@ +--- +description: Switch this plugin's Postman MCP server to LOCAL (stdio via the npx package), authenticated with your API key. +allowed-tools: Read, Write, Bash +--- + +# /postman:use-local -- Use the Local MCP Server + +Switch the Postman MCP server for this plugin from the remote hosted server to the **local** stdio package (`@postman/postman-mcp-server`, run via `npx`) by rewriting the plugin's own `.mcp.json` in place. Only change the transport (remote → local) — keep the plugin's API-key auth model; this plugin does not use OAuth. + +## Workflow + +### Step 1: Locate and Read `.mcp.json` + +Find this plugin's `.mcp.json` (the file at the plugin root, next to `.cursor-plugin/`) and read its current content so you can confirm the change: + +```bash +find "$PWD" -maxdepth 2 -name ".mcp.json" 2>/dev/null; cat ./.mcp.json 2>/dev/null +``` + +If you can't find it, ask the user for the path to the installed plugin's `.mcp.json`. + +### Step 2: Verify the API Key + +The local server authenticates with a Postman API key read from the environment (there is no OAuth for the local package): + +```bash +[ -n "$POSTMAN_API_KEY" ] && echo "POSTMAN_API_KEY is set" || echo "POSTMAN_API_KEY is NOT set" +``` + +If it isn't set, tell the user to run `export POSTMAN_API_KEY=` and add it to `~/.zshrc` or `~/.bashrc`, then restart the shell. They can get a key at https://postman.postman.co/settings/me/api-keys. Never hardcode the key into the file — it's read from the environment. + +### Step 3: Overwrite `.mcp.json` + +Write exactly this content to the target `.mcp.json`: + +```json +{ + "mcpServers": { + "postman": { + "command": "npx", + "args": ["-y", "@postman/postman-mcp-server@latest"], + "env": { + "POSTMAN_API_KEY": "${POSTMAN_API_KEY}" + } + } + } +} +``` + +`${POSTMAN_API_KEY}` is expanded by Cursor from your environment, and the spawned stdio process also inherits your shell environment. To match Cursor's default remote toolset (the `/mcp` Full endpoint), add `"--full"` to `args`. Use `"--code"` for Code mode or `"--minimal"` for the minimal toolset. + +### Step 4: Confirm and Restart + +Print the new file content back to the user, then tell them to reload the MCP server in Cursor (**Settings → MCP**, or restart Cursor) for the change to take effect. Remind them they can switch back to the hosted server at any time with `/postman:use-remote`. + +## Error Handling + +| Error | Response | +|-------|----------| +| `.mcp.json` not found | "I couldn't find the plugin's `.mcp.json`. What's the path to the installed plugin directory?" | +| `POSTMAN_API_KEY` not set | "The local server needs `POSTMAN_API_KEY`. Set it with `export POSTMAN_API_KEY=`, add it to your shell profile, and restart the shell." | +| npx / package fails | "Cursor couldn't start the local server. Make sure Node.js and `npx` are installed and on PATH." | + +## Related Commands + +- Switch back to the hosted server -> `/postman:use-remote` diff --git a/commands/use-remote.md b/commands/use-remote.md new file mode 100644 index 0000000..c7d75d1 --- /dev/null +++ b/commands/use-remote.md @@ -0,0 +1,67 @@ +--- +description: Switch this plugin's Postman MCP server to the REMOTE hosted server, authenticated with your API key. +allowed-tools: Read, Write, Bash +--- + +# /postman:use-remote -- Use the Remote MCP Server + +Switch the Postman MCP server for this plugin from the local stdio package back to Postman's **remote** hosted server by rewriting the plugin's own `.mcp.json` in place. This plugin authenticates the hosted server with an API-key `Authorization` header (a deliberate workaround for Cursor's OAuth login loop) — do **not** switch it to OAuth. + +## Workflow + +### Step 1: Locate and Read `.mcp.json` + +Find this plugin's `.mcp.json` (the file at the plugin root, next to `.cursor-plugin/`) and read its current content so you can confirm the change: + +```bash +find "$PWD" -maxdepth 2 -name ".mcp.json" 2>/dev/null; cat ./.mcp.json 2>/dev/null +``` + +If you can't find it, ask the user for the path to the installed plugin's `.mcp.json`. + +### Step 2: Verify the API Key + +The hosted server is reached with an API-key bearer header (no OAuth): + +```bash +[ -n "$POSTMAN_API_KEY" ] && echo "POSTMAN_API_KEY is set" || echo "POSTMAN_API_KEY is NOT set" +``` + +If it isn't set, tell the user to run `export POSTMAN_API_KEY=` and add it to `~/.zshrc` or `~/.bashrc`, then restart the shell. They can get a key at https://postman.postman.co/settings/me/api-keys. + +### Step 3: Overwrite `.mcp.json` + +Write exactly this content to the target `.mcp.json`: + +```json +{ + "mcpServers": { + "postman": { + "type": "http", + "url": "https://mcp.postman.com/mcp", + "headers": { + "Authorization": "Bearer ${POSTMAN_API_KEY}" + } + } + } +} +``` + +`${POSTMAN_API_KEY}` is expanded by Cursor from your environment. The `/mcp` path is the Full toolset (Cursor's default for this plugin); use `/code` for Code mode or `/minimal` for the minimal toolset. **EU accounts:** use the `https://mcp.eu.postman.com/...` host instead. Keep the API-key header — do not remove it and rely on OAuth. + +### Step 4: Confirm and Restart + +Print the new file content back to the user, then tell them to reload the MCP server in Cursor (**Settings → MCP**, or restart Cursor) for the change to take effect. Remind them they can switch to the local package at any time with `/postman:use-local`. + +## Error Handling + +| Error | Response | +|-------|----------| +| `.mcp.json` not found | "I couldn't find the plugin's `.mcp.json`. What's the path to the installed plugin directory?" | +| `POSTMAN_API_KEY` not set | "The hosted server needs `POSTMAN_API_KEY` for the bearer header. Set it with `export POSTMAN_API_KEY=` and restart the shell." | +| 401 after switching | "The hosted server returned 401. Your API key may be invalid or expired — generate a new one at https://postman.postman.co/settings/me/api-keys." | +| Tool count exceeds Cursor's limit | "The Full (`/mcp`) toolset can exceed Cursor's tool limit. Switch to `/code`, or disable unused tools in Settings → MCP." | + +## Related Commands + +- Switch to the local stdio package -> `/postman:use-local` diff --git a/skills/postman-knowledge/SKILL.md b/skills/postman-knowledge/SKILL.md index d81fe3b..de267bc 100644 --- a/skills/postman-knowledge/SKILL.md +++ b/skills/postman-knowledge/SKILL.md @@ -35,7 +35,8 @@ Core Postman concepts and MCP tool guidance for making better decisions when wor | Goal | Approach | |------|----------| | Push code changes to Postman | Spec Hub + sync (`createSpec` -> `syncCollectionWithSpec`) | -| Consume a Postman API in code | Read collection + codegen (`getCollection` -> generate client) | +| Generate an OpenAPI spec from your code | Scan the project's routes and write a spec (`/postman:generate-spec`) | +| Generate a typed client from a Postman collection | Read the collection and write client code (`/postman:generate-client`) | | Find an API | Use `searchPostmanElements`, then drill into details | | Test an API | Run collection (`runCollection` with environment) | | Fake an API for frontend | Mock server (`createMock` from collection with examples) | diff --git a/skills/postman-routing/SKILL.md b/skills/postman-routing/SKILL.md index f87c015..2b853a0 100644 --- a/skills/postman-routing/SKILL.md +++ b/skills/postman-routing/SKILL.md @@ -13,7 +13,16 @@ When a user mentions anything related to APIs, Postman, collections, specs, or A | User intent patterns | Route to | Command | |---------------------|----------|---------| | "sync", "update collection", "create collection", "import spec", "push to postman", "keep in sync", "deploy spec" | Sync collections with code | `/postman:sync` | -| "generate", "client", "code for", "wrapper", "SDK", "consume", "typed client", "api client" | Generate client code | `/postman:codegen` | +| "generate spec", "openapi", "swagger", "spec from code", "api spec", "document the api shape" | Generate an OpenAPI spec from code | `/postman:generate-spec` | +| "generate client", "client", "SDK", "typed client", "api client", "consume", "wrapper", "code for" | Generate a client from a collection | `/postman:generate-client` | +| "run collection", "run the collection", "newman", "run via CLI" | Run a collection with the CLI | `/postman:run-collection` | +| "send request", "curl", "hit this endpoint", "make a request", "call this URL" | Send an HTTP request | `/postman:send-request` | +| "list flows", "what flows", "find a flow" | List Postman Flows | `/postman:list-flows` | +| "trigger flow", "run flow", "kick off the flow", "execute the flow" | Trigger a Postman Flow | `/postman:trigger-flow` | +| "deploy flow", "make the flow triggerable", "publish the flow" | Deploy a Postman Flow | `/postman:deploy-flow` | +| "flow run", "why did the flow fail", "inspect run", "run id" | Inspect a Flow run | `/postman:get-flow-run` | +| "use local", "local mcp", "run mcp locally", "stdio server" | Switch to the local MCP server | `/postman:use-local` | +| "use remote", "hosted mcp", "remote server", "switch back to hosted" | Switch to the remote MCP server | `/postman:use-remote` | | "find", "search", "what endpoints", "is there an API for", "show me", "what's available", "discover", "list APIs" | Discover APIs | `/postman:search` | | "test", "run tests", "check if", "validate", "test results", "failing tests" | Run collection tests | `/postman:test` | | "mock", "fake API", "stub", "mock server", "frontend needs", "mock URL" | Create mock server | `/postman:mock` | @@ -26,13 +35,13 @@ When a user mentions anything related to APIs, Postman, collections, specs, or A ## Routing Priority 1. **Exact command match** -- If the user types `/postman:sync`, run that command directly -2. **Strong intent match** -- If the user says "generate a TypeScript client for the payments API", that's clearly `/postman:codegen` +2. **Strong intent match** -- If the user says "generate an OpenAPI spec from my API code", that's clearly `/postman:generate-spec` 3. **Contextual match** -- If the user is working on a spec and says "push this to Postman", that's `/postman:sync` -4. **Ambiguous** -- If intent is unclear, ask: "I can help you sync collections, generate client code, search for APIs, run tests, create mocks, improve docs, or audit security. What do you need?" +4. **Ambiguous** -- If intent is unclear, ask: "I can help you sync collections, generate an OpenAPI spec, search for APIs, run tests, create mocks, improve docs, or audit security. What do you need?" ## When to Use Commands vs. Raw MCP Tools -- **Use commands** for multi-step workflows (syncing, codegen, testing). Commands handle the full flow including error handling, async polling, and result formatting. +- **Use commands** for multi-step workflows (syncing, spec generation, testing). Commands handle the full flow including error handling, async polling, and result formatting. - **Use raw MCP tools** for simple one-off queries ("What workspaces do I have?" -> just call `getWorkspaces`). ## Common Compound Workflows