How MCP Tools Work — Executable Functions for AI

How MCP Tools Work — Executable Functions for AI

2026-03-24

Tools are the action layer of MCP. They let AI do things in the real world — query a database, create a file, send a message, deploy code. Every useful AI integration eventually comes down to tools.

A tool has a name, a description the AI reads to decide when to use it, and a schema that defines what inputs it accepts. The AI generates the inputs. The server executes the function. The result goes back to the AI.

Anatomy of a Tool

Every tool has four parts:

{
  "name": "search_code",
  "description": "Search for code patterns across the project using regex or literal string matching",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "The search pattern (regex or literal string)"
      },
      "path": {
        "type": "string",
        "description": "Directory to search in. Defaults to project root."
      },
      "caseSensitive": {
        "type": "boolean",
        "description": "Whether the search is case-sensitive",
        "default": false
      }
    },
    "required": ["query"]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "matches": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "file": { "type": "string" },
            "line": { "type": "number" },
            "content": { "type": "string" }
          }
        }
      },
      "totalCount": { "type": "number" }
    }
  }
}

name — unique identifier. The AI uses this to call the tool. Convention: snake_case, scoped by domain (github_create_issue, db_run_query, fs_read_file).

description — the most important field. The AI reads this to decide WHEN to use the tool. A bad description means the AI calls the wrong tool or doesn't call it when it should. Be specific about what the tool does, when to use it, and what it doesn't do.

inputSchema — JSON Schema defining the inputs. The AI generates values that conform to this schema. Required fields, types, descriptions, defaults, enums — the more precise the schema, the more reliable the AI's inputs.

outputSchema — optional JSON Schema defining the output structure. When present, the server must return structured data conforming to this schema. Helps the AI parse results reliably.

How Tool Execution Works

AI Model Host Client Server tool call route tools/call result context The model generates: { "name": "search_code", "arguments": { "query": "fn main" } } The server executes the search and returns matches The result becomes context for the model's next response The AI never calls the server directly. The host mediates every interaction.

The request:

{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "tools/call",
  "params": {
    "name": "search_code",
    "arguments": {
      "query": "fn main",
      "path": "src/"
    }
  }
}

A successful response:

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Found 3 matches for 'fn main' in src/"
      }
    ],
    "structuredContent": {
      "matches": [
        { "file": "src/main.rs", "line": 1, "content": "fn main() {" },
        { "file": "src/bin/server.rs", "line": 5, "content": "fn main() -> Result<()> {" },
        { "file": "src/bin/cli.rs", "line": 3, "content": "fn main() {" }
      ],
      "totalCount": 3
    }
  }
}

The response has both content (unstructured, for display) and structuredContent (typed, for programmatic use). A tool can return one or both.

Content Types

Tool results aren't limited to text. A tool can return:

  • Text — plain text or formatted content
  • Images — base64-encoded PNG, JPEG, etc.
  • Audio — base64-encoded audio data
  • Resource links — URIs pointing to resources the AI can read
  • Embedded resources — full resource content inline in the result

This means a screenshot tool can return an image. A code analysis tool can return resource links to the files it analyzed. A monitoring tool can return a chart as an image.

Error Handling

Two levels of errors:

Protocol errors — the tool doesn't exist, the arguments are malformed, the server can't process the request:

{
  "jsonrpc": "2.0",
  "id": 42,
  "error": {
    "code": -32602,
    "message": "Unknown tool: search_codee"
  }
}

Tool execution errors — the tool ran but failed (API rate limit, invalid input, business logic error):

{
  "jsonrpc": "2.0",
  "id": 42,
  "result": {
    "content": [
      { "type": "text", "text": "Search failed: directory 'src/' does not exist" }
    ],
    "isError": true
  }
}

The distinction matters. Protocol errors mean something is wrong with the setup. Tool execution errors mean the tool ran but the operation failed — the AI can read the error message and try a different approach.

Writing Good Tool Descriptions

The description is what the AI reads to decide when to use a tool. Bad descriptions cause bad tool selection.

Bad: "Search files" — Too vague. Search by name? Content? Size? Date?

Good: "Search for code patterns across the project using regex or literal string matching. Returns file paths, line numbers, and matching content. Use this when you need to find where a function, variable, or pattern is used in the codebase." — Specific about what it does, how it searches, what it returns, and when to use it.

Bad: "Run a query" — What kind of query? SQL? GraphQL? Text search?

Good: "Execute a read-only SQL query against the PostgreSQL database. Returns rows as JSON objects. Use for data exploration, schema inspection, or answering questions about the data. Does not support INSERT, UPDATE, or DELETE." — Specific about the database, the query language, what's returned, and the constraints.

Annotations

Tools support optional annotations that hint at their behavior:

  • readOnlyHint — the tool doesn't modify anything (safe to run without confirmation)
  • destructiveHint — the tool deletes or permanently modifies data (should require confirmation)
  • openWorldHint — the tool interacts with external services (may have side effects outside the local system)

These are hints, not guarantees. The host application uses them to decide when to prompt the user for confirmation. A tool marked destructiveHint: true should always show a confirmation dialog.

Security

Tools are the most sensitive part of MCP. They execute actions in the real world. The security model:

  1. Servers validate all inputs — never trust the AI's arguments blindly
  2. Hosts confirm sensitive operations — show the user what's about to happen
  3. Tools declare their nature — annotations help hosts make confirmation decisions
  4. Rate limiting — prevent runaway tool calls
  5. Audit logging — record every tool call for review

The human is always in the loop. MCP is designed so that the AI proposes actions and the human (or the host's policy) approves them.

Next Steps