Automation tools
Every action the app can do to a workspace is a JSON tool. All frontends share the same tool table: the CLI today, an MCP server later. This page lists all 71 tools. It comes from the output of postguy-cli tools --json, which is the source of truth. Run it to get the schemas in machine-readable form.
postguy-cli tools # name, safety and title, one line per tool
postguy-cli tools --json # {"tools":[{name,title,description,inputSchema,readOnly,destructive}]}
See the CLI reference for the commands that run the tools.
How calls work
- Arguments are one JSON object.
nullor no--jsonmeans{}. Any other JSON type is refused with "argument(arguments)must be a JSON object". - Unknown arguments are refused. The error lists what is allowed:
tool: unknown argument `x`; allowed: a, b. Every schema hasadditionalProperties: false. - Missing required arguments are refused:
tool: missing required argument `x`. Types are not checked up front. A wrong type fails inside the tool with a message like "argumentxmust be ..., got ...". - Error strings say what was wrong and what is allowed. The ones you will meet most:
unknown tool `x`; run `postguy-cli tools`no workspace is open; call workspace_open firstcollection `ID` not found in the workspace(the same shape for every entity kind)PATH is outside the allowed directory ROOT: the same text whether or not the path exists.
- Ids are opaque strings. Get them from the list tools (
collection_list,env_list,run_list, ...) or from the result of a create tool. Postguy generates UUIDs. Ids from imported files can be shorter. - Deletes go to the workspace trash. Destructive tools are flagged
destructiveand move data to.trash/instead of erasing it.history_clear,console_clearandcookies_*clear their own stores. See Workspace format. - Paths in arguments (
path,out,data,paths) go through--rootconfinement when a root is set. Relative paths resolve against the root, and a path outside it is refused. Without--root, nothing is confined and relative paths resolve against the current directory. - Response bodies are capped at 1 MiB in tool results (
request_send,response_get,response_render_body). Useresponse_saveto get the full decoded body. - Cancelling:
request_send,request_cancelandcollection_rundo not hold the session lock while they run. Sorequest_cancelcan stop an in-flight send from another thread. The CLI runs steps one after another, so this only matters for embedders.
One call is one process
Every postguy-cli call starts a new process with no workspace open. Any tool other than workspace_open fails with no workspace is open; call workspace_open first. For more than one step, use run --script. It runs a list of steps in one process and one session.
A script file cannot pass one step's result to the next step, because arguments are static JSON. Tools take ids, not names. For name-based flows, pick one of these:
- Import something, then read the ids back with a list tool (
import_textorimport_file, thencollection_list). Do this in a secondrun --scriptcall, or read the printed result lines. - Let an agent read each step's output and generate the next script.
- Use
run --collection NAME --workspace DIR, which resolves names for you (see the CLI reference).
run --script step format
A script is a JSON array of steps, or an object with a steps array. Each step is {"tool": "<name>", "args": {...}}; args is optional. Steps run in order. The first step must be workspace_open, unless the tools you call need no workspace.
[
{"tool": "workspace_open", "args": {"path": "work"}},
{"tool": "collection_create", "args": {"name": "Smoke"}},
{"tool": "collection_list", "args": {}}
]
Output is one line per step on stdout, {"step":0,"tool":"workspace_open","ok":true,"result":{...}}, then {"ok":true,"steps":3}. A failing step prints {"step":1,"tool":"...","ok":false,"error":"..."} on stderr, stops the run and exits 1.
This send flow fits in one script. The collection and request must already exist; use their real ids:
[
{"tool": "workspace_open", "args": {"path": "work"}},
{"tool": "request_send", "args": {"collection": "COLLECTION_ID", "request": "REQUEST_ID"}},
{"tool": "response_get", "args": {}},
{"tool": "history_list", "args": {"limit": 5}}
]
Tool reference
In the tables, an argument in bold is required. Safety is read-only (changes nothing), write, or destructive (deletes or clears data).
Workspace
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
workspace_open | write | Create the folder if needed and open it; takes the workspace lock. Paths stay inside --root when one is set. | path — workspace folder |
workspace_info | read-only | Path, counts and the active environment id of the open workspace. | none |
workspace_export_zip | write | Zip the workspace documents (not .postguy secrets/cookies/cache and not .trash); path resolves inside --root. | out — zip file path |
import_zip | write | Reads .json entries (collection/environment/globals) from a zip through the normal importers; unsafe paths are refused, arbitrary entries are skipped. | path — zip file path; replace (boolean) — replace same-id documents instead of suffixing |
Collections and folders
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
collection_list | read-only | Collections in sidebar order with id, name and counts. | none |
collection_get | read-only | The full collection JSON. | collection — collection id |
collection_create | write | A new empty collection with a generated id. | name — collection name |
collection_rename | write | New name; empty names are refused. | collection — collection id; name — new name |
collection_duplicate | write | Deep copy with fresh ids for every item. | collection — collection id; name — name for the copy (default: <name> Copy) |
collection_delete | destructive | Moves the collection file to the workspace trash and drops its secrets. | collection — collection id |
folder_create | write | Inside the collection root or another folder. | collection — collection id; parent — parent folder id (omit for the collection root); name — folder name |
folder_rename | write | New name; empty names are refused. | collection — collection id; folder — folder id; name — new name |
folder_delete | destructive | Deletes the folder and its contents; the subtree JSON is parked under .trash/item-<time>.json. | collection — collection id; folder — folder id |
Requests
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
request_create | write | HTTP, gRPC or WebSocket; the protocol is fixed for the request's life. | collection — collection id; folder — folder id (omit for the collection root); kind — http | grpc | websocket; name — request name (default New Request) |
request_get | read-only | The request JSON including its kind-specific body. | collection — collection id; request — request id |
request_update | write | Replaces name, description and/or the kind-specific definition (the serialized RequestKind object). | collection — collection id; request — request id; name — new name; description — new description; definition (object) — serialized RequestKind ({"type":"http",...}) |
request_move | write | Into a folder, or the collection root when folder is omitted. | collection — collection id; request — request id; folder — target folder id (omit for the collection root) |
request_duplicate | write | Deep copy into the same parent with fresh ids. | collection — collection id; request — request id; name — name for the copy (default: <name> Copy) |
request_delete | destructive | Removes it from the collection; the JSON is parked under .trash/item-<time>.json. | collection — collection id; request — request id |
request_send | write | Runs the full send pipeline (variables, inherited auth, cookies, proxy, redirects, decompression) and records History, Console and the response cache. | collection — collection id; request — request id; environment — environment id (default: the workspace's active environment) |
request_cancel | write | Cancels the send started by request_send for that request id, or the most recent send (last), or a collection run (run:<collection id>). | sendId — request id passed to request_send, last, or run:<collection id> |
snippet_generate | read-only | One HTTP request as cURL, raw HTTP, fetch, Python requests, Go, Rust reqwest, PowerShell or Node axios; variables stay unresolved. gRPC/WS snippets are not implemented yet. | collection — collection id; request — request id; language — curl (default), raw-http, fetch, python, go, rust, powershell or node-axios; indent (integer, min 0) — spaces per level; 0 means a tab (default 2); include_boilerplate (boolean) — wrap the request in imports/main (default true) |
gRPC, WebSocket and OAuth
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
grpc_describe | read-only | Loads the request's service definition (proto set, inline files, or server reflection listing every service) and returns services, methods with streaming flags, and every reachable message's fields and types. | collection — collection id; request — request id |
grpc_example_message | read-only | A default JSON object for the request method's input type. | collection — collection id; request — request id |
grpc_invoke | write | Calls one unary method with JSON input (defaults to the request's stored message); returns the response JSON and metadata. Streaming methods use grpc_stream; grpc_send runs scripts and tests. | collection — collection id; request — request id; message (object) — request message JSON (defaults to the stored message) |
grpc_send | write | Invokes a saved gRPC request through the full pipeline: pre-invoke script, variables, inherited auth as metadata, the call (unary or streaming, chosen from the method), on-message and post-response scripts and the Test tab. A non-OK gRPC status is a result, not an error. | collection — collection id; request — request id; environment — environment id (default: the active environment) |
grpc_check_message | read-only | Lists the JSON keys of a request message that the method's input type does not define, with their byte ranges. Defaults to the stored message. | collection — collection id; request — request id; message — request message JSON text (default: the stored message) |
grpc_set_proto | write | Copies the .proto files (and the imports they pull in) into a workspace proto set, compiles it, and stores it as the request's service definition. Creates no collection. Paths resolve inside --root. | collection — collection id; request — request id; paths (array) — the .proto files, together in one folder tree |
grpc_stream | write | Calls a server-, client- or bidi-streaming method with an array of JSON messages and returns every response message in arrival order (cap 10,000). Unary methods use grpc_invoke. | collection — collection id; request — request id; messages (array) — request messages in order (server streaming uses the first) |
proto_import | write | Copies the .proto files (and the imports they pull in) into a workspace proto set under protos/<name>/, compiles it, and creates a collection with one gRPC request per service method (url {{grpcUrl}}). Compile errors name file:line:column. Paths resolve inside --root. | paths (array) — the .proto files to import, together in one folder tree; name — proto set and collection name (default: the first file's name); replace (boolean) — move an existing set of the same name to the trash instead of suffixing the new one |
ws_connect | write | Connects a saved WebSocket request (variables resolved at connect), returns a session id. Events are read with ws_messages. | collection — collection id; request — request id |
ws_send | write | Send text or base64 binary to an open session; the echo/event log records it. | session — session id; text — text message; binary_base64 — base64 binary message |
ws_messages | read-only | Events after since (default 0) with sequence, direction, kind, text, bytes and close/detail; includes sent, received and network rows. | session — session id; since (number) — last sequence number already read |
ws_disconnect | write | Send a close frame and end the session. | session — session id; code (number) — close code (default 1000); reason — close reason |
oauth2_token | write | Runs client_credentials/password/authorization_code (with optional PKCE verifier) against the request's OAuth 2.0 auth, or refreshes it; stores the tokens in the secrets file and updates the request auth. | collection — collection id; request — request id; mode — grant | refresh | code; code — authorization code for mode=code; verifier — PKCE verifier for mode=code with PKCE |
Environments and globals
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
env_list | read-only | Id and name in order-file order, plus which one is active. | none |
env_create | write | An empty environment with a generated id. | name — environment name |
env_rename | write | New name; empty names are refused. | environment — environment id; name — new name |
env_duplicate | write | Deep copy with a fresh id; secret values copy too. | environment — environment id; name — name for the copy |
env_delete | destructive | Trashes the file, clears its secrets, and clears the active id when it pointed here. | environment — environment id |
env_set_active | write | environment: null clears it. | environment — environment id or null |
env_get | read-only | The environment JSON with secret values rehydrated for the caller. | environment — environment id |
env_set_var | write | Creates the row or updates it; secret: true stores the value outside the environment file. | environment — environment id; key — variable name; value — value (empty clears it); secret (boolean) — store the value in the secrets file; enabled (boolean) — row participates (default true); description — row description |
env_unset_var | destructive | Removes the row and its stored secret. | environment — environment id; key — variable name |
globals_get | read-only | The globals file with secret values rehydrated. | none |
globals_set_var | write | Creates or updates one globals row (secret values split out). | key — variable name; value — value (empty clears it); secret (boolean) — store the value in the secrets file; enabled (boolean) — row participates (default true); description — row description |
variables_resolve | read-only | Resolves {{variables}} and reports each hit's source scope, secret flag and unresolved state. | text — template text; collection — collection id for collection variables; environment — environment id (default: active) |
runtime_variables | write | The runtime variables scripts set with pg.setVar/bru.setVar for a collection (session-lived, never saved). Returns them as an object; with clear they are dropped afterwards. | collection — collection id; clear (boolean) — drop the variables after reading them |
Import and export
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
import_text | write | Postman collection (v2.0/v2.1), environment or globals JSON, OpenAPI 3 / Swagger 2 (JSON or YAML), HAR 1.2, or cURL commands; auto-detected, name clashes get a suffix unless replace is set; returns the ImportReport. | text — the JSON/YAML document or cURL command text; format — "auto" (default): the format is detected; replace (boolean) — replace a same-id collection/environment or the existing globals instead of suffixing/refusing; folders — OpenAPI folder layout: "tags" (default) or "paths" |
import_file | write | Size-capped (100 MB) read, then the same mapping as import_text; the path resolves inside --root. | path — file path; replace (boolean) — replace instead of suffixing; folders — OpenAPI folder layout: "tags" (default) or "paths" |
import_bruno | write | Imports a Bruno collection folder (it must contain bruno.json): requests become a collection, environments/*.bru become environments (secret values go to the secrets store), and every other file (scripts, images) is copied into the collection's Assets keeping its relative path. Returns the collection, environments and assets outcome. The path resolves inside --root. | path — the Bruno collection folder; replace (boolean) — replace instead of suffixing |
export_collection | write | Postman v2.1 JSON or the Postguy native file; writes out or returns the JSON. | collection — collection id; format — "postman" (default) or "native"; out — file path to write (inside --root) |
export_environment | write | Postman environment shape; secret values are omitted unless include_secrets is set. Writes out or returns the JSON. | environment — environment id; out — file path to write; include_secrets (boolean) — include secret values |
export_globals | write | Postman globals shape; secret values are omitted unless include_secrets is set. Writes out or returns the JSON. | out — file path to write; include_secrets (boolean) — include secret values |
Assets
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
asset_list | read-only | The files of a collection's Assets tab (path, size, modifiedMs), sorted by path. Scripts read them through pg.assets/require/fs, and bodies through {{% base64(file('path')) %}}. | collection — collection id |
asset_import | write | Copies files and folders (kept with their structure) into the collection's assets under dir; returns imported and skipped (with reasons). Name clashes get a (2) suffix unless replace is set. Paths resolve inside --root. | collection — collection id; paths (array) — files and folders to import; dir — destination folder inside the assets (default: the root); replace (boolean) — overwrite same-named assets instead of suffixing |
asset_delete | destructive | Removes one asset file (a .bak copy stays beside it) and any folders left empty. | collection — collection id; path — asset path, e.g. images/a.jpg |
asset_rename | write | Renames an asset path; refuses when the target already exists. Returns the new AssetInfo. | collection — collection id; from — current asset path; to — new asset path |
Runner
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
collection_run | write | Runs the collection (or one folder, or an ordered subset of requests) sequentially: scripts, tests, iterations and CSV/JSON data rows, delay, stop on error. gRPC and WebSocket requests are skipped. The result is stored (newest 20 per collection) and returned; cancel it with request_cancel run:<collection id>. | collection — collection id; folder — folder id: run only this folder; environment — environment id (default: the workspace's active environment); iterations (integer, min 1) — iteration count (default: one per data row, or 1; at most 10000); delay_ms (integer, min 0) — pause between requests in ms (at most 600000); data — path of a CSV (header row) or JSON (array of objects) data file, inside --root; stop_on_error (boolean) — stop after the first request error, script failure or failed test; requests (array) — request ids to run, in this order (default: every request in tree order) |
run_list | read-only | The collection's stored runs, newest first, with totals and pass/fail. | collection — collection id |
run_get | read-only | The full result of a stored run: iterations, requests, tests and failures. | collection — collection id; run — run id from run_list |
run_export | write | Renders a stored run as json, junit (XML), html (one self-contained file), csv (requests table), xlsx (Summary, Requests and Tests sheets) or pdf and writes it to out (inside --root). Datetimes use the local time zone. | collection — collection id; run — run id from run_list; format — json, junit, html, csv, xlsx or pdf; out — file path to write |
Responses, cookies, history and console
| Tool | Safety | Purpose | Arguments |
|---|---|---|---|
response_get | read-only | The newest (or id) cached response: status, headers, body (base64 plus text when UTF-8, capped at 1 MiB), size and timings. | id — history id (omit for the newest response) |
response_save | write | Writes the DECODED body atomically to path inside --root. | id — history id (omit for the newest response); path — file path |
response_render_body | read-only | Returns the body as UTF-8 text (with replacement markers when invalid) or base64, capped at 1 MiB. | id — history id (omit for the newest response); format — "text" (default) or "base64" |
cookies_list | read-only | Every jar cookie with domain, path, flags and expiry, plus the script allowlist. | none |
cookies_set | write | Stores one raw Set-Cookie value for a URL (domain/path/secure/expiry rules apply) and persists the jar. | url — the URL the cookie belongs to; setCookie — one Set-Cookie header value |
cookies_delete | destructive | Deletes by (domain, path, name) and persists the jar. | domain — cookie domain; path — cookie path; name — cookie name |
cookies_clear | destructive | Deletes every cookie and persists the empty jar. | none |
history_list | read-only | The newest sends, newest last (default 50). | limit (integer, min 1) |
history_open | read-only | One entry by id, including the as-sent request snapshot. | id — history id |
history_clear | destructive | Empties history.jsonl atomically. | none |
console_get | read-only | Newest-last console entries, optionally filtered by level or kind (default 100). | limit (integer, min 1); level — "info" | "warning" | "error"; kind — "request" | "log" | "warning" | "error" |
console_clear | destructive | Drops every retained console entry (the history file is untouched). | none |
Notes on some arguments:
ws_messagessinceandws_disconnectcodeare declared as strings in the schema, but the implementation reads JSON numbers ("since": 12). A string value is ignored and the default is used.env_set_activetakes{"environment": null}to clear the active environment; the schema declares the argument as a string.request_canceltakes the request id given torequest_send, the wordlast, orrun:followed by a collection id to cancel acollection_run.snippet_generatelanguages:curl(default),raw-http,fetch,python,go,rust,powershell,node-axios. Variables stay unresolved in the output. See Code snippets.collection_runwithiterationsomitted runs once per data row, or once without data. See Collection runner.
MCP server (planned)
postguy-cli mcp is not a subcommand: the CLI prints its usage and exits with code 2. The feature is tracked as planned in Feature status.The plan, from the project rules:
- It is a stdio server started as
postguy-cli mcp, over the same tool table as above. - It is opt-in: the app, the CLI and the installers never start it or register it with any client. The Windows installer explicitly registers no MCP server.
- Any future network transport would be off by default, bound to loopback and token-authenticated.
Until it ships, an agent can run postguy-cli tools --json to learn the schemas, and postguy-cli call or run --script to run them.