Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Note
O suporte à ferramenta MCP de auto-hospedagem no .NET estará disponível em breve.
O Go expõe um agente como uma ferramenta MCP combinando tool/agenttool, tool/mcptoole o SDK oficial do MCP Go. Encapsular o agente com agenttool.New, registrá-lo com mcptool.AddTool e servi-lo em um transporte MCP.
O exemplo de Foundry mantido usa stdio. Ele requer um endpoint do projeto Foundry, uma implantação do modelo e uma credencial do Azure:
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to expose an Agent as an MCP tool.
package main
import (
"context"
"github.com/microsoft/agent-framework-go/agent"
"github.com/microsoft/agent-framework-go/examples/internal/demo"
"github.com/microsoft/agent-framework-go/provider/foundryprovider"
"github.com/microsoft/agent-framework-go/tool/agenttool"
"github.com/microsoft/agent-framework-go/tool/mcptool"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
// Run "npx @modelcontextprotocol/inspector go run ." to connect to this MCP server.
func main() {
token := demo.FoundryTokenCredential()
// Create Microsoft Foundry agent with the same configuration as the C# example.
agent := foundryprovider.NewAgent(
demo.FoundryProjectEndpoint,
token,
foundryprovider.ModelDeployment(demo.FoundryModel),
foundryprovider.AgentConfig{
Instructions: "You are good at telling jokes, and you always start each joke with 'Aye aye, captain!'.",
Config: agent.Config{
Name: "Joker",
Description: "An agent that tells jokes.",
},
},
)
// Create an MCP server with the agent exposed as a tool.
srv := mcp.NewServer(&mcp.Implementation{
Name: "agent-mcp-server",
Version: "1.0.0",
}, nil)
// Register the agent as an MCP tool.
mcptool.AddTool(srv, agenttool.New(agent, agenttool.Config{}))
// Run the MCP server with StdIO transport.
if err := srv.Run(context.Background(), &mcp.StdioTransport{}); err != nil {
demo.Panic(err)
}
}
Consulte a integração de ferramentas MCP para padrões de cliente e servidor e o exemplo completo do servidor MCP para obter instruções de execução.
Use agent-framework-hosting-mcp para expor um agente ou fluxo de trabalho do Agent Framework como ferramenta no SDK nativo do Model Context Protocol. O pacote não escolhe uma estrutura da Web nem encapsula o ciclo de vida do servidor do SDK do MCP. Seu aplicativo ainda possui o servidor MCP, o registro do manipulador, o transporte, a política de chave de sessão, a autenticação, a autorização e a implantação.
pip install --pre agent-framework-hosting-mcp
Converter no limite do protocolo
mcp_to_run(...) converte argumentos de ferramenta MCP validados em mensagens do Agent Framework e opções de chat selecionadas e mcp_from_run(...) converte uma resposta concluída em valores mcp ContentBlock nativos. Use essas duas funções diretamente quando o contrato de ferramenta de um aplicativo precisar de um esquema e manipulador nativo totalmente personalizados:
"properties": {
TASK_ARGUMENT: {
"type": "string",
"description": "The request for the hosted agent.",
},
**CHAT_OPTION_ARGUMENTS,
},
"required": [TASK_ARGUMENT],
"additionalProperties": False,
},
)
]
)
async def call_tool(
_ctx: ServerRequestContext[dict[str, Any]], params: types.CallToolRequestParams
) -> types.CallToolResult:
"""Convert, run, and render without the agent-backed adapter."""
name = params.name
arguments = params.arguments or {}
if name != "run_agent_manually":
raise MCPError(types.INVALID_PARAMS, f"Unknown MCP tool: {name}")
run = mcp_to_run(
arguments,
argument_name=TASK_ARGUMENT,
chat_option_arguments=CHAT_OPTION_ARGUMENTS,
)
result = await agent.run(run["messages"], options=run["options"])
return types.CallToolResult(content=mcp_from_run(result))
server = Server("agent-framework-hosting-mcp-manual-sample", on_list_tools=list_tools, on_call_tool=call_tool)
credential = DefaultAzureCredential()
Somente os nomes de argumento listados chat_option_arguments são copiados em run["options"]; outros argumentos MCP permanecem disponíveis na representação bruta da mensagem, mas não são encaminhados para o cliente modelo.
Hospedar com MCPServer
Para aplicativos MCP SDK 2.x, use MCPServer para derivar um esquema de ferramentas MCP nativo de uma função decorada. Retorne CallToolResult explicitamente depois de converter a resposta concluída do Agent Framework:
from contextlib import asynccontextmanager
from typing import Literal
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_hosting_mcp import mcp_from_run, mcp_to_run
from azure.identity.aio import DefaultAzureCredential
from mcp import types
from mcp.server.mcpserver import MCPServer
credential = DefaultAzureCredential()
agent = Agent(
client=FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=credential,
),
name="MCPHostedAgent",
description="Answer a request with the hosted Agent Framework agent.",
instructions="Answer the user's request clearly and concisely.",
)
@asynccontextmanager
async def lifespan(_server: MCPServer[None]) -> AsyncGenerator[None]:
"""Close the model credential when the MCP server stops."""
async with credential:
yield
server = MCPServer(
name="agent-framework-hosting-mcpserver-sample",
instructions="Expose an Agent Framework agent as an MCP tool.",
lifespan=lifespan,
)
@server.tool(
name="run_agent",
description="Run the hosted Agent Framework agent.",
structured_output=False,
)
async def run_agent(
task: str,
reasoning_effort: Literal["low", "medium", "high"] | None = None,
) -> types.CallToolResult:
"""Run the agent with MCPServer-validated arguments."""
O exemplo usa HTTP streamable sem estado. Adicione autenticação, autorização e persistência de sessão de propriedade do aplicativo antes de expor o servidor além de um ambiente local confiável.
Hospedar um agente como uma ferramenta gerada
AgentMCPTool deriva de um agente o nome, a descrição e o esquema da ferramenta nativa de um agente, e mantém a listagem, a análise, a execução e a conversão de resultados alinhados para que não haja descompasso entre os dois:
) -> types.CallToolResult:
"""Run the app-owned tool with native MCP and Agent Framework values."""
return await agent_tool.call_tool(params.name, params.arguments)
server = Server("agent-framework-hosting-mcp-sample", on_list_tools=list_tools, on_call_tool=call_tool)
credential = DefaultAzureCredential()
agent = Agent(
client=FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=credential,
),
name="MCPHostedAgent",
description="Answer a request with the hosted Agent Framework agent.",
instructions="Answer the user's request clearly and concisely.",
)
agent_tool = AgentMCPTool(
agent,
name="run_agent",
argument_description="The request for the hosted agent.",
chat_option_parameters={
"reasoning_effort": {
"type": "string",
AgentMCPTool usa o nome e a descrição do agente, a menos que seja substituído.
parameters adiciona propriedades de esquema JSON de propriedade do aplicativo que permanecem disponíveis nos argumentos MCP brutos e chat_option_parameters adiciona propriedades cujos valores são explicitamente copiados em opções de chat do Agent Framework.
Manter uma sessão por chamada
Passe um AgentState existente e um session_id_parameter para permitir que chamadas repetidas com o mesmo session_id opaco definido pelo aplicativo continuem a mesma conversa:
state = AgentState(agent)
agent_tool = AgentMCPTool(
state,
name="run_agent",
argument_description="The request for the hosted agent.",
parameters={
"session_id": {
"type": "string",
"minLength": 1,
"description": (
"Opaque, app-defined conversation key. Reuse the same value to continue and update one conversation."
),
}
},
required_parameters={"session_id"},
chat_option_parameters={
"reasoning_effort": {
"type": "string",
AgentMCPTool executa apenas a sequência AgentState get/run/set da sessão; seu aplicativo deve autenticar ou autorizar o identificador da sessão e serializar chamadas concorrentes para a mesma sessão, como o exemplo faz com um asyncio.Lock por sessão. Isso não é ramificação no estilo previous_response_id — uma aplicação que precisa ramificar uma conversa deve aceitar IDs de origem e destino distintos, copiar a sessão de origem e armazenar o resultado sob a chave de destino.
Hospedar um fluxo de trabalho como uma ferramenta
WorkflowMCPTool deriva uma ferramenta MCP nativa do tipo de entrada start-executor de um fluxo de trabalho e converte as saídas de um fluxo de trabalho concluído. As entradas dataclass, Pydantic e outras entradas em forma de objeto tornam-se argumentos MCP de nível superior; as entradas primitivas são encapsuladas em um nome de argumento configurável:
async def list_tools(
_ctx: ServerRequestContext[dict[str, Any]], params: types.PaginatedRequestParams | None
) -> types.ListToolsResult:
As instâncias de fluxo de trabalho preservam o estado de execução, portanto os aplicativos que precisam de chamadas independentes devem fornecer uma fábrica WorkflowState com cache_target=False, conforme mostrado acima. A restauração do ponto de verificação, as respostas humanas no loop e os identificadores de continuação permanecem de propriedade do aplicativo; se um fluxo de trabalho solicitar entrada externa, o adaptador será gerado em vez de retornar um resultado de ferramenta de êxito vazio.
Para obter o conjunto completo de servidores executáveis, incluindo a MCPServer variante, consulte os exemplos de hospedagem do MCP.
Important
Trate o identificador de sessão MCP e qualquer argumento definido pelo session_id aplicativo como entrada não confiável. Autentique e autorize o chamador antes de usar qualquer uma das duas operações para carregar ou salvar o estado da sessão e derive o particionamento durável do locatário, usuário ou workspace autenticado, em vez de usar o valor bruto.
Próximas Etapas
Vá mais fundo: