mcp_best_practices

Follow these standardized naming patterns:

MCP Server Best Practices

Quick Reference

Server Naming

Tool Naming

Response Formats

Pagination

Transport


Server Naming Conventions

Follow these standardized naming patterns:

Python: Use format {service}_mcp (lowercase with underscores)

Node/TypeScript: Use format {service}-mcp-server (lowercase with hyphens)

The name should be general, descriptive of the service being integrated, easy to infer from the task description, and without version numbers.


Tool Naming and Design

Tool Naming

  1. Use snake_case: search_users, create_project, get_channel_info
  2. Include service prefix: Anticipate that your MCP server may be used alongside other MCP servers
  1. Be action-oriented: Start with verbs (get, list, search, create, etc.)
  2. Be specific: Avoid generic names that could conflict with other servers

Tool Design


Response Formats

All tools that return data should support multiple formats:

JSON Format (response_format="json")

Markdown Format (response_format="markdown", typically default)


Pagination

For tools that list resources:

Example pagination response:

{
  "total": 150,
  "count": 20,
  "offset": 0,
  "items": [...],
  "has_more": true,
  "next_offset": 20
}

Transport Options

Streamable HTTP

Best for: Remote servers, web services, multi-client scenarios

Characteristics:

Use when:

stdio

Best for: Local integrations, command-line tools

Characteristics:

Use when:

Note: stdio servers should NOT log to stdout (use stderr for logging)

Transport Selection

| Criterion | stdio | Streamable HTTP | |-----------|-------|-----------------| | Deployment | Local | Remote | | Clients | Single | Multiple | | Complexity | Low | Medium | | Real-time | No | Yes |


Security Best Practices

Authentication and Authorization

OAuth 2.1:

API Keys:

Input Validation

Error Handling

DNS Rebinding Protection

For streamable HTTP servers running locally:


Tool Annotations

Provide annotations to help clients understand tool behavior:

| Annotation | Type | Default | Description | |-----------|------|---------|-------------| | readOnlyHint | boolean | false | Tool does not modify its environment | | destructiveHint | boolean | true | Tool may perform destructive updates | | idempotentHint | boolean | false | Repeated calls with same args have no additional effect | | openWorldHint | boolean | true | Tool interacts with external entities |

Important: Annotations are hints, not security guarantees. Clients should not make security-critical decisions based solely on annotations.


Error Handling

Example error handling:

try {
  const result = performOperation();
  return { content: [{ type: "text", text: result }] };
} catch (error) {
  return {
    isError: true,
    content: [{
      type: "text",
      text: `Error: ${error.message}. Try using filter='active_only' to reduce results.`
    }]
  };
}

Testing Requirements

Comprehensive testing should cover:


Documentation Requirements