Kurlo
Kurlo
The open-source Postman alternative your AI agent can drive. No account, no paid plan, no telemetry. Collections live as YAML in your Git repo.
Download · Website · Docs · MCP server · Compare

Why Kurlo
Free for a team of any size. There is no paid plan to grow into and no account to create. A team shares a workspace through any Git host, and every request is a readable YAML file that gets reviewed in the same pull request as the API change.
Your Postman collections keep working. Import a Postman, Insomnia, Bruno, OpenAPI or HAR file.
pm.test,pm.expectwith chai,pm.sendRequestandrequire('lodash')run as they were written.Your AI agent can use it.
kurlo mcplets Claude Code, Cursor, Codex and any other MCP client run your saved requests with their auth and tests, write new requests and tests, and explain why the last call failed. Secrets are sent to the API but never shown to the model.See what the browser will do. Send a request with a browser's CORS and CSP rules and get the error before your users do. Postman, Insomnia and Bruno do not do this.
Small and native. Built with Go and the system WebView instead of Electron, so the macOS download is 22 MB and the Linux one is 11 MB.
Kurlo | Postman | Insomnia | Bruno | |
Free plan | ✅ Every feature, any team size | 1 user | Up to 3 Git Sync users | Private Git hosts need Pro |
Account needed | ✅ No | For collections | Beyond Scratch Pad | No |
Collections in your Git repo | ✅ | Native Git in the desktop app | ✅ | ✅ |
Postman | ✅ Run as written | Native | Compatibility layer | Converted to |
Mock server | ✅ Local, no cap | Cloud, needs an account | 1,000 requests/mo free | ✅ Local |
MCP | ✅ Client and server | Client | Client | Community servers |
Browser CORS and CSP checks | ✅ | — | — | — |
Checked against vendor pricing pages on 15 October 2026. Details and sources: vs Postman, vs Insomnia, vs Bruno.
If Kurlo saves you time, a ⭐ helps other people find it.
Related MCP server: Reqly
Download
Grab the latest build from the releases page.
Platform | Installer |
macOS (Apple Silicon + Intel) |
|
Windows 10/11 (x64, arm64) |
|
Linux (x64) |
|
Every release ships SHA256 checksums and minisign signatures, and the in-app updater refuses any binary that fails either check.
The command line (kurlo run for CI, kurlo mcp for AI agents) is also on npm as @kurlo/cli, with prebuilt binaries for macOS, Linux and Windows on x64 and arm64. It does not need the desktop app:
npx -y @kurlo/cli --versionGuides, the scripting reference, and the YAML workspace format live in the documentation site.
Features
Requests
All HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Query params, headers, body (JSON, form-data, x-www-form-urlencoded, raw text/XML/HTML, binary file)
cURL import — paste a curl command into the URL field, it parses automatically
Bulk edit for params, headers and form fields — switch the table to a
key: valuetext area and backGraphQL, Server-Sent Events, WebSocket, Socket.IO, gRPC, and MCP request types — an MCP call discovers the server's tools, resources and prompts, seeds the arguments from the tool's schema, and shows the raw JSON-RPC exchange
Postman, Insomnia, Bruno/OpenCollection, OpenAPI/Swagger, HAR, cURL, and all-data backup import paths
OpenAPI/Swagger imports from a link as well as a file — paste the spec URL and Kurlo fetches it and builds the collection
Postman, OpenAPI, OpenCollection, and all-data backup export paths
Authentication
Bearer Token
Basic Auth
Digest Auth — MD5, SHA-256 and SHA-512-256 plus their
-sessvariants, withqop=authandauth-intAPI Key — in header or query string
OAuth 2.0 — Client Credentials, Authorization Code (with PKCE), Password, and Device Code grants; loopback browser sign-in, refresh tokens, and automatic token refresh before each send
AWS Signature v4
Client certificates (mutual TLS), per request or inherited from a collection
Per-request and collection defaults with inheritance
Scripting — pre-request and test scripts in sandboxed JavaScript, with legacy Tengo support:
// pre-request: inject a header
pm.request.headers.set("X-Client", "kurlo")
// pre-request: rewrite and sign the body
pm.request.body.update(JSON.stringify({ ...pm.request.body.json(), nonce: pm.crypto.randomHex(8) }))
// test: assert status and shape
pm.test("status is 200", () => pm.response.to.have.status(200))
pm.test("has an id", () => pm.response.to.have.jsonSchema({ type: "object", required: ["id"] }))require resolves bundled stand-ins for lodash, ajv, tv4, uuid, crypto-js, and chai, so imported Postman scripts keep working. pm.sendRequest makes an HTTP call from a script, and pm.execution.skipRequest() skips the send.
Environments & Variables
Multiple environments per workspace, switch with one click
Matrix view — every variable as a row, every environment as a column, edited in place
{{variable}}template syntax in URLs, headers, params, body, auth fieldsSet variables from test scripts (
pm.variables.set,pm.environment.set)Manual-save and autosave modes both cover request and environment edits
Workspaces & Collections
Multiple workspaces for separate projects or clients
Collections with nested folder hierarchy and empty-folder preservation
Drag-and-drop organisation
Request history — every send on its own page, request and stored response side by side, reopenable in the editor (14-day retention, 1000 entries)
Collection runner — sequential or parallel, data files, iterations, an HTML report, and the last run of every collection kept
Git-backed YAML workspaces with diagnostics, conflict helpers, and local-only secrets
CLI runner —
npx -y @kurlo/cli run ./workspace --env CIexecutes requests and their test scripts for CI, with data-driven iterations (--data), pretty/JSON/JUnit reporters, variable export, and a non-zero exit code on failure
AI agents (MCP server) — the Kurlo binary is also a Model Context Protocol server, so Claude Code, Codex, Cursor, Claude Desktop or any other MCP client can list your collections and environments, run saved requests and whole collections with their auth, scripts and tests, and send one-off calls with your {{variables}}. It can also keep the workspace up to date: add and change requests with their pm.* tests, save responses as examples and set environment variables, in the same YAML the app writes, never storing a secret. It reads the last request you sent from the app, so "why did that fail?" needs no copying. Secret values are sent to the API but masked as [secret] in everything the model sees, and environments you mark protected are off limits. One command sets up every client on the machine:
npx -y @kurlo/cli mcp install --env StagingAdd --project to write a repository's shared .mcp.json and .cursor/mcp.json instead, so the whole team gets the server by cloning. Manual setup, the tools and the flags are covered in the MCP server guide.
Response examples — save any response as a named example on its request: the status, headers and body it came back with, alongside the request that produced it. Secrets are redacted on capture, a clean body is stored byte for byte, and examples ride along through Postman, OpenCollection, HAR and OpenAPI imports and exports. A response can be diffed against an example instead of against the previous send.
Cookies — a per-workspace cookie jar with a per-domain editor, disableable per request.
Cookie sync: pair Kurlo with the in-repo browser extension (
apps/desktop/extension, Chromium + Firefox) and the session you already have in the browser is the session Kurlo sends with. A loopback-only bridge that stays off until you turn it on, an approval you give in Kurlo by matching a six-digit code, and a per-domain allowlist enforced on both sides. Cookies travel one way: browser into Kurlo.
Mock server — serve a collection's saved examples over HTTP on a local port, so a client can be built against an endpoint that does not exist yet. Routing is by method and the example's path template (/orders/:id), a recorded query narrows which example answers, and a live log shows what the client asked for and which example replied. Loopback only; CORS preflight is answered for any origin.
Response viewer
Syntax-highlighted body with line numbers
Paginated rendering for large responses (512 KB pages, once a response exceeds 10 MB)
Full-text search with match navigation
Save response to file, copy to clipboard
Headers table, test results, script logs — all in one panel
Preview tab for HTML, images and PDFs; binary bodies are detected rather than rendered as mojibake
Diff against the previous response or a saved example
Timeline with connection details and the request as it went on the wire, secrets masked, one block per redirect hop
Realtime panels for SSE, WebSocket, Socket.IO, and gRPC responses
Code generation — copy the current request as a runnable snippet in one of 14 targets: cURL, HTTPie, JavaScript fetch, Node.js fetch, Axios, Python requests, Go net/http, Java OkHttp, C# HttpClient, PHP cURL, Ruby Net::HTTP, Swift URLSession, Kotlin OkHttp, and Rust reqwest. Secret variables stay as {{name}} placeholders.
Browser request emulation — send with a browser's rules instead of a client's: an Origin header, CORS preflight and response checks, and Content Security Policy enforcement, so a request can reproduce what the browser will do before the frontend is written.
Settings per request: HTTP version (auto / 1.1 / 2), SSL verification, redirect policy (follow, preserve method, preserve auth), cookie jar, timeout, proxy, URL encoding.
Keyboard-first: all actions have configurable shortcuts. A command palette (Cmd/Ctrl K) finds requests and runs commands, quick send (Cmd/Ctrl Enter), focus the URL (Cmd/Ctrl L), tab switching (Cmd/Ctrl 1–8, with 9 for the last tab). Kurlo shows Cmd on macOS and Ctrl on Windows and Linux.
Dark and light themes, with multiple built-in variations.
Local-first storage — the local Kurlo profile and its secrets are encrypted at rest with AES-256-GCM. The key is stored in the OS credential store when available and also kept as a 0600 recovery file in Kurlo's app-data directory. Git-backed workspace YAML is intentionally human-readable; secret values are replaced with local placeholders.
Building from source
Prerequisites
Go 1.25+
Node.js 22.12+
Wails v2 —
go install github.com/wailsapp/wails/v2/cmd/wails@latestmacOS: Xcode Command Line Tools
Windows: NSIS (for installer builds) and Windows SDK (for MSIX packaging/signing tools)
Linux:
libgtk-3-dev,libwebkit2gtk-4.1-dev
Dev mode (hot-reload frontend + Go backend):
git clone https://github.com/stormhop/kurlo
cd kurlo
npm install
make devProduction build for the current platform:
make buildAll platforms (requires each platform's toolchain):
make build-allRun the full check suite — frontend types, unit tests, gofmt, go vet, and race-enabled Go tests:
make checkSee make help for every available target.
Project layout
apps/desktop/ Wails v2 desktop application
apps/desktop/main.go Entry point, window config, native menus
apps/desktop/cmd/kurlo/ Headless CLI (run, mcp) published to npm as @kurlo/cli
apps/desktop/internal/
api/ HTTP executor, auth, request store, state
api/auth/ Bearer, Basic, Digest, API Key, OAuth2, AWS SigV4
model/ Shared Go types (request, response, auth config)
script/ JavaScript/Tengo scripting engines + pm.* API
apps/desktop/frontend/src/
App.svelte Root shell and layout
lib/stores/app.svelte.ts Composed app view-model
lib/stores/features/ Feature slices for requests, collections, Git, import/export, etc.
lib/components/ UI components
lib/backend.ts Wails bridge type definitions
apps/desktop/extension/ Cookie Sync browser extension (MV3 + Firefox event page)
apps/web/ Astro Starlight documentation site
npm/cli/ The @kurlo/cli npm launcher; scripts/build-npm-packages.mjs adds the binaries
schemas/ Public Git/YAML workspace JSON Schema
perf/ Generated performance fixtures (ignored by Git)Scripting API reference
Scripts run in a sandboxed JavaScript environment by default, or in the legacy Tengo engine for existing requests. Imports, filesystem, process, and network access are disabled. Execution timeout: 2 seconds by default, configurable per request up to 60.
The full surface — every method, the variable-scope precedence rules, and the Chai-style assertion aliases — is in the scripting API reference. The short version:
Surface | What it covers |
|
|
|
|
|
|
|
|
| The current data-row value in a data-driven run (read-only) |
|
|
|
|
| MD5/SHA digests, HMAC, base64, |
| A synchronous HTTP call through the regular request engine |
| From a pre-request script, skips the send — reported as skipped, not failed |
| Register a named assertion |
|
|
|
|
| Output to the Scripts panel |
require resolves bundled stand-ins for lodash, ajv, tv4, uuid, crypto-js, and chai. There is no event loop: setTimeout, async and await are not available, and pm.sendRequest's callback runs immediately.
Contributing
Bug reports, feature requests, and pull requests are welcome. Start with CONTRIBUTING.md — it covers the dev setup, what CI enforces, and how to scope a change. Everyone taking part is expected to follow the Code of Conduct.
Found a security problem? Please don't open a public issue — see SECURITY.md for private reporting instead.
License
Available Tools
15 toolscreate_collectionCreate a collectionA
Create an empty collection in the workspace for save_request to put requests in.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Collection name, for example the service or API it covers. | |
| workspace | No | Workspace name, when the folder holds more than one. | |
| description | No | Optional description. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, openWorldHint=false and idempotentHint=false, so the agent knows this is a local, non-destructive write. The description adds only that the result is an empty collection; it doesn't say what happens on a name collision, which matters given idempotentHint=false, nor whether the collection is immediately usable by save_request.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler. The operation is named first and the rationale for it follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter local write with full schema coverage and no output schema, the description covers the essentials. The remaining minor gap is duplicate-name behavior, which an agent might guess wrong given idempotentHint=false.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters (name, workspace, description) are documented in the schema, so the schema does the heavy lifting. The description adds no semantics beyond that, which is the baseline case for a fully-documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Create an empty collection in the workspace') and adds scope ('empty') plus the downstream consumer ('for save_request to put requests in'). That distinguishes it from the read/mutation siblings, though it doesn't explicitly contrast with delete_request or list_requests.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for save_request to put requests in' implies the workflow context: create a container first, then save requests into it. No explicit exclusions or alternatives are named, but among the siblings there is no competing create-container tool, so the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_requestDelete a saved requestADestructiveIdempotent
Delete a saved request and its examples from the workspace. In a Git workspace the deletion shows up in the next commit and can be restored from history.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes | Request id or path (Collection/Folder/Name). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered; the description adds genuine value beyond that by disclosing that examples are deleted along with the request and that deletion surfaces in the next Git commit and is restorable from history. It stops short of stating permission requirements or what happens outside a Git workspace.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, with the mutation and its cascade front-loaded before the recovery caveat. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive mutation with full annotation coverage and no output schema, the description covers cascade effects and recoverability, which is most of what an agent needs. It omits permission/prerequisite expectations and the permanence of deletion in non-Git workspaces (only implied).
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'request' parameter is documented as an id or Collection/Folder/Name path, so the schema carries the load. The description adds nothing about accepted path forms or how an ambiguous name is resolved, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (delete) and resource (saved request) plus the cascading scope ('and its examples'), which an agent can immediately separate from save_request, get_request, and list_requests. The Git-workspace clause further scopes what the operation affects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Deleting a saved request is self-evidently the inverse of save_request, and the Git clause hints at when recovery is possible, but the description never explicitly says when to use this versus alternatives like create_collection or how to handle a request that merely needs editing. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnose_last_failureDiagnose a failed requestARead-only
Explain why a request sent from the Kurlo app failed. Without entry it takes the most recent request that got no response, a 4xx or 5xx status, or failing tests. Returns the status, error, failed tests, the {{variables}} nothing sets, how the response differs from the saved example, and hints for the likely cause. Secrets are masked.
| Name | Required | Description | Default |
|---|---|---|---|
| entry | No | History entry id from list_history. Defaults to the most recent failure. | |
| environment | No | Environment to check variables against. Defaults to the one active in the app. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnlyHint/openWorldHint annotations by enumerating what the result contains (status, error, failed tests, unset variables, diff versus saved example, cause hints) and by disclosing that secrets are masked. For a read-only diagnostic with no output schema, this is the exact behavioral detail an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence, followed by default behavior and return contents. The middle sentence is a dense enumeration but every clause carries information; no filler or restated title text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so thoroughly, including the masking caveat. Both optional parameters have defaults explained, so an agent can call it with zero arguments and predict the output shape.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented. The description adds only one piece of real meaning — that 'failure' spans no-response, 4xx/5xx, or failing tests — which sharpens the default for `entry` but does not explain the `environment` parameter's effect on variable checking.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Explain why a request sent from the Kurlo app failed.' The diagnostic framing is clearly distinct from data-retrieval siblings like get_history_entry or list_history, though it never names an alternative explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context by defining the default trigger condition — 'the most recent request that got no response, a 4xx or 5xx status, or failing tests' — so an agent knows it can be called with no arguments after a failure. No explicit when-not or named alternative is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_testsGenerate tests for a saved requestA
Write pm.test assertions into a saved request from a real or described response: its status, its Content-Type and a JSON schema of its body (types and required fields, never values), and save the response as an example the mock server serves. from: run (default) sends the request, so it creates what a POST creates. from: example takes the status and body, or schema, the code returns, for an API that is not running anywhere yet. Tests the request already has are kept; a test with the same name is not added twice.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | With from: example, a representative response body. | |
| from | No | run sends the request and tests its response; example tests the response you describe. Defaults to run. | |
| schema | No | A JSON Schema for the body to use instead of one inferred from the response, for example built from the response type in the code. | |
| status | No | With from: example, the status the code returns (default 200). | |
| replace | No | Replace the request's test script instead of adding to it. | |
| request | Yes | Request id or path (Collection/Folder/Name). | |
| variables | No | With from: run, variable overrides for this call. | |
| contentType | No | With from: example, the Content-Type. Defaults to application/json for a JSON body. | |
| environment | No | With from: run, the environment to send it with. Defaults to the one the server was started with. | |
| exampleName | No | Example name. Defaults to the status, for example "200 OK". | |
| saveExample | No | Save the response as an example (default true). An example of the same name is replaced. | |
| allowErrorStatus | No | With from: run, write tests even when the response is 4xx or 5xx, to test an error case on purpose. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that from:run actually fires the request ('it creates what a POST creates'), which is a real external side effect, and by documenting merge/dedup semantics for existing test scripts. It does not discuss auth requirements, rate limits, or what happens on network failure, so it stops short of full disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core capability is front-loaded and the two-mode branching is stated early, with no filler sentences. It is dense and slightly run-on, and the mock-example behavior is buried mid-sentence rather than given its own clause, but overall it is efficiently packed for a 12-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 12 parameters and no output schema, the description does the heavy lifting on the run/example distinction and the side-effect profile, which are the hardest things to infer. It omits any hint of the return value (e.g. the generated test script or example id) and says nothing about the tuning parameters, so it is complete enough to call correctly but not fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description still adds genuine meaning: it explains that `schema` overrides one inferred from the response (e.g. derived from a code type), and that duplicate-named tests are not added, which clarifies the `replace` semantics. Some parameters (variables, environment, allowErrorStatus, exampleName) are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Write pm.test assertions into a saved request') and enumerates exactly what gets asserted: status, Content-Type, and a JSON schema of the body. It also carves out its own scope against siblings like send_request and save_example by explaining that it both tests and persists the response as a mock example.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly branches on the `from` parameter: 'run (default) sends the request' versus 'example ... for an API that is not running anywhere yet,' naming the precondition that selects each mode. It also states the merge rule up front ('Tests the request already has are kept; a test with the same name is not added twice'), leaving nothing for the agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_history_entryShow a request sent from the Kurlo appARead-only
Show one request the user sent from the Kurlo app and the response they got: status, headers, body, errors, test results and script logs. Without entry it shows the last one sent, so "why did my last request fail?" needs no other input. Secrets are masked.
| Name | Required | Description | Default |
|---|---|---|---|
| entry | No | History entry id from list_history. Omit, or pass "last", for the newest. | |
| maxBodyBytes | No | Most bytes of the response body to return (default 65536, max 1048576). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely non-obvious behavior beyond that: secrets are masked in the returned data, and the default-to-newest behavior when no entry is supplied. Response size limiting is left to the schema rather than elaborated here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, each carrying distinct information: what is returned, the no-argument default, and the masking guarantee. Front-loaded with the primary action; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates well by enumerating the returned fields (status, headers, body, errors, test results, script logs) and flagging secret masking. Combined with the fully documented two-parameter schema and read-only annotations, nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already fully documented, including the "last" sentinel and the byte cap with defaults. The description's restatement that omitting entry returns the newest adds slight reinforcement but no new semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('Show one request the user sent ... and the response they got') and enumerates the payload contents (status, headers, body, errors, test results, script logs). This is clearly distinguishable from list_history (which yields ids) and from send_request-style siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit zero-argument usage path ('Without entry it shows the last one sent, so "why did my last request fail?" needs no other input'), which tells the agent exactly when no parameters are needed. It does not, however, contrast itself with the sibling diagnose_last_failure, which occupies overlapping territory.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_requestShow a saved requestARead-only
Show how a saved request is defined: method, URL, query parameters, headers, body, auth type, scripts, browser settings, and the saved example responses to compare a live response against. Credentials are not included.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes | Request id, path (Collection/Folder/Name) or name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the low bar for safety is covered. The description adds genuinely new behavioral context: that credentials are excluded from the returned definition and that saved example responses are included for comparison, both of which matter for how an agent interprets the output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the field enumeration is dense but each item tells the agent what to expect in the response. Slightly long-tailed, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description usefully compensates by enumerating the returned contents and the credentials exclusion. What remains unstated is error behavior for an unresolvable id/path/name, which is a minor gap for a single-parameter read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter exists and the schema documents it at 100% coverage ('Request id, path (Collection/Folder/Name) or name'). The description adds nothing beyond that about accepted identifier forms, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Show') and resource ('saved request'), and enumerates the fields returned, so an agent knows this is a definition/metadata read rather than an execution. It does not name the closely competing siblings (send_request, run_request), leaving the read-vs-execute distinction implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'saved request ... to compare a live response against', which hints at inspection before or after a send. However, there is no explicit statement of when to prefer this over send_request or run_request, and no stated alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_environmentsList environmentsARead-only
List the workspace's environments and their variables. Secret values are hidden.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real value beyond that with 'Secret values are hidden,' warning the agent that secret variables will be redacted rather than returned — a behavior it could otherwise misinterpret as missing data. It stops short of describing ordering, pagination, or whether inactive environments are included.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, with the scope stated first and the redaction caveat immediately after. Nothing redundant with the title or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param read-only listing with no output schema, the definition covers the essentials: what is returned and the one surprising behavior (hidden secrets). It could be marginally stronger by noting whether all environments are returned or whether the list is scoped/filtered, but nothing critical to correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. There is nothing for the description to disambiguate, and it correctly avoids inventing parameter discussion.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'List the workspace's environments and their variables.' An agent immediately knows the scope (workspace-level) and payload (environments plus their variables). No sibling tool overlaps with environments, so explicit differentiation isn't needed, but there's also no framing of how this relates to the request/collection tools around it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied — an agent infers it should call this to discover environments before reading or setting variables. There is no explicit statement of when to use this versus alternatives (e.g., set_variable), and no prerequisites or follow-up guidance. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_historyList requests sent from the Kurlo appARead-only
List the requests the user recently sent from the Kurlo app on this machine, newest first, with status, timing and the saved request each came from. Use it when the user refers to something they just sent or saw in Kurlo, then get_history_entry to read one.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most entries to return (default 20, max 100). | |
| query | No | Only entries whose name, saved request, method, URL or status contains every word of this text. | |
| failedOnly | No | Only requests that failed to send or got a 4xx or 5xx status. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety and scope are covered. The description adds useful behavior: results are newest first, scoped to this machine, and include status, timing, and originating saved request. It does not explain pagination or return shape beyond that, but the schema covers the limit parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences and front-loads the core purpose before adding the usage cue and follow-up tool. There is no redundant or filler text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with a fully documented schema and annotations covering safety, the description supplies enough context: recent local scope, ordering, returned fields, and follow-up behavior. The main remaining gap is an explicit differentiation from list_requests.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the schema. The description does not add parameter-specific meaning beyond what the schema provides, which is the expected baseline when schema coverage is high.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: list recent requests sent from Kurlo on this machine, newest first. It clearly indicates the content includes status, timing, and source saved request. It does not explicitly distinguish itself from the sibling list_requests, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete trigger: use when the user refers to something they just sent or saw in Kurlo. It also routes the agent to get_history_entry for reading one entry. It lacks explicit guidance on when to prefer list_requests instead, so a 4 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_requestsList saved requestsARead-only
List the saved requests in the workspace with their collection, folder, protocol, method and URL. The path or id of a request is what run_request and get_request take.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Only list requests whose path, method or URL contains every word of this text, ignoring case. For example: "post orders". | |
| collection | No | Only list requests in this collection. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful context beyond that by naming the fields each entry carries (collection, folder, protocol, method, URL), which is valuable given there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, with the verb and scope front-loaded ahead of the cross-reference to run_request/get_request.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the returned fields, and the annotations cover the safety profile. Pagination/ordering behavior is not mentioned, which is the only notable gap for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters (query, collection) are documented there with examples and semantics. The description says nothing about the filters, so it adds no meaning beyond the schema — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List the saved requests in the workspace') plus the fields returned, and links to the sibling tools that consume the resulting ids. This clearly separates it from list_history and list_environments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence tells the agent why it would call this: to obtain the path/id that run_request and get_request require. It gives clear context but no explicit exclusions (e.g., when to prefer list_history or search-style filtering).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_collectionRun a collectionA
Run the HTTP and GraphQL requests of a collection or folder in order, with their test scripts, and return a pass/fail summary per request. Realtime requests are skipped. Reports progress after each request when the call carries a progressToken.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | Only run requests under this folder path (slash-separated). | |
| failFast | No | Stop at the first failing request. | |
| variables | No | Variable overrides for this call, as name to value. They win over the environment. | |
| collection | No | Collection name. Omit to run every collection. | |
| environment | No | Environment name. Defaults to the one the server was started with. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=true, so the description earns its keep by disclosing execution semantics: requests run in order, test scripts execute, realtime requests are skipped, and progress is streamed per request when a progressToken is present. It does not say that the requests themselves may mutate external state, which is the main residual risk for an open-world write-hinted tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action and return shape, then the exclusion and the progress behavior. No sentence is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape ('pass/fail summary per request') and the skip rule, which is the essential missing structured data. The remaining gap is that none of the five parameters' effects on side effects (e.g., failFast leaving later requests unrun) are spelled out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes beyond it by tying the collection/folder pair to the run scope and by explaining the call-level progressToken, which does not appear in the input schema at all. No syntax hints are added for variables or environment, but the schema already covers those.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: runs the HTTP and GraphQL requests of a collection or folder, in order, with test scripts, returning per-request pass/fail. The 'collection or folder' scope implicitly separates it from the single-request siblings (run_request, send_request), though it never names them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Realtime requests are skipped' caveat and the ordering/test-script behavior imply when this tool is appropriate (whole-collection batches rather than a single call), but there is no explicit 'use this instead of run_request/send_request when…' routing. An agent must infer the boundary from the family of sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_requestRun a saved requestA
Send one saved HTTP or GraphQL request with its collection defaults, auth and scripts, and return the status, headers, body, timings and test results.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes | Request id, path (Collection/Folder/Name) or name. | |
| variables | No | Variable overrides for this call, as name to value. They win over the environment. | |
| environment | No | Environment name. Defaults to the one the server was started with. | |
| maxBodyBytes | No | Most bytes of the response body to return (default 65536, max 1048576). | |
| browserOrigin | No | Send the call the way a browser on this page origin would, for example https://app.example.com: browser headers, the CORS preflight when one is needed, and the CORS error a browser would raise. Omit it and a saved request uses its own browser settings, if any. | |
| browserCredentials | No | With browserOrigin, make it a credentialed request (fetch credentials: include), which a wildcard Access-Control-Allow-Origin does not satisfy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false and openWorldHint=true; the description adds that collection defaults, auth and scripts execute, which tells the agent the call can have real side effects beyond a plain read. It stops short of saying whether runs are recorded in history or how failures surface, but the execution semantics are meaningfully disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence covering action, inputs inherited, and returned data, with no filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates what comes back, and the six parameters are fully documented in the schema. The remaining gap is routing guidance against send_request/run_collection and any note on side effects or history recording.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including detailed notes on browserOrigin and browserCredentials, so the schema carries the parameter burden. The description adds no parameter-level detail beyond the general mention of defaults and auth; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send one saved HTTP or GraphQL request') and enumerates the return payload (status, headers, body, timings, test results). The word 'one saved' implicitly separates it from run_collection and send_request, but no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied through the phrase 'saved request' -- an agent must infer that ad-hoc sends belong to send_request and bulk runs to run_collection. There is no explicit when-to-use, when-not-to-use, or prerequisite statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_exampleSave a response as an exampleA
Save an example response on a saved request. Kurlo's mock server serves examples, and live responses can be compared against them. Without status and body it saves the response of the last run_request of that request in this session; secrets and cookies are removed from it. With status and body it saves the response you describe.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Body of a described response. | |
| name | No | Example name, for example "Created" or "Not found". Defaults to the status. | |
| notes | No | Optional notes. | |
| status | No | HTTP status code of a described response. | |
| headers | No | Other headers of a described response, as name to value. | |
| request | Yes | Request id or path (Collection/Folder/Name). | |
| contentType | No | Content-Type of a described response. Defaults to application/json for JSON bodies. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond the annotations, it discloses that examples are served by the mock server and used as comparison baselines, that the implicit-capture path draws from the last run in the current session, and that secrets and cookies are stripped from the captured response. It leaves open whether saving under an existing name overwrites or duplicates, which matters given idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose before behavior and mode switching; no filler. The middle sentence is dense, packing mock-server role, comparison use, default capture, and scrubbing into one run-on, but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a non-destructive write tool with full schema coverage and no output schema, the description covers both invocation modes and the notable side effect of secret/cookie removal. Remaining gaps are the response shape and collision/overwrite semantics for the name parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics by showing that status and body together constitute an alternate mode rather than independent optional fields. It does not clarify headers/contentType interplay beyond what the schema already says.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: saving an example response on a saved request. The description then distinguishes the tool from nearby siblings like run_request and send_request by explaining that examples are what Kurlo's mock server serves and what live responses are compared against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly splits the two calling modes: omit status/body to capture the last run_request of that request in this session, or supply status and body to record a described response. That is a clear when-to-do-what rule. It does not, however, contrast with save_request or state prerequisites such as whether the request must already be saved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_requestCreate or change a saved requestA
Create a saved HTTP or GraphQL request, or change one. Without request it creates a new one; with request (id or path) it changes that one, and only the fields you pass are changed. params, headers and form replace the whole list. Use {{variables}} for anything that differs per environment, such as {{baseUrl}}. Secrets are never written: auth tokens and passwords must be {{variable}} references. Test scripts are JavaScript with the Postman pm.* API, for example pm.test("status is 200", () => pm.response.to.have.status(200)).
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL; may use {{variables}}. Required for a new request. | |
| auth | No | Authentication. Secret parts (token, password, value) must be {{variable}} references. Defaults to inherit, which uses the collection's auth. | |
| body | No | Request body. JSON is stored as a JSON body, anything else as text, unless bodyType says otherwise. | |
| form | No | Form fields for a urlencoded or form (multipart) body. Replaces the existing list. | |
| name | No | Request name. Defaults to the method and path. | |
| type | No | Defaults to http. | |
| notes | No | Notes shown with the request. | |
| query | No | GraphQL query or mutation. | |
| folder | No | Folder path inside the collection, slash-separated, for example Users/Admin. An empty string moves the request to the top. | |
| method | No | HTTP method (default GET). Ignored for GraphQL, which is always POST. | |
| params | No | Query parameters. Replaces the existing list. | |
| headers | No | Request headers. Replaces the existing list. | |
| request | No | Id or path (Collection/Folder/Name) of the request to change. Omit to create one. | |
| bodyType | No | ||
| variables | No | GraphQL variables. | |
| collection | No | Collection to create the request in, or to move it to. Optional when there is only one. | |
| testScript | No | JavaScript run on the response; pm.test assertions become the request's tests. | |
| preRequestScript | No | JavaScript run before the request is sent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses the surprising behaviors an agent must know: params/headers/form wholesale replacement, partial-update semantics for everything else, and the hard rule that secrets must be {{variable}} references rather than literals. It also states what testScript/preRequestScript actually are (JavaScript with the pm.* API), which annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with create-vs-update, then replacement semantics, then constraints and script guidance — a sensible order with little waste. The inline pm.test example is illustrative but runs long for what it conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 18-parameter mutation with no output schema, the description covers mode selection, replacement behavior, variable/secret conventions, and script semantics. It stops short of saying what is returned (e.g. the saved request's id), which the agent would need to chain into run_request or send_request.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 94%, so nearly every parameter is already self-documenting, and most description content (list replacement, url required for new requests, default GET) restates the schema. The genuine addition is the cross-cutting {{variables}} and secret-as-variable convention, which is useful but marginal against an already strong schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb pair and resource: create or change a saved HTTP/GraphQL request. The word "saved" implicitly separates it from send_request and run_request, but no sibling is named, so the agent must infer the persistence distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly resolves the main ambiguity: omit `request` to create, pass an id or path to update, and only passed fields change. What's absent is routing advice against alternatives such as send_request or save_example when the agent is unsure whether to persist at all.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_requestSend an HTTP requestA
Send a one-off HTTP request that is not saved in the workspace. {{variables}} in the URL, headers and body are resolved from the environment.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Absolute URL; may use {{variables}}. | |
| body | No | Request body. JSON is sent as application/json, anything else as text/plain, unless a Content-Type header says otherwise. | |
| method | No | HTTP method (default GET). | |
| headers | No | Request headers, as name to value. | |
| variables | No | Variable overrides for this call, as name to value. They win over the environment. | |
| environment | No | Environment name. Defaults to the one the server was started with. | |
| maxBodyBytes | No | Most bytes of the response body to return (default 65536, max 1048576). | |
| browserOrigin | No | Send the call the way a browser on this page origin would, for example https://app.example.com: browser headers, the CORS preflight when one is needed, and the CORS error a browser would raise. Omit it and a saved request uses its own browser settings, if any. | |
| browserCredentials | No | With browserOrigin, make it a credentialed request (fetch credentials: include), which a wildcard Access-Control-Allow-Origin does not satisfy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and openWorldHint=true, so the agent knows this can make external, non-read-only calls. The description adds useful context that the request is not persisted and that {{variables}} are resolved from the environment, but it does not discuss side effects, authentication, redirects, or response truncation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with no filler. The key constraint, that the request is one-off and unsaved, is front-loaded before the variable-resolution note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter, open-world HTTP tool with no output schema, the description is adequate but thin. The rich input schema covers parameters well, yet the description does not explain response behavior, error handling, or the safety implications of sending real external requests.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema carries most parameter detail, and the baseline would be 3. The description adds cross-cutting semantic value by explaining that {{variables}} in the URL, headers, and body are resolved from the environment, which the schema only partially states for the url field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: sending a one-off HTTP request that is not saved in the workspace. This scope distinguishes it from saved-request tools, but it does not explicitly name a sibling such as run_request as the alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'one-off HTTP request that is not saved in the workspace' clearly indicates the transient use case. It stops short of explicit when-not guidance or naming alternative tools for saved requests.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_variableSet an environment variableA
Set a non-secret variable in an environment, creating the environment if it does not exist. The value is written to the environment's file, so it is shared through Git; never use it for a secret. Secret variables and protected environments can only be changed in Kurlo.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Variable name, used in requests as {{key}}. | |
| value | Yes | Value. | |
| workspace | No | Workspace name, when the folder holds more than one. | |
| description | No | What the variable is for. | |
| environment | No | Environment name. Defaults to the one the server was started with. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that the value is persisted to the environment's file and shared through Git, and that a missing environment is created as a side effect. It does not say what happens when the key already exists (overwrite vs error), which matters given idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: capability, persistence/Git implication, then the security boundary. Front-loaded with the action and scoping constraint, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and full schema coverage, the description supplies the missing behavioral context: Git persistence, non-secret constraint, and environment auto-creation. Only the overwrite behavior for an existing key is left unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are already documented, including the environment default and workspace disambiguation. The description adds no additional parameter meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (set a non-secret variable in an environment) and immediately scopes it away from secrets and protected environments. An agent can distinguish this from list_environments or save_request without reading the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the negative case: 'never use it for a secret' and directs secret/protected changes to Kurlo. It also documents the side effect of creating a missing environment. What's missing is a positive routing rule toward a sibling tool (e.g., when to prefer list_environments first), but the exclusions are strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
15 tool updates
v2.4.1- First observed
create_collection - First observed
delete_request - First observed
diagnose_last_failure - First observed
generate_tests - First observed
get_history_entry - First observed
get_request - First observed
list_environments - First observed
list_history - First observed
list_requests - First observed
run_collection - First observed
run_request - First observed
save_example - First observed
save_request - First observed
send_request - First observed
set_variable
TDQS
Scored across 15 tools
Most tools have clearly distinct purposes, and the saved-vs-one-off split between run_request and send_request is explicit. However, generate_tests overlaps with save_example (both save a response as an example), and diagnose_last_failure shares some surface with get_history_entry, creating minor ambiguity.
All tools use a consistent snake_case verb_noun pattern (save_request, list_history, run_collection, etc.). The verbs vary appropriately by action while the structure remains predictable throughout.
15 tools is at the upper end of the ideal range but appropriate for a Postman-like API client covering requests, collections, environments, history, and testing. Each tool earns its place without obvious redundancy.
Request lifecycle is well covered (save, delete, list, get, run, send), but collection management is incomplete: only create_collection exists, with no list, update, or delete. Environment and example lifecycles also lack delete operations, leaving notable gaps for an agent to manage the workspace fully.
Maintenance
Related MCP Connectors
Build and publish pages, manage collections, records and files in a Markerloop workspace.
- uivoidOAuthapp.uivoid
Manage uivoid projects, tools, keys, hosted databases and teams from your agent.
1 Manage Cronitor monitors and send telemetry pings — list, inspect, create, update, delete.
Run and manage AI agent tasks on tavya: create, search and steer tasks, read wikis, call the API.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to interact with Istek API Client for managing workspaces, collections, environments, variables, and request history. Allows natural language control of API development workflows including creating collections, adding requests, and managing environment configurations.-
- AlicenseNot gradedqualityAmaintenanceAPI client with an MCP server. Your agent builds collections from your codebase, runs requests, writes e2e flows, and exports them to GitHub Actions CI automatically. Category: Developer Tools2 npm4ISC
- AlicenseNot gradedqualityDmaintenanceA keyboard-first API client that stores requests and environments as plain files, and exposes its workspace over MCP so agents can browse, send, and create requests with vault access.137 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables API development directly from MCP clients by creating and editing collections, running requests through the real CLI, generating documentation, and starting mock servers.38 npmMIT