Habilidade de Desenvolvimento MCP em Python
Construa servidores e clientes MCP em Python usando o SDK mcp (que inclui FastMCP).
Orientação rápida
- Pacote:
mcpno PyPI (inclui FastMCP). Instalação:pip install "mcp[cli]" - Para integração com LangChain/LangGraph:
pip install langchain-mcp-adapters - Versões do spec:
2024-11-05,2025-03-26,2025-06-18,2025-11-25 - Imports:
from mcp.server.fastmcp import FastMCP, Context, Image
Antes de começar a codificar
Leia o(s) arquivo(s) de referência apropriado(s) do diretório references/ desta habilidade com base no que o usuário precisa:
| O usuário quer... | Leia este arquivo |
|---|---|
| Criar um servidor MCP (ferramentas, recursos, prompts) | references/server.md |
| Criar um cliente MCP ou agente multi-servidor | references/client.md |
| Usar Context (logging, progresso, amostragem, elicitação) | references/context.md |
| Entender transportes, autenticação, segurança, ciclo de vida | references/protocol.md |
Sempre leia o arquivo de referência relevante antes de escrever código. As referências contêm caminhos de importação exatos, assinaturas de API, mapeamentos de tipo de retorno e pegadinhas que são essenciais para um código correto.
Arquitetura em resumo
Host (Claude Desktop / IDE / agente customizado)
├── Cliente MCP 1 ──► Servidor MCP A (local, STDIO)
├── Cliente MCP 2 ──► Servidor MCP B (remoto, HTTP Streamable)
└── Cliente MCP 3 ──► Servidor MCP C (remoto, OAuth 2.1)
- Host: Aplicação de IA que cria clientes
- Cliente: Conexão 1:1 com um único servidor
- Servidor: Expõe ferramentas, recursos, prompts
Três primitivas: Ferramentas (funções controladas pelo modelo), Recursos (dados somente leitura controlados pela aplicação), Prompts (modelos de mensagem controlados pelo usuário).
Dois transportes: STDIO (subprocesso local, cliente único) e HTTP Streamable (rede, multi-cliente, endpoint padrão /mcp).
Modelo mínimo de servidor (início copiável)
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("MeuServidor")
@mcp.tool()
def minha_ferramenta(param: str) -> str:
"""Descreve o que esta ferramenta faz."""
return f"Resultado: {param}"
@mcp.resource("data://config")
def obter_config() -> str:
"""Configuração do servidor."""
return '{"key": "value"}'
if __name__ == "__main__":
mcp.run() # STDIO por padrão; use mcp.run(transport="streamable-http") para HTTP
Modelo mínimo de cliente
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import asyncio
async def main():
params = StdioServerParameters(command="python", args=["server.py"])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
resultado = await session.call_tool("minha_ferramenta", {"param": "olá"})
print(resultado.content[0].text)
asyncio.run(main())
Regras principais e pegadinhas
- Docstrings são obrigatórias em funções
@mcp.tool()— elas se tornam a descrição da ferramenta enviada ao LLM. Sem docstring, o LLM não sabe o que a ferramenta faz. - Dicas de tipo são obrigatórias — FastMCP gera o JSON Schema a partir delas. Use
Annotated[str, Field(description="...")]para documentação rica de parâmetros. - Context é injetado por dica de tipo — adicione
ctx: Contextcomo parâmetro; ele é automaticamente excluído do esquema de entrada da ferramenta. - Tipos de retorno importam:
str→ TextContent,dict→ JSON TextContent,bytes→ BlobResourceContents,Image→ ImageContent,list→ múltiplos blocos de conteúdo. - Erros: levante exceções nas ferramentas → são retornadas ao LLM com
isError=True. Não retorne strings de erro como saída normal. - Servidores STDIO nunca devem imprimir para stdout — toda saída não-MCP vai para stderr. Use
loggingcom manipulador stderr ouctx.info(). - Async é preferível para ferramentas que fazem E/S. Handlers síncronos e assíncronos são suportados.
- Anotações de ferramenta são dicas, não imposição:
readOnlyHint,destructiveHint,idempotentHint,openWorldHint. - MultiServerMCPClient (v0.1.0+) NÃO é um gerenciador de contexto assíncrono. Instancie diretamente:
client = MultiServerMCPClient({...}). - InMemorySaver é apenas para desenvolvimento — use PostgresSaver ou SqliteSaver em produção.
Fluxo de trabalho de desenvolvimento
mcp dev server.py # Iniciar com MCP Inspector (UI de depuração)
mcp dev server.py --with pandas # Com dependências extras
mcp install server.py # Registrar no Claude Desktop
mcp install server.py -e API_KEY=x # Com variáveis de ambiente
mcp run server.py # Executar diretamente
Quando usar cada transporte
| Cenário | Transporte | Por quê |
|---|---|---|
| Ferramenta CLI local / integração desktop | STDIO | Zero rede, latência de microssegundos |
| API de produção, multi-cliente | HTTP Streamable | Escalável, balanceado por carga |
| Serverless (Lambda, Cloud Run) | HTTP Streamable + stateless_http=True | Sem estado por requisição |
| Incorporação em FastAPI/Starlette existente | HTTP Streamable (montagem) | Compartilha app ASGI |