New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@toolrelay/cli

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@toolrelay/cli

CLI for ToolRelay — validate configs, serve local MCP servers, and deploy to production with audit traces

latest
npmnpm
Version
1.1.0
Version published
Maintainers
1
Created
Source

@toolrelay/cli

Turn any REST API into an MCP server that AI agents can use — in one command.

Define your API endpoints in a JSON config, and the CLI gives you a local Model Context Protocol server that Claude, GPT, and other AI agents can connect to instantly. No SDK integration, no code changes, no infrastructure to manage.

Why

AI agents need tools. Your API already exists. The gap between the two is boilerplate: building an MCP server, handling auth, mapping parameters, debugging what the agent actually sent. This CLI closes that gap.

  • Zero code — describe your API in JSON, get a working MCP server
  • Works with any REST API — GET, POST, PUT, DELETE with path, query, body, and header parameters
  • Built-in auth — static tokens, API keys, OAuth 2.0 (with PKCE), custom headers
  • Audit traces — every tool call logs the full request/response cycle so you can see exactly what happened
  • Session viewer — browse past sessions in a local web UI, like Playwright's HTML reporter for API calls
  • Environment variable interpolation${VAR} syntax keeps secrets out of committed config files
  • Deploy when ready — one command to go from local testing to a hosted MCP endpoint at toolrelay.io

Quick start

npx @toolrelay/cli init

The wizard walks you through your API — name, base URL, auth, and endpoints. It generates a toolrelay.json config file.

Then start the MCP server:

npx @toolrelay/cli serve toolrelay.json

That's it. Add the printed URL to Claude Desktop's config and your API is available as tools.

How it works

                  toolrelay.json
                       |
    npx @toolrelay/cli serve toolrelay.json
                       |
          Local MCP Server (localhost:8787)
           /            |            \
     tools/list    tools/call     health
                       |
              Your REST API backend
  • You describe your API in toolrelay.json — endpoints, parameters, auth
  • serve starts a local MCP Streamable HTTP server
  • AI agents connect and discover your tools via tools/list
  • When an agent calls a tool, the CLI maps parameters, injects auth, and proxies the request to your backend
  • Every call is logged with full audit traces — request, response, timing, errors

Config file

The init wizard generates this, or create it by hand:

{
  "app": {
    "name": "My API",
    "base_url": "http://localhost:3000",
    "auth_type": "static_token",
    "auth_config": { "token": "${API_TOKEN}" }
  },
  "tools": [
    {
      "name": "get_user",
      "description": "Get a user by ID",
      "http_method": "GET",
      "endpoint_path": "/api/users/{id}",
      "parameter_mapping": [
        { "name": "id", "type": "string", "required": true, "target": "path", "description": "The user ID" }
      ]
    }
  ]
}

Tip: description on both tools and parameters is how AI agents decide which tool to use. Clear descriptions directly improve how well agents interact with your API.

Environment variables

Use ${VAR_NAME} in any string field to reference environment variables. Secrets stay out of your config:

export API_TOKEN=sk-my-secret-key
npx @toolrelay/cli serve toolrelay.json

If a referenced variable is missing, the CLI fails with a clear error listing the missing names.

Auth types

auth_typeauth_configDescription
noneNo authentication
static_token{ "token": "..." }Bearer token in Authorization header
api_key_relay{ "header_name": "X-API-Key" }Consumer API keys relayed to backend
custom_header{ "headers": { "X-Custom": "value" } }Custom header name/value pairs
oauth2{ "authorize_url", "token_url", ... }OAuth 2.0 with PKCE (see OAuth2 section)

Parameter mapping

Each parameter in parameter_mapping tells the CLI how to translate what the agent sends into what your API expects:

FieldRequiredDescription
nameyesParameter name (what the AI agent sends)
typeyesstring, number, boolean, object, or array
requiredyesWhether the parameter is required
targetyesWhere it goes: path, query, body, or header
backend_keynoBackend field name if different from name
default_valuenoDefault when not provided
descriptionnoShown to AI agents — always include this

Path parameters replace {placeholder} in the URL. Query parameters are appended as ?key=value. Body parameters are sent as JSON (use dot-notation in backend_key for nesting, e.g. address.city). Header parameters are injected as HTTP headers.

A single tool can mix all four targets:

{
  "name": "update_item",
  "http_method": "PUT",
  "endpoint_path": "/api/items/{item_id}",
  "parameter_mapping": [
    { "name": "item_id", "type": "string", "required": true, "target": "path" },
    { "name": "dry_run", "type": "boolean", "required": false, "target": "query", "default_value": false },
    { "name": "title", "type": "string", "required": true, "target": "body" },
    { "name": "idempotency_key", "type": "string", "required": false, "target": "header", "backend_key": "Idempotency-Key" }
  ]
}

Commands

serve — Local MCP server

npx @toolrelay/cli serve toolrelay.json
npx @toolrelay/cli serve toolrelay.json --port 9000 --verbose

Starts a local MCP Streamable HTTP server. On startup it prints a Claude Desktop config snippet you can copy directly.

OptionDescription
--base-url <url>Override base_url from config
-p, --port <number>Port (default: 8787)
-v, --verboseShow response headers and extra detail

Endpoints:

EndpointDescription
POST /mcpMCP JSON-RPC (tools/list, tools/call, etc.)
GET /mcpSSE stream (with Mcp-Session-Id)
GET /healthHealth check + OAuth status
GET /timelineCall timeline as JSON
GET /oauth/startTrigger OAuth flow (OAuth2 apps)
GET /oauth/statusCheck OAuth state

Every tool call is tracked with sequence number, timing, arguments, status, and the gap between calls. On Ctrl+C, a formatted timeline and summary are printed. Sessions are saved to .toolrelay/sessions/ — browse them with toolrelay ui.

init — Generate a config

npx @toolrelay/cli init              # Interactive wizard
npx @toolrelay/cli init --yes        # Starter template

validate — Check config

npx @toolrelay/cli validate toolrelay.json

Validates without making HTTP calls. Catches schema errors, path parameter mismatches, and missing auth fields. Run in CI to catch config issues before deploying.

ui — Session viewer

npx @toolrelay/cli ui

Opens a local web UI to browse past serve sessions. Drill into individual tool calls to see parameter resolution, request/response bodies, diagnostics, and errors.

publish — Deploy to production

npx @toolrelay/cli login
npx @toolrelay/cli publish toolrelay.json
npx @toolrelay/cli publish toolrelay.json --dry-run

Deploys your config to ToolRelay. The command is idempotent — creates on first run, updates only what changed after that.

What you get after publishing:

  • Hosted MCP endpoint at https://proxy.toolrelay.io/mcp/<your-slug>
  • Consumer portal for API key self-service
  • Auto-generated docs — OpenAPI spec, SKILL.md, landing page
  • Usage analytics — call volume, latency, error rates per tool
  • Rate limiting and caching — per-consumer, per-tier controls
OptionDescription
--dry-runShow what would change without making API calls
--pruneDelete remote tools no longer in config

For CI/CD, use TOOLRELAY_DEPLOY_TOKEN instead of toolrelay login. Generate one at toolrelay.io/dashboard/settings.

OAuth2

When auth_type is "oauth2", the serve command handles the full browser-based authorization code flow locally:

{
  "auth_config": {
    "authorize_url": "https://provider.com/oauth/authorize",
    "token_url": "https://provider.com/oauth/token",
    "client_id": "${OAUTH_CLIENT_ID}",
    "client_secret": "${OAUTH_CLIENT_SECRET}",
    "scopes": "read write"
  }
}

On startup, a browser window opens for authorization. After you approve, tokens are stored in memory and injected into every tool call automatically. Refresh is handled transparently.

client_id and client_secret are optional — public client PKCE flows work without them.

Register http://localhost (any port) as a redirect URI in your OAuth provider.

PKCE

PKCE is enabled by default. Set "use_pkce": false for providers that reject it (e.g., AWS Cognito confidential clients):

ProviderPKCERecommendation
Auth0, Okta, Google, SupabaseYesLeave default
AWS Cognito (public client)YesLeave default
AWS Cognito (confidential client)May rejectSet "use_pkce": false

Workflow

1. npx @toolrelay/cli init          → Generate toolrelay.json
2. npx @toolrelay/cli serve         → Test locally with Claude Desktop
3. (iterate on config)
4. npx @toolrelay/cli publish       → Deploy to production

File locations

PathPurpose
toolrelay.jsonApp + tool config (committed to git)
.toolrelay/sessions/Local session logs (auto-gitignored)
~/.toolrelay/credentials.jsonLogin credentials (mode 0600)

License

Proprietary — see LICENSE for details.

Keywords

toolrelay

FAQs

Package last updated on 28 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts