> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmcp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Test Tool

> Execute a tool live against the upstream API and return the response, timing, and outbound request details.

Runs the tool through the same execution pipeline that MCP clients hit, but with the admin "Test Tool" affordances: by default it uses the **test credentials** stored on the tool/server, surfaces the outbound HTTP request for inspection, and records `last_tested_at` / `last_test_response_ms` on success.

<Note>
  This is the endpoint that the **Test** button in the admin UI calls. Use it to validate a tool's parameter mapping, headers, and response handling without going through an MCP client.
</Note>

<Note>
  Draft and inactive tools cannot be tested — publish/activate them first or you'll get a `422`. Pass `use_test_credentials: false` to execute against production credentials instead of test credentials.
</Note>

## Path Parameters

<ParamField path="server_id" type="string" required>
  The UUID of the server the tool belongs to (e.g. `836995ae-1cff-41ec-823e-a4f07ccca3a0`). Numeric IDs are also accepted for backwards compatibility.
</ParamField>

<ParamField path="id" type="string" required>
  The UUID of the tool to test (e.g. `5376af81-6bb8-4b01-800c-508d7672e394`). Numeric IDs are also accepted for backwards compatibility.
</ParamField>

## Body Parameters

<ParamField body="arguments" type="object">
  Object of input arguments to pass to the tool. Keys must match the tool's `input_schema.properties`. Defaults to `{}`.
</ParamField>

<ParamField body="use_test_credentials" type="boolean" default="true">
  When `true` (default), execute with test credentials so production keys aren't put through experimentation. When `false`, execute against live production credentials — the same path an MCP client takes.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
       --url https://yoursite.com/wp-json/getmcp/v1/servers/836995ae-1cff-41ec-823e-a4f07ccca3a0/tools/5376af81-6bb8-4b01-800c-508d7672e394/test \
       --header 'Authorization: Bearer gmcp_your_api_key' \
       --header 'content-type: application/json' \
       --data '{
         "arguments": { "city": "London" },
         "use_test_credentials": true
       }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://yoursite.com/wp-json/getmcp/v1/servers/836995ae-1cff-41ec-823e-a4f07ccca3a0/tools/5376af81-6bb8-4b01-800c-508d7672e394/test",
      headers={
          "Authorization": "Bearer gmcp_your_api_key",
          "Content-Type": "application/json",
      },
      json={
          "arguments": {"city": "London"},
          "use_test_credentials": True,
      },
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://yoursite.com/wp-json/getmcp/v1/servers/836995ae-1cff-41ec-823e-a4f07ccca3a0/tools/5376af81-6bb8-4b01-800c-508d7672e394/test",
    {
      method: "POST",
      headers: {
        "Authorization": "Bearer gmcp_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        arguments: { city: "London" },
        use_test_credentials: true,
      }),
    }
  );
  const data = await response.json();
  ```

  ```php PHP theme={null}
  $response = wp_remote_post(
      "https://yoursite.com/wp-json/getmcp/v1/servers/836995ae-1cff-41ec-823e-a4f07ccca3a0/tools/5376af81-6bb8-4b01-800c-508d7672e394/test",
      [
          "headers" => [
              "Authorization" => "Bearer gmcp_your_api_key",
              "Content-Type"  => "application/json",
          ],
          "body" => wp_json_encode([
              "arguments" => ["city" => "London"],
              "use_test_credentials" => true,
          ]),
      ]
  );
  $data = json_decode( wp_remote_retrieve_body( $response ), true );
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "outbound_request": {
      "method": "GET",
      "url": "https://wttr.in/London?format=j1",
      "headers": {
        "Accept": "application/json"
      },
      "body": null
    },
    "raw_response": {
      "status_code": 200,
      "headers": { "content-type": "application/json" },
      "body": "{ \"current_condition\": [ ... ] }"
    },
    "mcp_output": {
      "content": [
        { "type": "text", "text": "{\"current_condition\":[...]}" }
      ],
      "isError": false
    },
    "timing": {
      "total_ms": 342
    }
  }
  ```

  ```json 200 OK — execution error theme={null}
  {
    "outbound_request": null,
    "raw_response": null,
    "mcp_output": {
      "content": [
        { "type": "text", "text": "Test failed: cURL error 6: Could not resolve host: invalid.example" }
      ],
      "isError": true
    },
    "timing": { "total_ms": 0 }
  }
  ```

  ```json 404 Not Found theme={null}
  {
    "code": "getmcp_not_found",
    "message": "Tool not found.",
    "data": { "status": 404 }
  }
  ```

  ```json 422 Unprocessable Entity — draft/inactive tool theme={null}
  {
    "code": "getmcp_tool_not_testable",
    "message": "Cannot test a draft tool. Publish the tool first.",
    "data": { "status": 422 }
  }
  ```
</ResponseExample>

## Response Fields

<ResponseField name="outbound_request" type="object">
  The exact HTTP request that was dispatched to the upstream API — `method`, `url`, `headers`, `body`. Useful for verifying that parameter mapping and templating produced the URL/body you expected. `null` when the executor short-circuited before issuing a request.
</ResponseField>

<ResponseField name="raw_response" type="object">
  The unprocessed upstream response — `status_code`, `headers`, `body` (always a string). `null` on transport errors.
</ResponseField>

<ResponseField name="mcp_output" type="object">
  The MCP-shaped result that an MCP client would have received: `{ content: [{ type, text }], isError }`. `isError` is `true` when the upstream returned a non-2xx status or the executor itself threw.
</ResponseField>

<ResponseField name="timing" type="object">
  `{ total_ms: <int> }` — wall-clock duration of the full test, including auth resolution and response mapping.
</ResponseField>

## Status Codes

| Code  | Meaning                                                                            |
| ----- | ---------------------------------------------------------------------------------- |
| `200` | Test ran. Check `mcp_output.isError` to distinguish upstream failure from success. |
| `404` | Tool (or its parent server) not found.                                             |
| `422` | Tool status is `draft` or `inactive` — not testable in its current state.          |
