Everything Retriever does.
The complete feature list for the native Mac API client, grouped the way you'll look for it. If something you need isn't here, check what's not in yet or ask for it.
Requests
- GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS, with a colored method pill.
- Query parameters and headers as a table, or as a JSON object: toggle at the top right, both views edit the same rows. Rows you switch off are kept but not sent.
- Header names autocomplete as you type, and so do values for
Content-Type,Accept,Authorizationand other common headers. - Bodies: JSON, XML, plain text, form URL-encoded, and multipart with file upload (prefix a value with
@or use Add File…).Content-Typeis set from the body type unless you set one yourself. - A code editor for JSON, XML and text bodies: syntax highlighting, braces and quotes that close themselves, auto-indent, and one-click JSON and XML formatting. Invalid JSON shows a quiet badge with the parser's exact message.
- Per-request timeout and redirect policy.
Auth
- Bearer token, HTTP Basic, HTTP Digest, API key (as a header or a query parameter), OAuth 2.0, AWS Signature, or none.
- AWS Signature (SigV4): access key, secret key, an optional session token, region and service. Each send is signed at that moment, for API Gateway, S3, Lambda and other AWS services. HTTP requests.
- Digest: the username and password are sent only in answer to the server's challenge, and only to the request's own host.
- Every request can inherit its collection's default auth, so a whole API is configured in one place.
- Any field can be a
{{variable}}, so secrets stay in environments and exported collections stay clean. - Client certificates (mutual TLS): Settings → General → Client certificates takes a .p12 or .pfx file and passphrase per host, such as
api.example.comor*.example.com. The certificate is presented only to the host it was set up for, and the row shows whose it is and when it expires. HTTP and GraphQL requests; not WebSocket or gRPC yet.
OAuth 2.0
Pick OAuth 2.0 in the Auth tab, fill in the endpoints (or pick a preset), and press Send. Retriever gets the token, attaches it, and keeps it fresh.
| Grant | What happens |
|---|---|
| Authorization code + PKCE | You sign in in a browser; Retriever exchanges the code, with an S256 code challenge. |
| Client credentials | Machine to machine: the client id and secret get a token directly, no window. |
| Device code | A panel shows a short code (already on your clipboard) and opens the verification page. Approve there; Retriever picks up the token by itself. |
| Password | For legacy APIs: username and password go to the token endpoint. |
| Refresh token | Start from a refresh token you already have. |
- Automatic refresh. A token about to expire is refreshed before the request goes out. If the server still answers 401, Retriever refreshes once and retries — without opening a browser.
- Any redirect URI.
http://127.0.0.1/callbackstarts a one-shot listener on your Mac (any free port, bound to 127.0.0.1 only). A custom scheme likeretriever://oauth/callbackuses the macOS sign-in sheet with your default browser's logins. An https redirect — including one registered for Postman — opens an in-app browser that stops at the redirect. - Presets for GitHub, Google, Microsoft Entra ID, Auth0, Okta and Spotify.
- Tokens follow your environment. Requests whose settings resolve the same share one token; switch from Staging to Production and you get Production's token.
- A token card shows whether the token is valid, when it expires and its scopes, with Get New Token, Refresh, Clear and copy.
- Advanced: client authentication as a Basic header or in the body, the token in a header (with any prefix) or a query parameter, the OpenID Connect
id_tokeninstead of the access token, and extra parameters for the authorization URL and token requests (audience,prompt,access_type…). - Tokens are stored in
oauth-tokens.jsonnext to your workspace, readable only by you — never inworkspace.jsonand never in exports.
Environments, variables and dynamic values
{{name}}anywhere: URL, params, headers, body, auth. Values come from the active environment first, then the collection, and can reference other variables.- Environments switch from the toolbar. An environment variable named
baseUrloverrides the collection's base URL, which is how Local, Staging and Production switch servers. - Undefined variables are highlighted before you send; resolved ones show their value on hover.
- Secret variables: the lock on a variable masks its value on screen, hides it from AI agents and command-line output, and leaves it out of exported files. Requests still use it. It is about what is shown and shared; the value stays in your workspace file.
- Dynamic values, fresh on every send:
{{$uuid}},{{$timestamp}},{{$timestampMs}},{{$isoTimestamp}},{{$date(yyyy-MM-dd)}},{{$randomInt(1,100)}},{{$randomString(12)}},{{$base64(text)}},{{$env(HOME)}}.
GraphQL, WebSocket, gRPC and event streams
- GraphQL. A GraphQL body type with a highlighted query editor and a JSON variables pane, sent as a POST (or in the URL for GET). Fetch Schema runs introspection with the request's own headers, auth and cookies. The schema explorer lists queries, mutations and every type; Use turns a field into a ready-to-run operation with variables for its arguments, and Insert adds a field to your query. A 200 that carries
errorsgets a warning badge. - WebSockets. Pick WebSocket from the method pill, press ⌘↩ to connect, then send text or JSON messages, with
{{variables}}filled in per message. Messages appear as a filterable conversation with timestamps; ping to time the round trip. Headers, params, auth and cookies go with the handshake, and closing keeps the transcript in History, where other requests can chain from it. - gRPC. Unary and server-streaming calls over HTTP/2, with TLS (
grpcs://) or plaintext (grpc://, and any localhost address). Services come from server reflection or from.protofiles and their imports. Write the message as JSON, or start from a Template of the input type; 64-bit numbers, enums, bytes and well-known types like Timestamp and Struct follow the proto3 JSON rules. Headers become metadata and auth becomesauthorization. The gRPC status is shown by name and counts as its HTTP equivalent, so chaining and failure explanations work as they do for HTTP. Client streaming takes a JSON array of messages. Replies compressed with gzip or deflate are read. - Server-Sent Events. A
text/event-streamresponse, such as an LLM API with"stream": true, is shown as a list of events that grows while the stream is open: number, event name, id and data. Click an event for its full, pretty-printed data, filter the list, or switch to the raw stream. Stop ends the stream and keeps what arrived as the response, in history and for chaining. - Code. gRPC requests generate a
grpcurlcommand and WebSocket requests awebsocatone.
Cookies
- A cookie jar for the workspace. Cookies a server sets, including on redirects and WebSocket handshakes, are kept and sent back to matching requests by domain, path, Secure flag and expiry, as a browser would. Cookies set for a public suffix (co.uk, github.io, vercel.app…) are refused, as RFC 6265 requires.
- Request → Cookies… (⌥⌘K) lists them by domain; edit, add or delete any of them. A response that set cookies shows a link to the jar.
- A request can switch the jar off in its Docs tab, and a
Cookieheader you set yourself wins for the same name.
Response chaining, without scripts
- Read the last response of another request:
{{@Login.body.data.token}},{{@Login.header.Set-Cookie}},{{@Login.status}}. Array items use.0,.1, … - Right-click any value in a response (tree row or header) and choose Copy as Chain Reference.
- Chained requests get a link in the sidebar and a reads from / feeds strip with freshness dots.
- Send chain runs every dependency in order, then the request.
Tests, without scripts
- The Tests tab holds checks that run on every response: the status, a header, a value in the JSON body (
data.items.0.id, the same paths as chain references), the whole body, or the time taken. - Compare with equals, contains, exists, less than, greater than or a regular expression. Expected values can use
{{variables}}. - Each row shows whether the latest response passed; hover a failure to see what the response had. The response shows a count such as 3/5 tests.
- Run All… on a collection or folder sends everything in it in order and shows each request's status, time and tests, with what failed underneath. Stopping at the first failure is optional.
- The same tests decide the result of
retriever-mcp sendin a terminal or CI, and whether Send chain carries on.
Responses
- Status, time, size and content type at a glance. Click the status for a plain-English guide: what it means, what to check, and a link to MDN.
- JSON as a collapsible tree: order-preserving, virtualized rows, key previews on folded objects, fold to level two, collapse or expand all. Large payloads fold automatically and are parsed off the main thread.
- XML (SOAP, RSS, anything
+xml) is indented and coloured for reading, with attributes, namespaces, comments, CDATA and text exactly as sent. - HTML is indented and coloured too: the error page or login redirect that arrives as one long line becomes readable. A Formatted / Raw switch shows an HTML or XML body exactly as it arrived.
- Images are shown as images, with their pixel size, and PDFs open in a viewer, whatever content type the server sent. Other binary responses get a short notice and Save rather than garbled text.
- Copy a value, its path, or a chain reference. A raw view with real text selection for megabyte bodies.
- Response headers, and the exact request that was sent, with every variable resolved.
- The last 25 responses of every request are kept, so switching back is instant.
- Search Responses… (⇧⌘F) finds text in every saved response — bodies, headers, the URL that was sent and the request body — and opens the request on the response that matched.
Code generation
- ⇧⌘C turns a request into cURL, Swift (URLSession), JavaScript (fetch), Node.js (https), Python (requests), Go (net/http) or HTTPie — highlighted, with variables and the current OAuth token already filled in.
- Copy as cURL from the menu or the sidebar in one step.
Import and export
- cURL: paste a command into Import or straight into a request's URL field, or ⇧⌘V to import from the clipboard. A specific Content-Type (such as application/merge-patch+json) is kept.
- Postman Collection v2.1, including folders, auth and OAuth 2 settings, and Postman environments. Common one-line test assertions (a status check, a header, a value in the body) become Tests; scripts with logic are left out, because nothing is executed.
- Insomnia v4 exports: workspaces, folders, environments and auth.
- HAR files from browser dev tools: requests grouped by host, assets left out.
- OpenAPI 3 and Swagger 2, in JSON or YAML: operations become requests grouped by tag, servers become the base URL, and security schemes — bearer, basic, API key and OAuth 2 — become the collection's auth.
- Export any collection as Postman Collection v2.1. Tests are written as Postman test scripts.
- File → Export Workspace… writes every collection and environment to one file that Import reads back, for moving to another Mac or sharing a setup. Secret variables are written without their values; response history, cookies and OAuth tokens are not included.
- Coming from Paw? The migration guide maps every concept.
Organizing
- Collections with folders, drag to move, duplicate, rename in place.
- Select several at once: shift-click a second row to select everything in between, then right-click to move the selection to any collection or folder or to delete it, press ⌫, or drag it onto a folder. Each is one undo step.
- Reorder by dragging a request or folder onto a request (it lands just before it, and a line shows where), or with Move Up and Move Down in the right-click menu. Run All… and the command line send in this order.
- Each collection has a base URL (prefixed to relative URLs like
/users, available as{{baseUrl}}), its own variables, default auth, notes, an icon and a color. - Per-request notes for gotchas and example IDs.
- A sidebar filter, and a sidebar that folds to a slim rail.
- Tabs: ⌘T, ⌘W, ⇧⌘] / ⇧⌘[, or ⌘-click a request to open it beside.
- Eight themes (Midnight, the default, plus Retriever, Graphite, Nord, Solarized, Dracula, Rosé Pine and Evergreen), each light, dark, or following the system.
- A starter collection against the free DummyJSON API — 40+ real requests, including a login → token → authenticated chain.
Undo and history
- ⌘Z / ⇧⌘Z undo and redo deletes, moves, renames, imports and edits, 100 steps deep. Text fields keep their own typing undo.
- Request history (⌥⌘Y, the toolbar clock, or right-click a request): every earlier revision of the request with a line-by-line diff against now — URL, params, headers, body, auth, docs, settings — and one-click restore. Tokens and passwords show only their last four characters.
- A revision is saved when you leave a request you edited, so each editing session is one step back.
- Version history (⌥⌘Z): saved copies of the whole workspace, taken before every delete, import and restore, before changes from the MCP server, and every 10 minutes while you edit. See what differs from now and restore a single request, folder, collection or environment, or the whole workspace.
- Versions are plain
workspace.jsoncopies inversions/: all of today's, one a day for a month, one a week for a year.
Keyboard
- ⌘K quick open: fuzzy-find any request, switch environments, run commands.
- Arrow keys walk the sidebar; ⌘F finds in a response.
- ⌘↩ send, ⌘N new request, ⌘O import, ⇧⌘C generate code, ⌘S fold the sidebar.
- Every shortcut is rebindable in Settings: click it, press new keys.
Optional AI features
Off until you add your own API key in Settings → AI. Pick the provider you already pay for: TypeSafe, Anthropic or OpenAI. Each feature has its own switch, and without a key nothing is sent.
- Explain failed responses. Click the status of a 4xx or 5xx response to see the likely cause (expired credentials, wrong environment, rejected body, missing header, rate limit, a server problem) and the fix: get a new OAuth token and resend, switch environment and resend, or jump to the Auth, Body or Headers tab.
- Chain suggestions. When a value you typed (a pasted token, an id in the path, a body field) exactly matches a field in another request's last response, Retriever offers to replace it with the
{{@Request.body.path}}reference. Matching happens on your Mac; the model only judges whether the match is meant or a coincidence. One click applies it, ⌘Z undoes it. - ⌘K by description. A search of three words or more, like "the one that adds an item to a cart", adds the best matches above the usual name matches.
- Secrets stay home. Authorization and cookie headers, fields named like token, secret, password or key, and values that look like credentials are masked before a question is sent. The key lives in
typesafe.json, readable only by you. See Privacy. - Your provider, your bill. Retriever asks one narrow question per feature and reads back a typed answer, not prose. With Anthropic or OpenAI you also pick the model, so the cost of that question is yours to set.
MCP server for AI agents
Retriever ships a Model Context Protocol server, so Claude Code, Cursor or any MCP client can work with your requests. It uses the same workspace as the app: what an agent changes appears in your sidebar within a second, and the responses it fetches land in your history.
claude mcp add retriever -- /Applications/Retriever.app/Contents/MacOS/retriever-mcp
Twenty-two tools: list_collections, list_requests, get_request, send_request, send_adhoc, create_request, update_request, delete_request, get_last_response, list_environments, set_active_environment, set_variable, update_collection, import_curl, import_openapi, generate_code, export_postman, oauth_token, list_cookies, clear_cookies, graphql_schema and grpc_describe. Requests can be created as GraphQL, WebSocket or gRPC, and sending a WebSocket request returns the conversation.
- Values that look like secrets are masked unless the agent asks to reveal them.
- Requests that use OAuth 2 get their token automatically. The agent reuses and refreshes tokens you got in the app; browser sign-ins happen once, in the app.
- It makes only the requests your agent asks for, and nothing else.
- Resources: the workspace, and each collection as an outline of its requests (method, URL, parameter names, body fields, tests). An outline carries no values, bodies, notes or cookies, so an agent can be given one without being given your credentials.
- Prompts:
test_endpoint,debug_requestanddocument_collection, shown as commands in clients that support them.
The same program runs saved requests from a terminal or a CI job, with no MCP client:
/Applications/Retriever.app/Contents/MacOS/retriever-mcp send "DummyJSON/Auth" --env Staging --var limit=5
- Name a request, a folder or a whole collection. Requests go out in order, so chains work, with the app's variables, auth and cookies.
- Each response is printed with its tests. The exit status is 0 when everything passed, 1 when a request failed and 2 for a mistake in the command.
--jsonfor machine-readable output,--quietfor one line per request,--keep-goingto continue after a failure.
Your data
- Everything lives in
~/Library/Application Support/Retriever/:workspace.jsonfor collections and environments, one history file per request,versions/with earlier copies of the workspace,oauth-tokens.jsonfor tokens,cookies.jsonfor the cookie jar andgraphql-schemas/for introspected schemas. - Plain, readable JSON. Back it up, sync it, or commit it to git.
- Workspace folder: Settings → General → Workspace → Choose Folder… keeps
workspace.jsonin a folder you pick, such as a git repository or a synced folder, so a team can share collections. Only that file lives there. OAuth tokens, cookies, client certificates, response history and versions stay on your Mac, and so do the values of variables marked secret: the shared file carries their names, and each person fills in their own. Every other value in the file is shared. The command line and MCP server follow the same choice. - No account, no telemetry, no license check. Besides the requests you send, the only network traffic is a daily check for updates, which you can turn off, and a report when you choose Help → Report an Issue….
- Updates: Retriever → Check for Updates…, a daily automatic check, and optional automatic install (Settings → General → Updates). Updates are signed and verified before they install.
- Native Swift, signed and notarized by Apple, macOS 15 or later. One universal app for Apple silicon and Intel Macs.
Not in yet
- Custom JavaScript dynamic values and extensions
- GraphQL subscriptions
- Interactive client and bidirectional gRPC streaming
- Client certificates for WebSocket and gRPC connections
The roadmap is ordered by what people moving from Paw run into first. Tell me what blocks you.
Get it
Free, in full. No license key, no account, no subscription, no feature behind a paid tier. A signed and notarized DMG for macOS 15 or later: download it, drag Retriever to Applications, done.