Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Note
Podpora samoobslužného nástroje MCP v .NET bude brzy k dispozici.
Note
Podpora samoobslužného nástroje MCP není aktuálně dostupná pro Go.
Pomocí agent-framework-hosting-mcp můžete zpřístupnit agenta nebo pracovní postup platformy Agent Framework jako nástroj v nativní sadě SDK Model Context Protocol. Balíček nevolí webový framework ani nezajišťuje životní cyklus serveru MCP SDK; vaše aplikace nadále spravuje Server, registraci obslužných rutin, transport, zásady pro klíče relací, ověřování, autorizaci a nasazení.
pip install --pre agent-framework-hosting-mcp
Převést na rozhraní protokolu
mcp_to_run(...) převede ověřené argumenty nástroje MCP na zprávy agenta Framework a vybrané možnosti chatu a mcp_from_run(...) převede dokončenou odpověď na nativní hodnoty MCP ContentBlock . Tyto dvě funkce použijte přímo, když kontrakt nástrojů aplikace potřebuje plně vlastní nativní schéma a obslužnou rutinu:
@server.list_tools()
async def list_tools() -> list[types.Tool]:
"""Return the app-owned native MCP tool definition."""
return [
types.Tool(
name="run_agent_manually",
description=agent.description or "",
inputSchema={
"type": "object",
"properties": {
TASK_ARGUMENT: {
"type": "string",
"description": "The request for the hosted agent.",
},
**CHAT_OPTION_ARGUMENTS,
},
"required": [TASK_ARGUMENT],
"additionalProperties": False,
},
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict[str, object] | None) -> list[types.ContentBlock]:
"""Convert, run, and render without the agent-backed adapter."""
if name != "run_agent_manually":
raise ValueError(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 mcp_from_run(result)
Do chat_option_arguments se kopírují pouze názvy argumentů uvedené v run["options"]; ostatní argumenty MCP zůstávají dostupné v nezpracované reprezentaci zprávy, ale klientovi modelu se nepřeposílají.
Hostování agenta jako jednoho vygenerovaného nástroje
AgentMCPTool přebírá od agenta nativní název nástroje, popis a schéma a udržuje jejich výpis, parsování, spouštění a převod výsledků ve vzájemném souladu, takže se tyto dvě části nemohou rozejít:
agent_tool = AgentMCPTool(
agent,
name="run_agent",
argument_description="The request for the hosted agent.",
chat_option_parameters={
"reasoning_effort": {
"type": "string",
"enum": ["low", "medium", "high"],
"description": "Optional reasoning effort for models that support it.",
}
},
)
@server.list_tools()
async def list_tools() -> list[types.Tool]:
"""Describe the app-owned MCP tool schema."""
return await agent_tool.list_tools()
@server.call_tool()
async def call_tool(name: str, arguments: dict[str, object] | None) -> list[types.ContentBlock]:
"""Run the app-owned tool with native MCP and Agent Framework values."""
return await agent_tool.call_tool(name, arguments)
AgentMCPTool použije název a popis agenta, pokud není zadáno jinak.
parameters přidá vlastnosti schématu JSON vlastněné aplikací, které zůstanou dostupné v nezpracovaných argumentech MCP, a chat_option_parameters přidá vlastnosti, jejichž hodnoty se explicitně zkopírují do možností chatu v rozhraní Agent Framework.
Zachovat relaci pro každé volání
Předejte existující AgentState a session_id_parameter, aby opakovaná volání se stejným neprůhledným identifikátorem session_id, definovaným aplikací, mohla pokračovat v jedné konverzaci:
session_locks: dict[str, asyncio.Lock] = {}
@server.list_tools()
async def list_tools() -> list[types.Tool]:
"""Return the agent-derived MCP tool definition."""
return await agent_tool.list_tools()
@server.call_tool()
async def call_tool(name: str, arguments: dict[str, object] | None) -> list[types.ContentBlock]:
"""Serialize calls per app-owned session before using ``AgentState``."""
session_id = arguments.get("session_id") if arguments else None
if not isinstance(session_id, str) or not session_id:
raise ValueError("MCP tool argument 'session_id' must be a non-empty string.")
lock = session_locks.setdefault(session_id, asyncio.Lock())
async with lock:
return await agent_tool.call_tool(name, arguments)
AgentMCPTool provádí pouze sekvenci get/run/set pro relaci; vaše aplikace musí ověřit nebo autorizovat identifikátor relace a serializovat souběžná volání pro stejnou relaci, jak to ukázka dělá pomocí AgentState pro každou relaci. Nejedná se o větvení ve stylu previous_response_id – aplikace, která potřebuje rozdělit konverzaci do větví, by měla přijímat samostatná zdrojová a cílová ID, zkopírovat zdrojovou relaci a uložit výsledek pod cílovým klíčem.
Hostovat workflow jako nástroj
WorkflowMCPTool vytváří jeden nativní nástroj MCP ze vstupního typu spouštěcího vykonavatele pracovního postupu a převádí výstupy dokončeného pracovního postupu. Dataclass, Pydantic a další vstupy tvarované objekty se stanou argumenty MCP nejvyšší úrovně; primitivní vstupy jsou zabalené do konfigurovatelného názvu argumentu:
server = Server("agent-framework-hosting-mcp-workflow-sample")
workflow_tool = WorkflowMCPTool(
WorkflowState(create_workflow, cache_target=False),
name="draft_content",
)
Instance workflow zachovávají stav provádění, takže aplikace, které vyžadují nezávislá volání, by měly poskytnout továrnu WorkflowState s cache_target=False, jak je znázorněno výše. Obnovení kontrolního bodu, odpovědi v režimu human-in-the-loop a identifikátory pokračování zůstávají na straně aplikace; pokud pracovní postup vyžaduje externí vstup, adaptér místo vrácení prázdného úspěšného výsledku nástroje vyvolá výjimku.
Kompletní sadu spustitelných serverů včetně varianty FastMCP, která odvozuje její schéma z zdobené funkce, najdete v ukázkách hostování MCP.
Important
Považovat identifikátor relace MCP a libovolný argument definovaný session_id aplikací za nedůvěryhodný vstup. Před použitím kteréhokoli z nich k načtení nebo uložení stavu relace ověřte a autorizujte volajícího a trvalé rozdělení odvoďte od ověřeného tenanta, uživatele nebo pracovního prostoru, nikoli od nezpracované hodnoty.
Další kroky
Jděte hlouběji: