Build MCP Tools by Hand: A Guide to the GetMCP Tool Editor
Importers get you a first draft. To build MCP tools that an AI client calls correctly every time, you need control over each part of the request and the answer. GetMCP’s Tool Editor is where you do that: one screen to define the HTTP request, the parameters the model may fill in, where each one goes, how the response is trimmed, and a live test panel to prove it works.
This guide is for anyone building or refining tools by hand, whether you started from scratch, from a cURL command or from a spec import. It walks through every section of the editor with the real field names, then shows practical patterns for trimming responses, fixing values and testing safely.
What is the Tool Editor?
A tool in GetMCP is one HTTP request your AI client can make through an MCP server. The Tool Editor is the full-page screen that defines it. It opens when you click Add Tool and choose From Scratch, when a cURL import hands you a tool to finish, or when you click any existing tool on a server’s Tools tab.

The screen has two panels. The left one holds the configuration sections: Basic Info, API Endpoint, Input Parameters, Request Body Template, Response Mapping and Advanced Settings. The right one is Test Tool. The top bar shows the tool’s state: a Draft badge with Save Draft and Publish for new tools, or an Active/Inactive toggle with Save Changes once it is live.

How to build MCP tools in the editor
1. Basic Info: name, description, tags
Tool Name is what you call the tool; the slug shown under it is the name AI clients see, so “Get Order Status” becomes get_order_status. Description (up to 500 characters) is how the model decides whether to call the tool, so say what it does, what it returns and when to use it. Tags group tools in the admin and are optional.
2. API Endpoint: method and URL
Pick the HTTP Method (GET, POST, PUT, PATCH or DELETE) and enter the Endpoint URL. Use {{name}} for path segments the caller must always supply, as in https://api.acme.example/v1/orders/{{order_id}}. The editor warns you when a placeholder belongs to an optional parameter with no default, because an omitted value would reach the API as literal braces, and when a placeholder has no matching parameter, which is fine only if a server connection variable fills it. Re-import from cURL sits under the URL.
3. Input Parameters: what the model may send
Click Add Parameter for each value the AI client supplies. Each parameter has:
| Field | What it does |
|---|---|
| Parameter Name | The argument name the client sends. |
| Type | String, Number, Integer, Boolean, Array or Object. Calls with the wrong type are rejected before your API is touched. |
| Description | Shown to the model. Say what a valid value looks like. |
| Mapping Target | Where the value goes: Path (replaces {{name}}), Query, Body or Header. |
| Mapping Key | The name used in the outbound request, if different. Leave it empty to use the parameter name, so city can be sent as query key q. |
| Default Value | Sent when the model leaves the argument out, and published in the schema. |
| Required | The call is rejected if the argument is missing. |
Drag parameters to reorder them. The JSON Schema Preview under the list shows the exact input schema clients receive, so you never have to write JSON Schema yourself. A body Mapping Key with dots, such as customer.email, writes into a nested JSON object.
4. Request Body Template: the fixed part of the body
The Body Template is the full body sent on every call. Whatever the model fills in for a body parameter is written on top, and everything else goes out exactly as written. Use it for values the model should never choose, such as a list ID or a source tag. A cURL import fills it from your sample; clear it to send only what the AI provides.
5. Response Mapping: what the model reads back
Large API responses cost tokens and distract the model. Selector Engine offers two ways to trim them:
- JSONPath (dot notation) picks one nested value, such as
data.resultsoritems[0]. - JMESPath filters, projects and reshapes, such as
orders[?status=='open'].{id: id, total: total}. See jmespath.org for the syntax.
Open Test expression against a sample response, paste a real response, and click Run expression. You see the pruned result the AI would receive and how much smaller it is. Response Format then sets the output: JSON, Text with an Output Template using {{field}} placeholders (applied to each item when the result is a list), or Image.
6. Advanced Settings
| Setting | What it does |
|---|---|
| Timeout (seconds) | How long to wait for the API, from 1 to 300. The default is 30. |
| Cache TTL (seconds) | Serve identical calls from cache for up to 86,400 seconds. 0 turns caching off. Only successful responses are cached. |
| Retry Count | Retries on failure, 0 to 5, for connection errors and 408, 429, 500, 502, 503 and 504 responses. |
| Retry Backoff | None (immediate), Linear (1s, 2s, 3s…) or Exponential (1s, 2s, 4s…). |
| Custom Headers | Fixed headers on every call. Values can use server connection variables. |
| SSL Verification | Verify the endpoint’s certificate. On by default. |
| Follow Redirects | Follow HTTP 3xx responses automatically. On by default. |
| Safety hints | Read-only, Destructive, Idempotent and Open world hints for clients that ask before running risky tools. Derived from the method automatically; Set manually to override. |
7. Test Tool: prove it before publishing
The right-hand panel builds an argument form from your parameters. Click Run Test; an unsaved tool is saved first. The result has three tabs: MCP Output (exactly what the AI client receives), Raw Response (what the API returned) and Outbound Request (the request GetMCP sent, with a Copy as cURL button). The last five runs stay in a history list. Tests use the server’s Test Credentials and fall back to the server-stored credential when none are set.
Use cases
Cut a product search down to what matters
A store’s search endpoint returns every field for every product. A JMESPath expression such as products[].{id: id, name: title, price: price} keeps three fields, so the model compares more products in less context.
Flow: “Find waterproof jackets under 100” → search_products → JMESPath → short list
Return support tickets as readable lines
A support tool selects the ticket list and uses the Text format with an Output Template like #{{id}} {{subject}} ({{status}}). The model gets one clean line per ticket.
Flow: list_tickets → selector → Output Template → text block
Send a workspace ID as a header
Acme’s API expects the workspace in an X-Workspace-Id header. A workspace_id parameter with Mapping Target Header and Mapping Key X-Workspace-Id lets the model choose the workspace without seeing any credential.
Flow: Model argument → Header mapping → Acme API
Pin the list a newsletter signup goes to
A marketing tool declares only email and first_name. The list ID and a "source": "assistant" tag live in the Body Template, so every signup lands in the right list, whatever the model is asked.
Flow: “Subscribe [email protected]” → add_subscriber → body template + email → email platform
Cache reference data that rarely changes
An operations team’s list_warehouses tool changes maybe once a month. A Cache TTL of 3600 means repeated questions in a busy hour hit the API once.
Flow: Repeated calls → cache hit → no upstream request
Flag a POST that spends money
A create_refund tool is a POST, which the automatic safety hints treat as a plain write. Setting Destructive manually tells clients that respect the hint to ask the user before running it.
Flow: Safety hints → Set manually → Destructive on → client asks for confirmation
Tips and gotchas
- Renaming changes the MCP name. Editing Tool Name regenerates the slug, so prompts or agent instructions that mention the old name need updating.
- The parameter list is a boundary. If a tool declares any parameters, arguments it does not declare are dropped. Delete a parameter and the model can no longer reach that field.
- Defaults are sent; examples are not. Only set a Default Value when that value is right for every call that omits it.
- A broken JMESPath expression fails loudly. The call returns an error naming the expression rather than the unfiltered response. Use Run expression before saving.
- Retry writes with care. Retrying a POST after a timeout can create a duplicate if the first attempt actually succeeded.
- Unsaved new tools are kept for you. A new tool you have not saved is stored in your browser for seven days and offered back when you return.
Related features
- cURL import: fill the editor from one pasted command.
- OpenAPI import: create many tools at once, then refine them here.
- Connection variables: per-account values like a subdomain, filled into URLs and headers.
- Chat Playground: try your tools with a real model before connecting a client.
FAQ
Do I need to know JSON Schema to build MCP tools?
No. You add parameters with a name, type, description and mapping, and GetMCP generates the input schema. The JSON Schema Preview shows the result if you want to check it.
Should I use JSONPath or JMESPath?
Use JSONPath when you need one value or one branch of the response. Use JMESPath when you need to filter a list, keep only some fields or reshape the result; it is the better choice for large responses.
Which credentials does Run Test use?
The server’s Test Credentials, set on the Authentication tab. If none are set, the test uses the server-stored API credential. Connected AI clients never see either.
Can one parameter go into a header or a nested body field?
Yes. Set Mapping Target to Header and put the header name in Mapping Key, or set it to Body and use a dotted Mapping Key such as customer.email for a nested field.
Explore everything a server can hold on the GetMCP features page, then open a tool, trim its response and run a test.
Ship an MCP server for your product this week.
Install GetMCP on any PHP host, import your API and share one URL. Your users can call your tools from Claude tonight.