Plug any APIinto your AI

PlugIt turns an OpenAPI, Swagger or Postman spec into tools for Claude, Codex, Cursor and VS Code. You pick the tools; it keeps your keys and your API safe.

✦ plugit · pets
Pick the tools to expose · 19 operations
⎿ GET /pet/findByStatus Finds Pets by status.
> / filter · space toggle · m mode · i details · s save
8 tools · ≈656 tokens · 0 write? for shortcuts

Every screen, in your terminal

✦ plugit · tool · findPetsByStatusread-only
GET /pet/findByStatus
Parameters
status query · string · required
Token cost
≈103 tokens in the tool list
Lint
✓ no findings
Input schema
  {
    "properties": {
      "status": {
        "default": "available",
        "enum": ["available", "pending", "sold"],
        "type": "string"
      }
    },
    "required": ["status"]
  }
❯ plugit lint notes
✗ error L007 [default] listNotes (GET /notes):
summary reads like an instruction to the
model: "Ignore previous instructions"
✗ error L007 [default] listNotes (GET /notes):
hidden text: summary contained invisible
or bidi characters (removed)
! warn L007 [default] getNote (GET /notes/{id}):
description embeds a URL (evil.example.test)
· info L008 [default] oldSearch (GET /search):
the spec marks this operation deprecated
notes: 2 errors, 1 warning, 1 info
plugit: lint found 2 errors
❯ plugit try pets findPetsByStatus
→ GET https://petstore3.swagger.io/api/v3/
pet/findByStatus?status=available
X-Api-Key: ***
←
HTTP 200 OK
Filtered to fields: id, name, status
[
  { "id": 1, "name": "Rex", "status": "available" },
  { "id": 2, "name": "Mittens", "status": "available" }
]
✦ plugit · logs · pets● live
18:02:11findPetsByStatusok 20042ms
18:02:19getPetByIdok 20038ms
18:02:31getPetByIdhttp_error 40435ms
18:03:02addPetdenied0.2ms
›getInventoryok 20051ms
args {"status":"available"}
error (none)
5 calls · 2 errors ↑↓ move · enter details
✦ plugit · stats · all APIslast 7 days
41 calls · 3 errors · sorted by calls
pets 41 calls · 7% errors · ≈656 tokens · 8 tools
toolcalls · p50p95
findPetsByStatus22 · 40ms88ms
getPetById12 · 36ms61ms
getInventory5 · 49ms70ms
addPet2 · 0.2ms0.3ms
✦ plugit · sync · pets+1 ~1 -1
! The spec's servers changed:
petstore3.swagger.io → new-home.example.test
base_url stays https://petstore3.swagger.io/api/v3
Added (1)
› ● GET /pet/{petId}/visits listVisits
Changed (1)
GET /pet/findByStatus description served in default
Removed (1)
POST /pet/{petId}/uploadImage overrides kept
✦ plugit install
Choose the MCP clients (space to tick, enter to confirm)
› ● Claude Desktop detected
● Claude Code detected
○ OpenAI Codex
● Cursor detected
○ VS Code (GitHub Copilot)
○ Windsurf
○ Gemini CLI
○ LM Studio
3 selected space toggle · enter confirm

Tool detail

Parameters with their locations, the token cost, lint findings and the exact input schema, before anything reaches a model.

Screen 1 of 7. Drag the row, or use the arrows.

Twenty seconds, start to finish

Adding the Petstore API, inspecting a tool, keeping three response fields, linting, one real call, then installing into Claude Desktop. Recorded in a terminal, not mocked up.

Safe by default

Change any setting and the panel shows what the model would get.

Read-only until you say so

GET, HEAD and OPTIONS are offered. Writes need confirm-writes or full, and confirm-writes asks you in the client before each call.

✦ what the model seesread-only
8 of 19 tools offered · ≈656 tokens
addPet not offered · read-only

Your key never reaches the model

Secrets live in the OS keyring or an environment variable. Every result is redacted, in raw, percent-encoded and base64 form, even when the API echoes the key back.

X-Api-Key: ***
echo the API sent the key back as raw, %-encoded and base64: *** *** ***

Only the fields you need

List a tool's response fields and everything else stays out of the model's context. Here, each pet loses its photos, tags and category.

← HTTP 200 OK · filtered to id, name, status
[
  {
    "id": 1,
    "name": "Rex",
    "status": "available"
  },
  {
    "id": 2,
    "name": "Mittens",
    "status": "available"
  }
]

The host is pinned

You confirm the base URL once. A spec, a redirect or the model itself can't send your key anywhere else, and private addresses are blocked unless you allow them.

→ GET https://petstore3.swagger.io/api/v3/pet/findByStatus?status=available

Poisoned text gets caught

Lint reads every description the model would read and flags instructions aimed at it before you serve them. Edit this one.

✗ error L007 reads like an instruction to the model: "Ignore previous instructions"
✦ what the model seesread-only
8 of 19 tools offered · ≈656 tokens
→ GET https://petstore3.swagger.io/api/v3/pet/findByStatus?status=available
X-Api-Key: ***
← HTTP 200 OK · filtered to id, name, status
[
  {
    "id": 1,
    "name": "Rex",
    "status": "available"
  },
  {
    "id": 2,
    "name": "Mittens",
    "status": "available"
  }
]
echo the API sent the key back as raw, %-encoded and base64: *** *** ***
addPet not offered · read-only
✗ error L007 reads like an instruction to the model: "Ignore previous instructions"

From spec to tool

petsnew
petstore.json · OpenAPI 3.0
19 operations
base URL pinned

First, point it at a spec.

petsread-only
8 tools · ≈656 tokens
11 writes not offered
3 response fields kept

Then choose what the model gets.

petsinstalled
Claude Desktop
entry added, no secrets
backup saved first

Then plug it into your client.

pets● live
findPetsByStatus · 200
42 ms · key masked
logged locally

Then see every call it makes.

Works where you work

Clients

  • Claude Desktopits config file
  • Claude Codeclaude mcp add
  • OpenAI Codexcodex mcp add
  • Cursor~/.cursor/mcp.json
  • VS Code with GitHub Copilotuser mcp.json
  • Windsurfmcp_config.json
  • Gemini CLI~/.gemini/settings.json
  • LM Studio~/.lmstudio/mcp.json
  • Any other MCP clientstdio or HTTP

Specs

  • OpenAPI 3.0 and 3.1JSON or YAML
  • Swagger 2.0JSON or YAML
  • Postman collectionsv2.0, v2.1
  • Form and multipart bodies611 of 612 Stripe ops

Credentials

  • Bearer, header or query keyskeyring or env
  • Basic authuser:password
  • OAuth2 client credentialsyour token_url
  • OAuth2 device sign-inrefresh in keyring

71%fewer tokens, the same reads

Offer all nineteen Petstore tools and the model reads ≈2,287 tokens of tool list before it starts. In read-only mode it gets the eight read tools, ≈656, and the writes never reach it. Each bar is PlugIt's own estimate for one tool.

Offered in read-only≈656 tokens · 8 read tools
  • findPetsByStatus≈103
  • loginUser≈95
  • getOrderById≈92
  • getUserByName≈89
  • getPetById≈87
  • findPetsByTags≈86
  • getInventory≈52
  • logoutUser≈52
Not offered≈1,631 tokens · 11 writes
  • addPet≈228
  • updatePet≈226
  • updateUser≈180
  • createUsersWithListInput≈178
  • placeOrder≈160
  • createUser≈146
  • updatePetWithForm≈141
  • uploadFile≈106
  • deletePet≈94
  • deleteOrder≈92
  • deleteUser≈80

Install PlugIt

An https URL, or a path to a .json or .yaml file.

Nothing is sent anywhere: this only fills in the commands.

go install github.com/swayam5342/plugit/cmd/plugit@latest
plugit add my-api https://petstore3.swagger.io/api/v3/openapi.json
plugit install my-api
No Go? Download a release

Go 1.26.7 or newer (older versions fetch it for you). Windows, macOS and Linux; one binary, no CGO.