mcp-rest-api
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
mcp-rest-api
An MCP server for testing REST APIs, built with Bun and TypeScript.
It runs over stdio and exposes one tool, http_request, that sends HTTP requests to a configured
base URL and returns status, headers, body and timing.
Features
All standard HTTP methods:
GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACEDetailed response: status code, status text, response headers, body, timing
Request bodies for
POST,PUTandPATCH(JSON objects/arrays or raw strings)Parameter binding:
{id}/:idpath placeholders and structured query params, URL-encoded for youGlobal headers from
HEADER_*environment variablesCase-insensitive prefix (
HEADER_,header_,HeAdEr_)Header name case preserved
Priority: per-request > auth > global
Authentication from environment variables: Basic, Bearer, API key
Response size limit (default 10000 bytes) with truncation metadata; only the body is truncated
SSL certificate verification, on by default, can be turned off for self-signed certificates
Proxy support: SOCKS5, SOCKS5h, SOCKS4/4a, HTTP and HTTPS proxies, with
NO_PROXYCredential masking: auth headers show as
Bearer ****cretin the result, and secrets echoed back by the API are scrubbed from the response body and headers
Related MCP server: API Request MCP Server
Requirements
To run with
npx: Node.js 20 or laterTo develop: Bun 1.4 or later
Install
No install step is needed with npx:
BASE_URL=https://jsonplaceholder.typicode.com npx -y @piinalpin/mcp-rest-apiFrom source:
bun installConfiguration
All configuration comes from environment variables. Only BASE_URL is required.
Variable | Default | Description |
| (required) | Base URL for all requests, e.g. |
| Global header. | |
| Basic auth username (needs | |
| Basic auth password | |
| Bearer token, sent as | |
| Header name for API key auth, e.g. | |
| API key value | |
|
| Maximum response body size in bytes |
|
| Set to |
| Proxy URL, e.g. | |
| Comma-separated hosts that bypass the proxy | |
|
| Request timeout in milliseconds |
The server stops at startup with a clear message when the configuration is invalid.
Custom headers
Every environment variable whose name starts with HEADER_ (any case) becomes a header on every request.
The part after the prefix is used as the header name, with its case kept:
HEADER_Accept=application/json # Accept: application/json
header_X-Request-Source=mcp # X-Request-Source: mcp
HeAdEr_X-Tenant-ID=acme # X-Tenant-ID: acmeHeader names with - cannot be set with export in most shells. Set them in the MCP client
env block (see examples) or with env 'HEADER_X-Api-Version=2' bun run start.
When the same header (compared case-insensitively) comes from more than one place, this order applies:
Per-request
headersin the tool call (highest)Authentication headers (
Authorization, API key header)Global
HEADER_*headers (lowest)
Authentication
Set one of these:
Basic:
AUTH_BASIC_USERNAMEandAUTH_BASIC_PASSWORDBearer:
AUTH_BEARERAPI key:
AUTH_APIKEY_HEADER_NAMEandAUTH_APIKEY_VALUE
The API key can be combined with Basic or Bearer. Basic and Bearer cannot be used together because both
use the Authorization header. Credentials stay in the server environment and are never part of tool arguments.
Credential masking
Credentials never appear in plain text in a tool result.
Request summary. Credential headers are masked and keep their auth scheme:
Header sent | Shown as |
|
|
|
|
|
|
Values shorter than 12 characters are masked fully (****). Masked headers: Authorization,
Proxy-Authorization, Cookie, X-API-Key, Api-Key, ApiKey, X-Auth-Token and the
AUTH_APIKEY_HEADER_NAME header. This applies to auth from environment variables, to HEADER_*
headers, and to credentials passed in per-request headers.
Response scrubbing. Some APIs echo credentials back (debug endpoints, error messages, reflected headers). Every occurrence of these secrets is replaced in the response body, response headers, request URL, request body and error messages:
Bearer token, API key value, Basic password and its base64 form
Proxy password from
PROXY_URLCredentials from per-request credential headers
The URL-encoded forms of all of the above
Scrubbing runs before truncation, and the server reads extra bytes past RESPONSE_SIZE_LIMIT, so a secret
that crosses the limit is still replaced. Secrets shorter than 6 characters are masked in headers but are
not searched for in bodies, because short strings would replace normal content.
Response size
Bodies larger than RESPONSE_SIZE_LIMIT bytes are truncated at a UTF-8 character boundary.
The status, headers and request summary are always complete. A truncated result contains:
"truncation": {
"originalSize": 52000,
"originalSizeExact": true,
"returnedSize": 10000,
"truncationPoint": 10000,
"sizeLimit": 10000,
"message": "Response body truncated: returned 10000 of 52000 bytes (limit 10000). ..."
}The server reads at most 50 MB of a body to measure it. For larger bodies originalSizeExact is false.
SSL verification
Verification is on by default. For development servers with self-signed certificates:
ENABLE_SSL_VERIFY=falseThe server writes a warning to stderr when verification is off. The setting also applies to the TLS
connection to an https:// proxy.
Proxy
PROXY_URL supports:
Scheme | Notes |
| SOCKS5, DNS resolved locally |
| SOCKS5, DNS resolved by the proxy |
| SOCKS4 / SOCKS4a |
| HTTP proxy. HTTPS targets use a |
Proxy credentials go in the URL: socks5://user:pass@host:1080. Credentials are not shown in logs or tool output.
NO_PROXY entries: * (all hosts), example.com or .example.com (the domain and its subdomains),
host:port (only that port).
Usage
Run the server directly (it waits for MCP messages on stdin):
BASE_URL=https://jsonplaceholder.typicode.com npx -y @piinalpin/mcp-rest-apiOr from source with Bun:
BASE_URL=https://jsonplaceholder.typicode.com bun run startClient setup
Most MCP clients use the same JSON shape:
{
"mcpServers": {
"rest-api": {
"command": "npx",
"args": ["-y", "@piinalpin/mcp-rest-api"],
"env": {
"BASE_URL": "https://api.example.com/v1",
"AUTH_BEARER": "your-token",
"HEADER_Accept": "application/json"
}
}
}
}Some clients use a different key or format. CLIENTS.md has the config file location, the
mcp add command and a ready-to-copy file in examples/clients/ for each of these:
Client | Quick start |
Claude Desktop | |
Claude Code |
|
OpenAI Codex |
|
OpenCode | opencode.json ( |
Command Code |
|
Google Antigravity | |
GitHub Copilot (VS Code) | vscode-copilot.mcp.json as |
GitHub Copilot CLI |
|
Cursor | cursor.mcp.json as |
Cline | |
Amp |
|
Hermes Agent | hermes.config.yaml ( |
Kimi Code | kimi-code.mcp.json as |
Pi |
|
CodeBuddy |
|
MCP Inspector
BASE_URL=https://jsonplaceholder.typicode.com npx @modelcontextprotocol/inspector npx -y @piinalpin/mcp-rest-apiTool: http_request
Argument | Type | Required | Description |
|
| yes | HTTP method |
| string | yes | Path relative to |
| object | no | Values for the endpoint placeholders |
| object | no | Query parameters. Arrays repeat the key; |
| string, object or array | no | Only for |
| object | no | Per-request headers |
Example call:
{ "method": "POST", "endpoint": "/users", "body": { "name": "Ada" } }Parameter binding
Write the endpoint as a template and pass the values separately. The server URL-encodes them,
so values with spaces, /, &, ?, # or non-ASCII characters are safe.
{
"method": "GET",
"endpoint": "/users/{userId}/posts/:postId",
"pathParams": { "userId": 42, "postId": "hello world" },
"queryParams": { "sort": "desc", "tag": ["news", "tech"], "draft": false }
}Request URL: https://api.example.com/v1/users/42/posts/hello%20world?sort=desc&tag=news&tag=tech&draft=false
Path params
{name}works anywhere in the endpoint, including the query string:/search?q={term}.:nameworks at the start of a path segment:/users/:id. A colon inside a segment stays literal, so/v1/projects/{id}:batchGetworks.A value is always one path segment:
/is encoded as%2F. The values"",.and..are rejected.A placeholder without a value is an error. A
pathParamskey with no placeholder adds a warning tovalidation.messages.
Query params
Values can be strings, numbers, booleans, arrays of those, or
null.Arrays repeat the key:
{"id": [1, 2]}gives?id=1&id=2.A query param replaces a param with the same name from the endpoint or
BASE_URL.nullremoves it.Priority, highest first:
queryParams, then the endpoint query string, thenBASE_URLquery params.
When parameters are bound, the result shows the template as request.endpoint next to the final request.url.
Example result:
{
"request": {
"url": "https://api.example.com/v1/users",
"method": "POST",
"headers": { "Authorization": "Bearer ****oken", "Content-Type": "application/json", "Content-Length": "14" },
"body": "{\"name\":\"Ada\"}"
},
"response": {
"statusCode": 201,
"statusText": "Created",
"timing": "84.2ms",
"headers": { "content-type": "application/json" },
"body": "{\"id\":1,\"name\":\"Ada\"}"
},
"validation": { "isError": false, "messages": ["Request completed successfully"] }
}HTTP 4xx and 5xx responses are normal results with validation.isError: true. Redirects are not followed.
Invalid input, network errors, timeouts, TLS and proxy failures return an MCP tool error.
More examples: examples/requests.md.
Development
bun test # unit and integration tests (local echo, SOCKS5, HTTP proxy and TLS servers)
bun run typecheck # tsc --noEmit
bun run dev # run with --watch
bun run smoke # after bun run build: start dist/index.js with Node.js and call the tool over stdioGitHub Actions (.github/workflows/ci.yml) runs the typecheck, tests, build and smoke test on
every push to main and every pull request. It then packs the npm package and runs it with npx on Linux
and Windows with Node.js 24. On a v* tag it also publishes to npm (see Publish).
The TLS tests generate a self-signed certificate with openssl and are skipped when it is not installed.
Build
bun run build # dist/index.js: one Node.js file with all dependencies bundled
bun run compile # dist/mcp-rest-api: a standalone binary that needs neither Node.js nor Bundist/index.js starts with #!/usr/bin/env node and is the package bin, so it runs with
node dist/index.js, bun dist/index.js or npx. All dependencies are bundled into it, so npx installs
nothing else.
Test the npm package locally
bun run build
npm packThen run the tarball from a different directory. Use --package; npm 12 does not run a tarball path given as the command:
BASE_URL=https://jsonplaceholder.typicode.com npx -y --package=/absolute/path/to/piinalpin-mcp-rest-api-0.1.0.tgz mcp-rest-apiPublish
CI publishes to npm when you push a version tag. Pushes to main and pull requests only run the checks.
npm version patch # or minor / major: updates package.json and creates the tag v1.2.3
git push --follow-tagsFor the tag, the workflow:
Fails early if the tag (without
v) differs from theversioninpackage.json.Runs the typecheck, tests, build and smoke test, then the
npxchecks on Linux and Windows.Publishes the exact tarball that passed those checks. Versions with a prerelease part, such as
1.2.0-beta.1, get thenextdist-tag; others getlatest.
Publishing uses npm trusted publishing (OIDC), so no npm token is stored in GitHub, and npm adds provenance to each version. One-time setup on npmjs.com, under the package's Settings > Trusted publishing, add a GitHub Actions publisher:
Field | Value |
Organization or user |
|
Repository |
|
Workflow filename |
|
Environment | (leave empty) |
Allowed actions | enable |
New trusted publisher configurations allow only npm stage publish by default, so npm publish must be enabled.
A new configuration expires if it has no successful publish within 2 days, so push the tag soon after creating it.
If npmjs.com does not let you add a trusted publisher before the package exists, publish the first version by hand:
bun run build
npm login
npm publishprepublishOnly runs the typecheck, the tests and the build first. The scoped package is published
as public (publishConfig.access).
Project layout
src/index.ts entry point: config, MCP server, stdio transport
src/config.ts environment variable parsing and validation
src/headers.ts HEADER_* parsing, auth headers, priority merge
src/mask.ts credential masking and secret scrubbing
src/url.ts BASE_URL + endpoint resolution
src/params.ts path placeholder and query parameter binding
src/proxy.ts proxy agent selection and NO_PROXY matching
src/http.ts HTTP transport (node:http / node:https), timeout, body reading
src/truncate.ts UTF-8 safe body truncation
src/tool.ts http_request tool schema and handlerBun's fetch does not support SOCKS proxies, so requests go through node:http / node:https with
socks-proxy-agent, http-proxy-agent and https-proxy-agent. Requests with and without a proxy use the same code path.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
AI-callable tools for API mocking, testing, monitoring, security, and automation.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client. Air Pipe MCP token as a bearer credential, e.g. 'Authorization: Bearer <token>'. Create one at https://app.airpipe.io/
Send one HTTP request, or one per row of a dataset, CSV or Google Sheet, and get the response back
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceProvides a structured HTTP client tool for making web requests with full HTTP method support, detailed response metadata, and error handling. Enables AI assistants to interact with any web API or endpoint through the curl_request tool.1 npm2MIT
- AlicenseBqualityDmaintenanceEnables automatic HTTP requests (GET, POST, PUT, DELETE, etc.) with JSON validation and proxy support. Supports custom headers, request bodies, and environment variable configuration for seamless API integration.12 npmMIT
- FlicenseAqualityDmaintenanceProvides a generic HTTP client tool allowing AI agents to make arbitrary HTTP requests from their environment, with support for environment-variable placeholders for secrets.1-
- AlicenseAqualityCmaintenanceEnables AI agents to execute HTTP/REST/GraphQL requests against any endpoint, including private VPN hosts and local services, while logging untruncated headers, request bodies, and raw responses into a local SQLite audit history. Agents can then search that history by keyword, date, method, or status, retrieve full details by ID, and export everything to JSON.5MIT