Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Test and debug APIs with Bruno, the open-source API client. Use when a user asks to create API requests, organize collections, write test scripts, use environments and variables, or collaborate on API workflows stored in Git.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 34% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 39% | 0% |
You are an expert in Bruno, the open-source API client that stores collections as plain text files in your Git repository. Unlike Postman (cloud-synced, proprietary format), Bruno uses a human-readable format (Bru) that lives alongside your code — versioned, reviewable, and shareable via Git.
api-collection/
├── bruno.json # Collection config
├── environments/
│ ├── dev.bru
│ ├── staging.bru
│ └── production.bru
├── auth/
│ ├── login.bru
│ ├── register.bru
│ └── refresh-token.bru
├── users/
│ ├── list-users.bru
│ ├── get-user.bru
│ ├── create-user.bru
│ └── update-user.bru
└── orders/
├── list-orders.bru
├── create-order.bru
└── process-refund.brubru# auth/login.bru — Human-readable, Git-diffable meta { name: Login type: http seq: 1 } post { url: {{baseUrl}}/api/auth/login body: json auth: none } headers { Content-Type: application/json } body:json { { "email": "{{testEmail}}", "password": "{{testPassword}}" } } script:post-response { // Save token for subsequent requests if (res.status === 200) { bru.setVar("authToken", res.body.token); bru.setVar("userId", res.body.user.id); } } tests { test("should return 200", () => { expect(res.status).to.equal(200); }); test("should return token", () => { expect(res.body.token).to.be.a("string"); expect(res.body.token.length).to.be.greaterThan(0); }); test("should return user", () => { expect(res.body.user.email).to.equal("{{testEmail}}"); }); }
bru# environments/dev.bru vars { baseUrl: http://localhost:3000 testEmail: test@example.com testPassword: testpass123 } vars:secret [ stripeKey, dbPassword ]
javascript// Pre-request script — runs before sending const crypto = require("crypto"); const timestamp = Date.now().toString(); const signature = crypto .createHmac("sha256", bru.getVar("apiSecret")) .update(timestamp) .digest("hex"); bru.setVar("timestamp", timestamp); bru.setVar("signature", signature); // Post-response script — process responses if (res.status === 200) { const users = res.body.data; bru.setVar("firstUserId", users[0].id); console.log(`Found ${users.length} users`); } // Chain requests — use variables from previous responses // login.bru sets {{authToken}} // create-order.bru uses {{authToken}} in auth header
bash# Install CLI npm install -g @usebruno/cli # Run entire collection bru run --env dev # Run specific folder bru run auth/ --env dev # Run with custom environment variables bru run --env production --env-var apiKey=sk_live_xxx # Output JUnit XML for CI bru run --env dev --output results.xml --format junit
bash# Desktop app (GUI) # Download from https://www.usebruno.com/downloads # CLI npm install -g @usebruno/cli
Example 1: User asks to set up bruno
User: "Help me set up bruno for my project"
The agent should:
Example 2: User asks to build a feature with bruno
User: "Create a dashboard using bruno"
The agent should:
vars:secret are never committedbru.setVar() in post-response scripts to pass data between requests (token → subsequent calls)bru run --env staging after deployment to verify API contract; fail the pipeline on test failuresOther measured skills in the registry, with their headline benchmark lift.