Aprenda a expor dados como Resources — permitindo que o modelo acesse informações sem executar ações.
Até agora trabalhamos com tools — funções que executam ações e retornam resultados. Agora vamos conhecer os resources: dados que o modelo pode ler, mas não modificar. Enquanto tools são "verbos" (fazer algo), resources são "substantivos" (acessar algo). Essa distinção é fundamental na arquitetura MCP.
No FastMCP, um resource é criado com o decorator @mcp.resource(), que recebe uma URI como identificador único:
@mcp.resource("config://app")
def get_config() -> str:
"""Retorna as configurações do app."""
return "versão: 1.0, modo: produção"
A diferença fundamental: tools executam ações (enviar email, calcular, consultar API), enquanto resources expõem dados (configurações, documentação, status). O modelo lê resources para obter contexto, mas não pode usá-los para modificar nada.
Pense em resources como arquivos em um sistema de arquivos virtual. Cada resource tem um endereço (URI) e um conteúdo. O modelo pode "abrir e ler" esses arquivos, mas não pode "escrever" neles. Use resources para tudo que o modelo precisa saber mas não precisa fazer: configurações, documentação, constantes, dados de referência.
Resources estáticos retornam dados fixos que não mudam entre chamadas — configurações do aplicativo, documentação, constantes, regras de negócio. São os mais simples de implementar e os mais comuns em servers MCP. O modelo pode acessá-los a qualquer momento para obter informações de referência.
@mcp.resource("config://app")
def get_app_config() -> str:
"""Configurações do aplicativo."""
return """
Aplicativo: Meu Server MCP
Versão: 1.0.0
Ambiente: produção
Max conexões: 100
Timeout padrão: 30s
"""
@mcp.resource("docs://ajuda")
def get_help() -> str:
"""Documentação de ajuda."""
return "Use as tools disponíveis para calcular e consultar clima."
Resources estáticos são ótimos para dar contexto ao modelo. Por exemplo, um resource com as regras de negócio da empresa permite que o modelo responda perguntas sobre políticas sem precisar de uma tool. Um resource com a documentação do sistema ajuda o modelo a guiar o usuário. Pense nos resources como o "manual de instruções" que o modelo pode consultar.
Diferente dos estáticos, resources dinâmicos retornam dados que mudam a cada acesso. A data e hora atual, o status do sistema, contadores, dados de monitoramento — tudo isso é dinâmico. A função do resource é chamada cada vez que o modelo acessa aquele URI, garantindo dados sempre atualizados.
from datetime import datetime
@mcp.resource("status://hora-atual")
def get_hora_atual() -> str:
"""Retorna a data e hora atual do servidor."""
agora = datetime.now()
return f"Data e hora: {agora.strftime('%d/%m/%Y %H:%M:%S')}"
@mcp.resource("status://sistema")
def get_status_sistema() -> str:
"""Retorna o status atual do sistema."""
import platform
return (
f"SO: {platform.system()}\n"
f"Python: {platform.python_version()}\n"
f"Hora: {datetime.now().strftime('%H:%M:%S')}"
)
O modelo decide que precisa de um dado (ex: hora atual) e solicita o resource pela URI.
O FastMCP recebe a requisição e executa a função associada àquela URI naquele momento.
A função retorna o dado atualizado (ex: "14:35:22") e o modelo usa na sua resposta ao usuário.
Resources dinâmicos são particularmente úteis em cenários de monitoramento e observabilidade. Um server MCP pode expor resources com métricas do sistema, status de serviços, logs recentes e dashboards de saúde — permitindo que o modelo responda perguntas como "Como está a saúde do sistema?" ou "Qual o uso de memória atual?" sem precisar de tools específicas.
Cada resource é identificado por uma URI (Uniform Resource Identifier) — um endereço único que segue o padrão tipo://caminho. O "tipo" (scheme) indica a categoria do dado e o "caminho" identifica o recurso específico. URIs bem organizadas facilitam a descoberta e o uso dos resources pelo modelo.
O formato da URI é scheme://path, onde o scheme indica o tipo de dado:
A URI identifica unicamente cada resource. Duas URIs diferentes sempre apontam para resources diferentes. Organize suas URIs de forma lógica e consistente.
data://x1 — sem significadoresource://get_stuff — verbo em resourceabc://123 — scheme sem semânticaconfig://ConfiguraçõesDoApp — acentos e maiúsculasconfig://app — claro e concisostatus://health — semântica claradocs://api/endpoints — hierárquicodb://users/schema — específico
O protocolo MCP permite que o client liste todos os resources disponíveis no server. Isso é feito automaticamente pelo FastMCP — todos os resources registrados com @mcp.resource() aparecem na listagem. Além disso, o MCP suporta resource templates — resources parametrizados onde parte da URI é variável.
Resource templates permitem criar resources parametrizados. O FastMCP detecta parâmetros na URI automaticamente:
@mcp.resource("users://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
"""Retorna o perfil de um usuário."""
return f"Perfil do usuário {user_id}"
O {user_id} na URI se torna um parâmetro. O modelo pode acessar users://alice/profile ou users://bob/profile — cada um retornando dados diferentes. O FastMCP registra isso como um resource template na listagem.
A listagem de resources funciona como um "catálogo" do server. O client MCP pode pedir a lista completa de resources antes de usar qualquer um deles. Isso permite que o modelo saiba exatamente quais dados estão disponíveis e como acessá-los. Mantenha suas URIs e descrições (docstrings) organizadas para facilitar a descoberta.
Cuidado com o que você expõe como resource. Todos os resources registrados ficam visíveis para o client MCP. Nunca exponha dados sensíveis como senhas, tokens de API, chaves privadas ou dados pessoais sem proteção adequada. Trate resources como endpoints públicos — se um dado não deve ser lido pelo modelo, não crie um resource para ele.
Vamos testar os resources que criamos no Claude Desktop. O modelo deve ser capaz de listar os resources disponíveis e ler o conteúdo de cada um. Diferente das tools (que o modelo chama ativamente), resources são dados que o modelo pode acessar quando precisa de contexto para responder uma pergunta.
Teste seus resources com perguntas que motivem o modelo a buscá-los:
config://app.
status://hora-atual e retornar o valor dinâmico.
status://sistema.
docs://ajuda.
Uma boa prática é criar um resource docs://ajuda em todo server MCP que explique quais tools e resources estão disponíveis. Quando o usuário pergunta "O que você pode fazer?", o modelo lê esse resource e apresenta as capacidades do server de forma organizada. É como criar um menu de ajuda integrado.
Pergunte sobre configurações. Verifique que o modelo retorna os dados fixos do resource config://app.
Pergunte a hora duas vezes com intervalo. Verifique que os valores mudam entre as consultas.
Faça perguntas que usem tanto tools quanto resources. Ex: "Consulte o clima e me diga a hora atual."
Próximo Módulo: 3.7 — Adicionando Prompts