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.
.claude/skills/terminalskills-bruno/SKILL.md| 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 failures| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 8,379 | 5,586 | -33% | 1 | 1 | 0% | 1,918 | 2,564 | +34% | 0 | 0 | — |
case-14 | pass→pass | 11,098 | 10,607 | -4% | 1 | 1 | 0% | 1,882 | 3,099 | +65% | 0 | 0 | — |
case-02 | fail→pass | 7,319 | 4,553 | -38% | 1 | 1 | 0% | 1,449 | 2,117 | +46% | 0 | 0 | — |
case-03 | fail→pass | 4,735 | 1,698 | -64% | 1 | 1 | 0% | 828 | 1,601 | +93% | 0 | 0 | — |
case-04 | fail→pass | 6,476 | 6,267 | -3% | 1 | 1 | 0% | 1,395 | 2,689 | +93% | 0 | 0 | — |
case-05 | fail→pass | 6,360 | 2,439 | -62% | 1 | 1 | 0% | 1,196 | 1,661 | +39% | 0 | 0 | — |
case-15 | fail→pass | 4,479 | 3,265 | -27% | 1 | 1 | 0% | 830 | 1,972 | +138% | 0 | 0 | — |
case-06 | pass→pass | 9,548 | 5,687 | -40% | 1 | 1 | 0% | 1,654 | 2,450 | +48% | 0 | 0 | — |
case-07 | fail→pass | 4,028 | 3,435 | -15% | 1 | 1 | 0% | 736 | 1,994 | +171% | 0 | 0 | — |
case-08 | pass→pass | 8,758 | 1,744 | -80% | 1 | 1 | 0% | 1,513 | 1,599 | +6% | 0 | 0 | — |
case-09 | pass→pass | 3,704 | 1,726 | -53% | 1 | 1 | 0% | 511 | 1,578 | +209% | 0 | 0 | — |
case-21 | pass→pass | 10,039 | 6,507 | -35% | 1 | 1 | 0% | 1,713 | 2,439 | +42% | 0 | 0 | — |
case-10 | pass→pass | 3,542 | 1,829 | -48% | 1 | 1 | 0% | 621 | 1,610 | +159% | 0 | 0 | — |
case-11 | pass→pass | 3,925 | 2,763 | -30% | 1 | 1 | 0% | 796 | 1,782 | +124% | 0 | 0 | — |
case-12 | pass→pass | 7,285 | 3,572 | -51% | 1 | 1 | 0% | 1,392 | 1,947 | +40% | 0 | 0 | — |
case-13 | fail→pass | 1,939 | 1,576 | -19% | 1 | 1 | 0% | 335 | 1,580 | +372% | 0 | 0 | — |
case-16 | pass→pass | 5,204 | 3,496 | -33% | 1 | 1 | 0% | 984 | 1,901 | +93% | 0 | 0 | — |
case-17 | fail→pass | 15,445 | 8,871 | -43% | 1 | 1 | 0% | 3,103 | 3,002 | -3% | 0 | 0 | — |
case-18 | fail→pass | 14,208 | 13,217 | -7% | 1 | 1 | 0% | 2,639 | 3,833 | +45% | 0 | 0 | — |
case-19 | pass→fail | 10,410 | 12,890 | +24% | 1 | 1 | 0% | 2,437 | 4,290 | +76% | 0 | 0 | — |
case-20 | pass→fail | 2,115 | 2,856 | +35% | 1 | 1 | 0% | 457 | 1,824 | +299% | 0 | 0 | — |
case-22 | fail→fail | 6,535 | 4,815 | -26% | 1 | 1 | 0% | 1,325 | 2,174 | +64% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.