Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga / Notatka
Obsługa narzędzi MCP do samodzielnego hostowania w .NET jest wkrótce dostępna.
Go uwidacznia agenta jako narzędzie MCP, łącząc tool/agenttool, tool/mcptooli oficjalny zestaw SDK MCP Go. Opakuj agenta za pomocą agenttool.New, zarejestruj go za pomocą mcptool.AddTool i obsłuż go za pośrednictwem transportu MCP.
Utrzymywany przykład Foundry używa stdio. Wymaga punktu końcowego projektu Foundry, wdrożenia modelu i poświadczeń platformy 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)
}
}
Zobacz Integracja narzędzi MCP dla wzorców klienta i serwera oraz kompletny przykład serwera MCP , aby uzyskać instrukcje wykonywania.
Użyj agent-framework-hosting-mcp, aby udostępnić agenta lub przepływ pracy Agent Framework jako narzędzie w natywnym pakiecie SDK Model Context Protocol. Pakiet nie wybiera frameworku webowego ani nie opakowuje cyklu życia serwera MCP SDK. Aplikacja nadal jest właścicielem serwera MCP, rejestracji procedury obsługi, transportu, zasad klucza sesji, uwierzytelniania, autoryzacji i wdrożenia.
pip install --pre agent-framework-hosting-mcp
Konwertować na granicy protokołu
mcp_to_run(...) Konwertuje zweryfikowane argumenty narzędzia MCP na komunikaty platformy agentów i wybrane opcje czatu oraz mcp_from_run(...) konwertuje ukończoną odpowiedź na natywne wartości MCP ContentBlock . Użyj tych dwóch funkcji bezpośrednio, gdy kontrakt narzędzi aplikacji wymaga w pełni niestandardowego, natywnego schematu i procedury obsługi:
"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()
Tylko nazwy argumentów wymienionych w pliku chat_option_arguments są kopiowane do run["options"]; inne argumenty MCP pozostają dostępne na nieprzetworzonej reprezentacji wiadomości, ale nie są przekazywane do klienta modelu.
Host z MCPServer
W przypadku aplikacji MCP SDK 2.x użyj polecenia MCPServer, aby uzyskać natywny schemat narzędzia MCP z funkcji ozdobionej. Zwróć CallToolResult jawnie po przekonwertowaniu ukończonej odpowiedzi 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."""
Przykład używa bezstanowego strumieniowego HTTP. Dodaj uwierzytelnianie należące do aplikacji, autoryzację i trwałość sesji przed udostępnieniem serwera poza zaufanym środowiskiem lokalnym.
Hostuj agenta jako pojedyncze wygenerowane narzędzie
AgentMCPTool wyprowadza natywną nazwę narzędzia, opis i schemat na podstawie agenta oraz zapewnia spójność listowania, parsowania, wykonywania i konwersji wyników, dzięki czemu oba nie mogą się rozjechać:
) -> 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 używa nazwy i opisu agenta, chyba że zostanie zastąpiony.
parameters Dodaje właściwości schematu JSON należące do aplikacji, które pozostają dostępne w nieprzetworzonych argumentach MCP, i chat_option_parameters dodaje właściwości, których wartości są jawnie kopiowane do opcji czatu programu Agent Framework.
Zachować sesję dla każdego wywołania
Przekaż istniejące AgentState i session_id_parameter, aby umożliwić powtarzanym wywołaniom z tym samym nieprzezroczystym identyfikatorem session_id zdefiniowanym przez aplikację kontynuowanie tej samej konwersacji:
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 Wykonuje AgentState tylko sekwencję pobierania/uruchamiania/ustawiania sesji; aplikacja musi uwierzytelniać lub autoryzować identyfikator sesji i serializować współbieżne wywołania dla tej samej sesji, co w przykładzie w przypadku sesji asyncio.Lock. To nie jest rozgałęzianie w stylu previous_response_id — aplikacja, która musi rozgałęzić konwersację, powinna przyjmować oddzielne identyfikatory źródłowy i docelowy, skopiować sesję źródłową i zapisać wynik pod kluczem docelowym.
Hostowanie przepływu pracy jako narzędzia
WorkflowMCPTool wyprowadza jedno natywne narzędzie MCP z typu wejściowego start-executora przepływu pracy i konwertuje dane wyjściowe ukończonego przepływu pracy. Dane wejściowe klasy danych, Pydantic i innych danych wejściowych w kształcie obiektu stają się argumentami MCP najwyższego poziomu; Pierwotne dane wejściowe są opakowane w konfigurowalną nazwę argumentu:
async def list_tools(
_ctx: ServerRequestContext[dict[str, Any]], params: types.PaginatedRequestParams | None
) -> types.ListToolsResult:
Instancje przepływu pracy zachowują stan wykonania, więc aplikacje wymagające oddzielnych wywołań powinny udostępnić fabrykę WorkflowState z cache_target=False, jak pokazano powyżej. Przywracanie punktów kontrolnych, odpowiedzi z udziałem człowieka i identyfikatory kontynuacji pozostają po stronie aplikacji; jeśli przepływ pracy wymaga danych wejściowych z zewnątrz, adapter zgłasza wyjątek zamiast zwracać pusty, pomyślny wynik działania narzędzia.
Pełny zestaw serwerów możliwych do uruchomienia, w tym MCPServer wariant, można znaleźć w przykładach hostingu MCP.
Important
Traktuj identyfikator sesji MCP i dowolny argument zdefiniowany przez session_id aplikację jako niezaufane dane wejściowe. Uwierzytelnij i autoryzuj wywołującego przed użyciem któregokolwiek z tych mechanizmów do wczytania lub zapisania stanu sesji, a trwały podział określaj na podstawie uwierzytelnionego tenanta, użytkownika lub obszaru roboczego, a nie surowej wartości.
Następne kroki
Głębiej: