Guidelines for naming MCP tools, describing parameters, and documenting tools in a language- and framework-agnostic manner
97
Pending
Does it follow best practices?
Impact
97%
1.02xAverage score across 5 eval scenarios
Pending
The risk profile of this skill
Comprehensive guidelines for naming MCP (Model Context Protocol) tools, describing parameters, and documenting tools in a language- and framework-agnostic manner.
MCP tools are the building blocks that extend AI assistant capabilities. Consistent naming, clear parameter descriptions, and comprehensive documentation enable agents to understand and use tools effectively across different implementations.
This tile provides language- and framework-agnostic guidelines for:
Tool names should be predictable, discoverable, and consistent across implementations.
| Principle | Description | Example |
|---|---|---|
| Predictable | Names should follow consistent patterns that agents can infer | search_web, read_file, execute_query |
| Discoverable | Similar tools should be grouped by prefixes or naming patterns | github_search_repos, github_get_issue |
| Consistent | Use the same naming style across all tools in a server | All lowercase with underscores (snake_case) or hyphens (kebab-case) |
| Action-oriented | Start with a verb describing what the tool does | create, read, update, delete, search, validate |
| Domain-prefixed | Prefix with domain when tools belong to specific domains | fs_read, http_fetch, db_query |
Choose one case style and use it consistently across all tools:
| Style | Format | Example | When to Use |
|---|---|---|---|
| snake_case | Lowercase with underscores | search_github_repositories | Most common, highly readable |
| kebab-case | Lowercase with hyphens | search-github-repositories | Common in CLI tools and URLs |
| camelCase | Lowercase first letter, capitals for subsequent words | searchGithubRepositories | JavaScript/TypeScript conventions |
| PascalCase | Capital first letter, capitals for subsequent words | SearchGithubRepositories | Typically used for types/classes, not tools |
Recommendation: Use snake_case for maximum cross-language compatibility.
Prefix tools to group related functionality and avoid name collisions:
| Strategy | Example | Use Case |
|---|---|---|
| Domain prefix | github_, sql_, file_ | Tools from a specific domain or service |
| Operation prefix | create_, read_, update_, delete_ | CRUD operations on resources |
| Source prefix | mcp_, system_, custom_ | Distinguish between built-in and custom tools |
| Good Names | Bad Names | Why |
|---|---|---|
search_web | webSearch (inconsistent case) | Consistent snake_case, action-oriented |
github_get_repo | getGithubRepo (mixes styles) | Domain-prefixed, predictable |
file_read | readFile (no domain prefix) | Clear domain grouping |
db_execute_query | executeQuery (ambiguous domain) | Explicit domain prefix |
Clear parameter descriptions are essential for agents to understand how to use tools correctly.
Each parameter should include:
| Field | Purpose | Example |
|---|---|---|
| Name | Identifier used in tool calls | query, file_path, limit |
| Type | Data type of the parameter | string, integer, boolean, array, object |
| Description | Clear explanation of what the parameter does | "Search query string" |
| Required | Whether the parameter is mandatory | true or false |
| Constraints | Validation rules (optional) | min: 1, max: 100, pattern: "^[a-z]+$" |
| Examples | Example values (optional) | "example query", 42, true |
| Do | Don't | Why |
|---|---|---|
| Use clear, concise language | Use technical jargon without explanation | Agents need to understand the purpose |
| Specify units when relevant | Assume default units | timeout_ms vs timeout (milliseconds vs seconds) |
| Include constraints in description | Hide constraints in type only | "Maximum number of results (1-100)" |
| Provide examples for complex parameters | Leave examples out | "JSON object with 'id' and 'name' fields" |
Use simple, language-agnostic types that map to common programming language types:
| MCP Type | Description | Common Mappings |
|---|---|---|
string | Text data | str (Python), string (Go/TypeScript), NSString (Swift) |
integer | Whole numbers | int (Python), number (TypeScript), int64 (Go) |
number | Floating-point numbers | float (Python), number (TypeScript), float64 (Go) |
boolean | True/false values | bool (Python), boolean (TypeScript), bool (Go) |
array | Ordered list of values | list (Python), Array (TypeScript), []interface{} (Go) |
object | Key-value mapping | dict (Python), Object (TypeScript), map[string]interface{} (Go) |
{
"name": "search_web",
"description": "Search the web for information",
"parameters": [
{
"name": "query",
"type": "string",
"description": "Search query string",
"required": true,
"examples": ["latest Python release", "weather in London"]
},
{
"name": "limit",
"type": "integer",
"description": "Maximum number of results (1-20)",
"required": false,
"default": 10,
"constraints": {"min": 1, "max": 20}
},
{
"name": "use_safe_search",
"type": "boolean",
"description": "Enable safe search filtering",
"required": false,
"default": true
}
]
}Comprehensive tool documentation helps agents understand when and how to use each tool.
| Section | Purpose | Example |
|---|---|---|
| Name | Tool identifier | read_file |
| Description | High-level purpose | "Read contents of a file from the filesystem" |
| Parameters | Inputs the tool accepts | file_path (string), encoding (string, optional) |
| Returns | What the tool outputs | "File contents as string" |
| Errors | Possible error conditions | "File not found", "Permission denied" |
| Examples | Example tool calls | read_file("config.json") |
| When to Use | Guidance on appropriate usage | "Use when you need to read configuration or data files" |
| Good Description | Bad Description | Why |
|---|---|---|
| "Search for repositories on GitHub using the GitHub API" | "GitHub repo search" | Clearly states purpose and source |
| "Execute a SQL query against a database and return results" | "Run SQL" | Specifies input/output and context |
| "Convert temperature between Celsius and Fahrenheit" | "Temperature converter" | Explains functionality clearly |
| "Use active voice and complete sentences in tool descriptions" | "Tool for X" or "Does Y" | Active voice and complete sentences make descriptions clearer and more professional |
For production-quality tool documentation, follow these advanced guidelines:
| Guideline | Description | Example |
|---|---|---|
| One-liner first | Start with action + object description. No fluff. | "Create refund for charge" not "This tool allows you to create a refund for a charge" |
| Inputs tight | Name, type, required/optional, constraints. Call out enums and max sizes. | limit: integer, required: false, constraints: {min: 1, max: 100}, description: "Maximum results (1-100)" |
| Output contract | Describe JSON shape and stable keys. Note nullable fields. | `{id: string, amount: number, currency: string, status: "pending" |
| Side effects + scope | What changes in the system, required auth/tenant, idempotency key support. | "Creates a new user record. Requires admin authentication. Supports idempotency keys." |
| Failure modes | Common errors with short "when/why" notes for retry/fallback. | INVALID_PARAMETER: "When input validation fails - check parameter types and constraints" |
| Tiny example | One happy path, one edge case. Minimal to avoid prompt bloat. | Happy: {"query": "python", "limit": 10} Edge: {"query": "", "limit": 1} |
| Reuse hinting | Tags like read/write, billing, high-latency, deprecation/version notes. | tags: ["write", "billing", "high-latency"], deprecated: "Use v2 endpoint after 2025-01-01" |
| New hire mindset | Describe tools as if to a new team member. Make implicit context explicit. | Explain specialized query formats, niche terminology, resource relationships that experts assume. |
Key Principle: When writing tool descriptions and specs, think of how you would describe your tool to a new hire on your team. Consider the context that you might implicitly bring—specialized query formats, definitions of niche terminology, relationships between underlying resources—and make it explicit.
Document possible error conditions and their meanings:
| Error | Description | Possible Causes |
|---|---|---|
FILE_NOT_FOUND | The specified file does not exist | Invalid path, missing file |
PERMISSION_DENIED | Insufficient permissions to access the resource | File permissions, user rights |
INVALID_INPUT | Input parameters fail validation | Wrong type, missing required fields |
NETWORK_ERROR | Network request failed | Server unreachable, timeout |
RATE_LIMITED | Too many requests | API rate limits exceeded |
{
"name": "github_search_repositories",
"description": "Search for GitHub repositories by keyword, language, or other criteria. Returns matching repositories with metadata.",
"parameters": [
{
"name": "query",
"type": "string",
"description": "Search query (supports GitHub search syntax)",
"required": true,
"examples": ["language:python", "tensorflow stars:>1000"]
},
{
"name": "sort",
"type": "string",
"description": "Sort field: stars, forks, updated",
"required": false,
"default": "stars",
"enum": ["stars", "forks", "updated"]
},
{
"name": "per_page",
"type": "integer",
"description": "Results per page (1-100)",
"required": false,
"default": 30,
"constraints": {"min": 1, "max": 100}
}
],
"returns": {
"type": "array",
"description": "List of repository objects with id, name, description, stars, etc."
},
"errors": [
{"code": "INVALID_QUERY", "description": "Search query syntax is invalid"},
{"code": "RATE_LIMITED", "description": "GitHub API rate limit exceeded"},
{"code": "NETWORK_ERROR", "description": "Failed to connect to GitHub API"}
],
"examples": [
{
"description": "Search for Python machine learning repositories",
"parameters": {"query": "machine learning language:python", "sort": "stars"}
}
]
}| Practice | Description | Implementation |
|---|---|---|
| Avoid implementation details | Don't reference specific programming languages or frameworks | Use "string" not "NSString" or "std::string" |
| Use generic type names | Stick to basic types that map across languages | string, integer, array, object |
| Document behavior, not implementation | Describe what the tool does, not how it's implemented | "Searches the web" not "Makes HTTP GET request to Google" |
| Provide examples in multiple formats | Show tool calls in different syntaxes when possible | JSON-RPC, CLI, REST-like examples |
| Include cross-platform considerations | Note platform-specific behavior if relevant | "On Windows, paths use backslashes" |
file_path vs filename vs path){
"name": "weather_get_current",
"description": "Get current weather conditions for a location",
"parameters": [
{
"name": "location",
"type": "string",
"description": "City name, postal code, or coordinates (lat,lon)",
"required": true,
"examples": ["New York", "10001", "40.7128,-74.0060"]
},
{
"name": "units",
"type": "string",
"description": "Temperature units: metric (Celsius) or imperial (Fahrenheit)",
"required": false,
"default": "metric",
"enum": ["metric", "imperial"]
}
],
"returns": {
"type": "object",
"description": "Weather data including temperature, conditions, humidity, wind"
}
}{
"name": "getWeather",
"description": "Gets weather",
"parameters": [
{
"name": "loc",
"type": "str",
"required": true
}
]
}Issues: Inconsistent naming (getWeather vs snake_case), vague description, ambiguous parameter name (loc), language-specific type (str), missing parameter description and examples.
Effective MCP tool documentation requires:
snake_case with domain prefixesFollowing these guidelines ensures that MCP tools are predictable, discoverable, and usable by AI agents across different platforms and implementations.