API reference

Request a new tool

Ask for a new deterministic tool to be added to this service, describing the job and an example.

GET POST /api/tools/request MCP tool tool_request

Records a request for a new tool. Use it when you (an agent or a person) keep doing the same deterministic job that has exactly one right answer and no tool here does it: a conversion, a validation, a calculation, a parser. Describe the job in problem, and give an example_input and the expected_output if you can; concrete examples make a request much more likely to be built. Requests are reviewed by the owner; check progress with tool_requests. A request is a suggestion, not an order, and nothing is guaranteed. Each client can submit up to 20 requests per 24 hours.

Browser version (runs locally): Request a Tool.

Try it

Credentials
Remember these credentials

Not saved: you will paste them again next time.

No credentials yet? Get a client ID and secret. They are sent only to this site, in an Authorization: Basic header.

POST /api/tools/request with a JSON body

Parameters

Parameter Type Default Description
title required string (≤ 120 chars) — Short name for the tool, e.g. "IBAN validator" or "Semantic version compare".
problem required string (≤ 4000 chars) — What you need done, why, and how you do it today. Say if you are an agent and what you are working on.
example_input string (≤ 4000 chars) — A sample input the tool would receive (no secrets or personal data).
expected_output string (≤ 4000 chars) — What the tool should return for example_input.
category Encoding | Hashing | Keys & Certificates | Inspect & Identify | Text & Data | Time & Scheduling | Other — Closest existing category, or Other.

Also accepted on every endpoint: format (json | text). Parameters may come from the query string, a JSON object body, an urlencoded or multipart form, or (for input) a text/plain body.

Global parameters
Parameter Type Default Description
format json | text json json returns the documented object. text returns only the primary value as text/plain (see "Text output").

Response 200 application/json

Field Type Description
request_id string Identifier of the request, e.g. tr_….
status "received" Always received for a new request.
created_at string When it was recorded (ISO 8601 UTC).
related array of object Similar requests already planned, building or shipped. A shipped one may already do the job.
related[].title string Title of a similar request.
related[].status "received" | "planned" | "building" | "shipped" | "declined" | "duplicate" received (not reviewed yet), planned, building, shipped (see shipped_url), declined or duplicate (see status_note).
related[].url string | null The shipped tool, when there is one.
next string How to follow the request up.

Errors

Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.

Status Code When
400 invalid_parameter A field is empty, too long, or not an allowed value.
429 rate_limited More than 20 requests in 24 hours.
400 missing_parameter A required parameter is absent.
400 unknown_parameter A parameter name is not in the table above (typos are rejected, not ignored).
413 payload_too_large The request body exceeds 1 MiB.
405 method_not_allowed A method other than GET, POST or OPTIONS.

Behaviour

  • Not idempotent: the result can differ between calls (time, randomness, or a live network check).
  • Requires a client ID and secret (authentication). Each call is recorded as one metadata row against your client ID; inputs and outputs are never stored or logged. Responses carry cache-control: no-store.
  • CORS: any origin may call this endpoint from a browser, using your credentials.

Examples

Responses below were produced by running each request through this code at build time. Long strings are shortened.

An agent asks for a version comparison tool

curl -X POST 'https://util.caruana.me/api/tools/request' \
  -H 'content-type: application/json' \
  -d '{"title":"Semantic version compare","problem":"I am a release agent. I compare semver strings (with pre-release tags) several times per run and sometimes get the ordering of 1.0.0-rc.10 vs 1.0.0-rc.9 wrong when reasoning about it.","example_input":"1.0.0-rc.10, 1.0.0-rc.9","expected_output":"1.0.0-rc.10 > 1.0.0-rc.9","category":"Text & Data"}'

Response 200

{
  "request_id": "tr_EXAMPLE",
  "status": "received",
  "created_at": "2026-10-14T09:00:00.000Z",
  "related": [],
  "next": "Call tool_requests (GET /api/tools/requests) with the same credentials to see its status."
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "tool_request",
    "arguments": {
      "title": "Semantic version compare",
      "problem": "I am a release agent. I compare semver strings (with pre-release tags) several times per run and sometimes get the ordering of 1.0.0-rc.10 vs 1.0.0-rc.9 wrong when reasoning about it.",
      "example_input": "1.0.0-rc.10, 1.0.0-rc.9",
      "expected_output": "1.0.0-rc.10 > 1.0.0-rc.9",
      "category": "Text & Data"
    }
  }
}