---
title: "MCP em Python: Criando Servidores de IA com FastMCP"
url: "https://python.dev.br/blog/mcp-model-context-protocol-python/"
markdown_url: "https://python.dev.br/blog/mcp-model-context-protocol-python.MD"
description: "Aprenda a criar servidores MCP (Model Context Protocol) em Python com FastMCP. Tutorial prático com tools, resources, prompts e exemplos reais de integração."
date: "2026-04-28"
author: "Equipe python.dev.br"
---

# MCP em Python: Criando Servidores de IA com FastMCP

Aprenda a criar servidores MCP (Model Context Protocol) em Python com FastMCP. Tutorial prático com tools, resources, prompts e exemplos reais de integração.


Se você trabalha com **inteligência artificial** em Python, provavelmente já enfrentou o desafio de conectar LLMs a dados e ferramentas externas. Cada integração exigia código personalizado, cada API tinha seu próprio formato, e manter tudo funcionando era um pesadelo. O **MCP (Model Context Protocol)** resolve exatamente esse problema.

Criado pela Anthropic e adotado rapidamente pela comunidade, o MCP se tornou o **padrão aberto** para conectar modelos de linguagem a fontes de dados e funcionalidades externas. Pense nele como uma "USB-C para IA" — uma interface universal que qualquer aplicação pode implementar.

Neste artigo, vamos entender o protocolo, instalar o SDK oficial e criar um servidor MCP completo em Python usando o **FastMCP**.

## O que é o Model Context Protocol?

O MCP é um protocolo aberto que padroniza a comunicação entre aplicações de IA (clientes) e fontes de dados ou ferramentas (servidores). Em vez de cada assistente de IA implementar integrações proprietárias, o MCP define uma interface comum com três primitivas:

- **Tools** — funções que o LLM pode chamar para executar ações (similar a endpoints POST)
- **Resources** — dados que o LLM pode ler para obter contexto (similar a endpoints GET)
- **Prompts** — templates reutilizáveis para interações padronizadas

Essa arquitetura permite que um único servidor MCP funcione com qualquer cliente compatível — Claude Desktop, editores de código, agentes autônomos e qualquer outra aplicação que implemente o protocolo.

## Por que o MCP importa para desenvolvedores Python?

O ecossistema Python já domina o desenvolvimento de IA, e o MCP potencializa isso de várias formas:

1. **Reutilização** — um servidor MCP escrito uma vez funciona com qualquer cliente
2. **Segurança** — o servidor controla exatamente quais dados e ações são expostos
3. **Tipagem** — o SDK usa [type hints](/blog/tipagem-estatica-python-mypy/) nativamente
4. **Simplicidade** — o FastMCP transforma funções Python comuns em tools MCP automaticamente

Se você já trabalha com [APIs REST em FastAPI](/blog/apis-rest-com-fastapi/) ou construiu [agentes com LangGraph](/blog/langgraph-agentes-ia-python/), o MCP é a próxima peça do quebra-cabeça.

## Instalação do SDK

O SDK oficial do MCP para Python requer **Python 3.10+**. A forma recomendada de instalar é com o [uv](/blog/uv-gerenciador-pacotes-python/):

```bash
# Com uv (recomendado)
uv add "mcp[cli]"

# Com pip
pip install "mcp[cli]"
```

O pacote `mcp[cli]` inclui o SDK completo, o framework FastMCP e ferramentas de desenvolvimento como o MCP Inspector.

## Criando seu primeiro servidor MCP

O FastMCP simplifica a criação de servidores. Vamos começar com um servidor que expõe uma ferramenta de cálculo:

```python
from mcp.server.fastmcp import FastMCP

# Cria o servidor
mcp = FastMCP("Calculadora")


@mcp.tool()
def somar(a: float, b: float) -> float:
    """Soma dois números e retorna o resultado."""
    return a + b


@mcp.tool()
def calcular_porcentagem(valor: float, percentual: float) -> float:
    """Calcula a porcentagem de um valor.

    Args:
        valor: O valor base para o cálculo
        percentual: A porcentagem desejada (ex: 15 para 15%)
    """
    return valor * (percentual / 100)


if __name__ == "__main__":
    mcp.run()
```

O FastMCP usa as **type hints** e **docstrings** das suas funções para gerar automaticamente as definições de tools que o LLM vai entender. Você não precisa escrever schemas JSON manualmente.

## Adicionando Resources

Resources são dados que o LLM pode consultar para obter contexto. Vamos adicionar um recurso que retorna informações de configuração:

```python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Meu Servidor")

# Resource estático
@mcp.resource("config://app")
def get_config() -> str:
    """Retorna a configuração atual da aplicação."""
    return """
    {
        "versao": "2.1.0",
        "ambiente": "producao",
        "banco": "PostgreSQL 16",
        "cache": "Redis 7"
    }
    """

# Resource dinâmico com parâmetro
@mcp.resource("usuarios://{user_id}/perfil")
def get_perfil_usuario(user_id: str) -> str:
    """Retorna o perfil de um usuário pelo ID."""
    # Em produção, buscaria no banco de dados
    usuarios = {
        "1": "Ana Silva - Desenvolvedora Senior",
        "2": "Carlos Souza - Tech Lead",
        "3": "Maria Santos - DevOps Engineer",
    }
    return usuarios.get(user_id, "Usuário não encontrado")
```

A diferença entre tools e resources é importante: **tools executam ações** (podem ter efeitos colaterais), enquanto **resources fornecem dados** (são somente leitura).

## Prompts reutilizáveis

Prompts definem templates de interação que o cliente pode usar:

```python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Code Reviewer")


@mcp.prompt()
def revisar_codigo(codigo: str, linguagem: str = "python") -> str:
    """Prompt para revisão de código com boas práticas."""
    return f"""Revise o seguinte código {linguagem} considerando:
- Boas práticas e padrões da linguagem
- Possíveis bugs ou vulnerabilidades
- Legibilidade e manutenibilidade
- Performance

Código para revisão:
```{linguagem}
{codigo}
```

Forneça sugestões específicas com exemplos de como melhorar."""
```

## Exemplo prático: servidor de consulta a banco de dados

Vamos criar um servidor mais realista que permite ao LLM consultar um banco [SQLite](/blog/python-e-banco-de-dados-sqlite/):

```python
import sqlite3
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Database Explorer")
DB_PATH = "minha_aplicacao.db"


def get_conexao():
    """Cria conexão com o banco de dados."""
    return sqlite3.connect(DB_PATH)


@mcp.resource("schema://tabelas")
def listar_tabelas() -> str:
    """Lista todas as tabelas do banco de dados."""
    conn = get_conexao()
    cursor = conn.execute(
        "SELECT name FROM sqlite_master WHERE type='table'"
    )
    tabelas = [row[0] for row in cursor.fetchall()]
    conn.close()
    return "\n".join(tabelas)


@mcp.resource("schema://tabela/{nome}")
def schema_tabela(nome: str) -> str:
    """Retorna o schema de uma tabela específica."""
    conn = get_conexao()
    cursor = conn.execute(f"PRAGMA table_info({nome})")
    colunas = cursor.fetchall()
    conn.close()
    resultado = f"Tabela: {nome}\n\nColunas:\n"
    for col in colunas:
        resultado += f"  - {col[1]} ({col[2]})"
        if col[5]:
            resultado += " [PK]"
        resultado += "\n"
    return resultado


@mcp.tool()
def consultar(sql: str) -> str:
    """Executa uma consulta SELECT no banco de dados.

    Args:
        sql: Query SQL (apenas SELECT é permitido)
    """
    sql_limpo = sql.strip().upper()
    if not sql_limpo.startswith("SELECT"):
        return "Erro: apenas consultas SELECT são permitidas."

    conn = get_conexao()
    try:
        cursor = conn.execute(sql)
        colunas = [desc[0] for desc in cursor.description]
        linhas = cursor.fetchall()
        resultado = " | ".join(colunas) + "\n"
        resultado += "-" * len(resultado) + "\n"
        for linha in linhas:
            resultado += " | ".join(str(v) for v in linha) + "\n"
        return resultado
    except Exception as e:
        return f"Erro na consulta: {e}"
    finally:
        conn.close()
```

Esse servidor permite que qualquer assistente de IA explore a estrutura do banco e execute consultas de leitura, sem nunca ter acesso direto de escrita.

## Testando com o MCP Inspector

O SDK inclui o **MCP Inspector**, uma interface web para testar servidores sem precisar de um cliente real:

```bash
# Inicia o Inspector apontando para seu servidor
mcp dev meu_servidor.py
```

O Inspector abre no navegador e mostra todos os tools, resources e prompts disponíveis. Você pode chamar cada um interativamente e verificar as respostas.

## Transportes: stdio vs HTTP

O MCP suporta diferentes mecanismos de transporte:

- **stdio** — comunicação via entrada/saída padrão (ideal para integrações locais como Claude Desktop)
- **Streamable HTTP** — comunicação via HTTP com suporte a streaming (ideal para servidores remotos)

```python
# Servidor com transporte HTTP
if __name__ == "__main__":
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
```

Para a maioria dos casos de uso local, o stdio é suficiente e mais simples. Para deploys em produção, o Streamable HTTP oferece mais flexibilidade.

## Boas práticas para servidores MCP

Depois de construir vários servidores MCP, algumas práticas se destacam:

1. **Docstrings claras** — o LLM usa as docstrings para entender quando e como usar cada tool
2. **Validação de entrada** — sempre valide parâmetros antes de executar ações
3. **Princípio do menor privilégio** — exponha apenas o mínimo necessário
4. **Tratamento de erros** — retorne mensagens de erro úteis em vez de exceções
5. **Resources para contexto** — use resources para dados que o LLM precisa consultar frequentemente

Se você trabalha com [tratamento de erros](/blog/tratamento-de-erros-python/) e [Pydantic para validação](/blog/pydantic-validacao-dados-python/), essas práticas já são familiares.

## Próximos passos

O ecossistema MCP está crescendo rapidamente. Além de criar seus próprios servidores, você pode:

- Explorar servidores MCP prontos da comunidade no GitHub
- Integrar com [OpenAI Agents SDK](/blog/openai-agents-sdk-python-multi-agentes/) que suporta MCP nativamente
- Combinar múltiplos servidores MCP em um único agente
- Adicionar autenticação OAuth para servidores HTTP em produção

O MCP está se tornando a camada de integração padrão entre LLMs e o mundo real. Se você desenvolve em Python e trabalha com IA, dominar esse protocolo é um diferencial competitivo importante em 2026.

Se quiser explorar mais sobre como conectar Python com modelos de linguagem, confira também nosso artigo sobre <a href="https://golang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go para backends de alta performance</a> que complementam servidores MCP, ou veja como <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust pode otimizar extensões Python</a> para processamento intensivo.
