Amostragem e roots
Tradução automática
Esta página foi traduzida automaticamente a partir da documentação em inglês, e a página em inglês é a versão de referência. Se algo parecer errado, Traduções explica como avisar.
Um handler pode pedir mais duas coisas ao cliente conectado: uma completion do próprio modelo do cliente (amostragem, sampling), e as pastas de workspace do cliente (roots).
As duas continuam funcionando, em todas as versões do protocolo que o SDK fala. Mas leia o aviso antes de projetar algo em cima delas:
Descontinuado pela especificação 2026-07-28
Amostragem e roots estão descontinuados a partir de 2026-07-28 (SEP-2577). Eles continuam totalmente funcionais e permanecem na especificação por pelo menos doze meses antes de se tornarem elegíveis para remoção, mas novas implementações não devem se apoiar neles. As migrações sugeridas: integre diretamente com a API do seu provedor de LLM em vez de usar amostragem, e passe diretórios via parâmetros de ferramenta, URIs de recurso ou configuração do servidor em vez de roots. A lista de todo o SDK está em Funcionalidades descontinuadas.
Amostragem: pegue emprestado o modelo do cliente
Um resolvedor retorna Sample(...) e a ferramenta recebe a completion, pelo mesmo mecanismo de dependência que executa Elicit em Dependências:
from typing import Annotated
from mcp.server import MCPServer
from mcp.server.mcpserver import Resolve, Sample
from mcp.types import CreateMessageResult, SamplingMessage, TextContent
mcp = MCPServer("Bookshop")
def draft_blurb(title: str) -> Sample:
prompt = f"Write a one-sentence blurb for the book {title!r}."
return Sample(
[SamplingMessage(role="user", content=TextContent(type="text", text=prompt))],
max_tokens=60,
)
@mcp.tool()
async def blurb(title: str, draft: Annotated[CreateMessageResult, Resolve(draft_blurb)]) -> str:
"""Draft a blurb for a book."""
return draft.content.text if draft.content.type == "text" else "No blurb."
Sample(messages, max_tokens=...)espelha os parâmetros desampling/createMessage. O valor injetado é oCreateMessageResultdo cliente; passetoolsoutool_choicee ele vira umCreateMessageResultWithTools.- O cliente precisa ter declarado a capacidade
sampling(sampling.toolsse você passartoolsoutool_choice). Se não declarou, a chamada falha com um erro de protocolo-32021em vez de enviar uma requisição que o cliente não consegue tratar. Uma sessão pré-2026 sem canal de retorno (back-channel) falha com o erro habitual de ausência de canal de retorno, já que não há por onde enviar. - Em
2026-07-28a requisição é entregue dentro do fluxo de múltiplas idas e voltas (Requisições com múltiplas idas e voltas); em2025-11-25ela é uma requisição independente para o cliente. O código é o mesmo nos dois casos, mas atenção à regra das múltiplas idas e voltas: a requisição precisa ser gerada de forma idêntica em todas as rodadas de retry, então construa-a apenas a partir dos argumentos da ferramenta e de outros dados estáveis. - Deixe
include_contextquieto: valores diferentes de"none"também estão descontinuados (SEP-2596) e exigem uma capacidade que quase nenhum cliente declara.
Roots: onde isso deve ir?
Roots são as pastas sobre as quais o cliente diz que o servidor pode operar. São uma orientação informativa, não um mecanismo de controle de acesso. Um resolvedor retorna ListRoots():
from typing import Annotated
from mcp.server import MCPServer
from mcp.server.mcpserver import ListRoots, Resolve
from mcp.types import ListRootsResult
mcp = MCPServer("Bookshop")
def workspace_roots() -> ListRoots:
return ListRoots()
@mcp.tool()
async def catalog_folder(roots: Annotated[ListRootsResult, Resolve(workspace_roots)]) -> str:
"""Pick the folder the catalog export should go to."""
if not roots.roots:
return "No workspace folders shared."
return str(roots.roots[0].uri)
- O
ListRootsResultinjetado traz uma lista deRoots: uma URIfile://e um nome de exibição opcional. - A barreira é a mesma da amostragem: sem uma capacidade
rootsdeclarada, a chamada falha com-32021em vez de enviar a requisição.
Do outro lado da conexão, o cliente responde às duas requisições com os callbacks que já tem: sampling_callback e list_roots_callback, tratados em Callbacks do cliente.
Em conexões da era 2025
ctx.session.create_message(...) e ctx.session.list_roots() ainda existem para código que controla a sessão diretamente. Eles só funcionam onde existe um canal de retorno (conexões da era 2025, não stateless), e chamá-los dispara um aviso de descontinuação. Os marcadores de resolvedor acima são a forma suportada: eles escolhem a entrega conforme a versão negociada e não emitem aviso.
Recapitulando
- Retorne
Sample(...)ouListRoots()de um resolvedor; a ferramenta recebe oCreateMessageResultou oListRootsResultcomo qualquer outra dependência. - O cliente precisa declarar a capacidade correspondente, ou a chamada falha com
-32021em vez de uma requisição ser enviada. - As duas funcionalidades estão descontinuadas em
2026-07-28: totalmente funcionais por enquanto, erradas para novos projetos. Prefira APIs de provedor à amostragem e parâmetros explícitos aos roots.
Para informar o andamento de uma ferramenta lenta: Progresso.