# Using Tools

> List, inspect, and call tools on connected MCP servers from the CLI.

**URL:** https://inference.sh/docs/connectors/using-tools
**Last updated:** 2026-10-11

---

List, inspect, and call tools on connected MCP servers from the CLI.

---

## List Tools

See all tools available on a connected server:

```bash
belt mcp tools linear
belt mcp tools linear --json   # array of {name, description, inputSchema}

# Same output — `mcp run` with a bare slug lists tools instead of erroring
belt mcp run linear
```

```
linear — 24 tools

tool                  description
list_issues           List issues with filtering and pagination
create_issue          Create a new issue
update_issue          Update an existing issue
get_issue             Get issue details by ID
list_projects         List all projects in the workspace
...
```

---

## Inspect a Tool

View a tool's input schema before calling it:

```bash
belt mcp tools linear:list_issues
belt mcp tools linear:list_issues --json   # single tool object with inputSchema

# Same schema view from the run command — handy when you already have slug:tool
belt mcp run linear:list_issues --help
```

```
linear:list_issues

List issues with filtering and pagination

  required: project
  input schema:
  {
    "type": "object",
    "properties": {
      "project": {
        "type": "string",
        "description": "Project key to filter by"
      },
      "status": {
        "type": "string",
        "description": "Filter by status (backlog, todo, in_progress, done)"
      },
      "limit": {
        "type": "integer",
        "description": "Max results to return"
      }
    }
  }

  run: belt mcp run linear:list_issues --input '{"project": "..."}'
```

Required fields and the sample `--input` line are derived from the tool's JSON Schema (`required` plus property types).

---

## Call a Tool

Run a tool and get the result:

```bash
# Inline JSON input (--input flag)
belt mcp run linear:list_issues --input '{"project": "INF", "limit": 5}'

# Positional JSON (same priority as --input when flag is omitted)
belt mcp run linear:list_issues '{"project": "INF", "limit": 5}'

# Input from file (@filename or path)
belt mcp run linear:create_issue --input @issue.json

# Piped stdin
echo '{"project": "INF"}' | belt mcp run linear:list_issues

# No input required
belt mcp run slack:list_channels

# Filter output with built-in jq (no external jq binary)
belt mcp run linear:list_issues --jq '.issues[] | .id'
belt mcp run linear:list_issues --jq '.issues[] | {id, title}'
```

Input resolves from `--input`, a positional argument, or piped stdin (in that order). See [CLI setup — JSON input](/docs/extend/cli-setup#running-apps).

Use `--jq` to print only the fields you need. String values are unquoted (like `jq -r`); other values are compact JSON.

Pass tool arguments with `-i` / `--input`, a positional JSON argument, or piped stdin — not `--args`. An unknown flag prints the parse error on stderr and reminds you where input goes.

When the MCP server marks a result with `is_error: true`, the full JSON still prints to stdout (so you can inspect or re-filter it), but stderr includes the server's error text when the payload carries one (`output`, `content[].text`, `message`, or `error`). A line points at `belt mcp tools <slug>:<tool>` for the input schema. The process exits **1**. With `--jq`, a filter written for the success shape may print nothing on stdout even though stderr has the failure detail — check `$?` and stderr, or drop `--jq` to see the raw payload.

### MCP Apps pages in the web playground

In the workspace UI, open a connector from **Explore → MCP servers** (or `/mcps/{slug}`). When you run a tool whose result includes `ui.html`, the playground renders that **MCP App** page above the JSON output. The page runs in a sandboxed iframe with the CSP from the tool result; follow-up tool calls from the page are proxied to the same server.

Permalinks (`/mcp-runs/{id}`) reload the recorded run so you can inspect or tweak inputs and re-run. Tools that return `input_required` (MRTR) cannot complete nested calls from the embedded page — use the CLI or API retry flow instead.

Results are printed as formatted JSON (or filtered lines when `--jq` is set).

When the tool returns a **partial page** (for example `next_cursor`, `has_more`, or GraphQL-style `pageInfo.hasNextPage`), the CLI prints a muted hint on **stderr** after stdout:

- `more results available: pass cursor <token> in --input to fetch the next page` when the payload names a cursor
- `more results available: this is one page. pass the server's cursor/page argument in --input to fetch the next` when the payload only signals more pages without a cursor field

Pass the cursor in your next call's JSON input (field name depends on the MCP tool schema — often `cursor`, `page`, or `after`). Hints follow the same suppression rules as other stderr tips (`INFSH_NO_TIPS=1`, non-TTY stderr, and `--jq` on `belt mcp run`). See [CLI setup — JSON output](/docs/extend/cli-setup).

```json
{
  "issues": [
    {
      "id": "INF-123",
      "title": "Fix auth middleware",
      "status": "in_progress",
      "assignee": "okaris"
    }
  ]
}
```

---

## Interactive elicitation (MRTR)

Some MCP tools cannot finish in a single round trip. The server returns an interim result with `input_required: true` and one or more `input_requests` (Multi Round-Trip Request / MRTR). Each request uses method `elicitation/create` with either:

| Mode | CLI behavior (interactive) |
|------|----------------------------|
| **form** | Renders a terminal form from `requestedSchema` (string, number, boolean, enum fields) |
| **url** | Shows the authorization URL, optionally opens your browser, then asks you to confirm when done |

`belt mcp run` handles this automatically in interactive terminals: it collects your answers or browser confirmation, retries the tool call with `inputResponses` and `requestState`, and repeats if the server asks for more input.

**Non-interactive** shells (`CI` set, no TTY, or `BELT_NON_INTERACTIVE=1`) cannot prompt. The CLI prints the MRTR envelope as JSON on stdout and exits with code **2**:

```json
{
  "input_required": true,
  "input_requests": { "...": { "method": "elicitation/create", "params": { ... } } },
  "request_state": "..."
}
```

Parse `input_requests`, complete each elicitation step out of band (open URLs, collect form values), then retry via `POST /mcps/{slug}/tools/{tool}` with the original `arguments`, `inputResponses`, and `requestState`. See [Credentials API — MCP tool proxy](/docs/api/rest/credentials#mcp-tool-proxy).

When the tool runs inside an **agent chat**, the runtime surfaces the same envelope on the tool invocation (`awaiting_input` + `MCPInputState` in `data`). Custom chat UIs should use **`submitMCPInput`** and the parsing helpers in **@inferencesh/sdk ≥ v0.12.0** — see [JavaScript SDK — MCP input requests](/docs/api/sdk-javascript#mcp-input-requests-mrtr).

---

## Tool Reference Format

Tools are referenced as `slug:tool_name`:

```
belt mcp tools <slug>              # list all tools
belt mcp run <slug>                # same as mcp tools <slug>
belt mcp tools <slug>:<tool>       # inspect one tool
belt mcp run <slug>:<tool> --help  # same schema view as tools <slug>:<tool>
belt mcp run <slug>:<tool>         # call a tool
```

---

## Next

- [Agent Tools](/docs/connectors/agent-tools) — give your agents access to connector tools
- [MCP Server](/docs/connectors/mcp-server) — access these tools from Claude Code or Cursor
