Önkiszolgáló ügynökök MCP-eszközökként

Note

Hamarosan megjelenik .NET önkiszolgáló MCP-eszköztámogatása.

Note

Az önkiszolgáló MCP eszköztámogatás jelenleg nem érhető el a Go-hoz.

Az agent-framework-hosting-mcp használatával az Agent Framework egyik ügynökét vagy munkafolyamatát eszközként teheti elérhetővé a natív Model Context Protocol SDK-ban. A csomag nem választ webes keretrendszert, és nem csomagolja be az MCP SDK-kiszolgáló életciklusát; az alkalmazás továbbra is a kezelőregisztráció, az átvitel, a munkamenetkulcs-szabályzat, a hitelesítés, az engedélyezés és az Serverüzembe helyezés tulajdonosa.

pip install --pre agent-framework-hosting-mcp

Konvertáljon a protokollhatáron

mcp_to_run(...) Az érvényesített MCP-eszközargumentumokat Agent Framework-üzenetekké és a kiválasztott csevegési lehetőségekké alakítja át, és mcp_from_run(...) a befejezett választ natív MCP-értékekké ContentBlock alakítja. Használja közvetlenül ezt a két függvényt, ha egy alkalmazás eszközszerződéséhez teljesen egyéni natív sémára és kezelőre van szükség:

@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)

A program csak a chat_option_arguments felsorolt argumentumneveket másolja a programba run["options"]; a többi MCP-argumentum elérhető marad az üzenet nyers ábrázolásán, de nem továbbítja őket a modellügyfélnek.

Ügynök üzemeltetése egy létrehozott eszközként

AgentMCPTool a natív eszköznevet, leírást és sémát egy ügynöktől származtatja, és a listázást, elemzést, végrehajtást és eredménykonvertálást igazítja egymáshoz, így a kettő nem tud elsodródni:

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 az ügynök nevét és leírását használja, hacsak ez nincs felülbírálva. parameters Olyan alkalmazás tulajdonában lévő JSON-sématulajdonságokat ad hozzá, amelyek elérhetők maradnak a nyers MCP-argumentumokban, és chat_option_parameters olyan tulajdonságokat ad hozzá, amelyek értékeit explicit módon másolják az Agent Framework csevegési beállításaiba.

Munkamenet fenntartása hívásonként

Adjon át egy meglévő AgentState-t és egy session_id_parameter-et, hogy az azonos átlátszatlan, alkalmazás által definiált session_id értékkel végzett ismételt hívások egyetlen beszélgetést folytathassanak:

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 csak a AgentState munkamenet get/run/set műveletsorozatát hajtja végre; az alkalmazásnak hitelesítenie kell vagy ellenőriznie kell a munkamenet-azonosító jogosultságát, és sorosítania kell az ugyanahhoz a munkamenethez tartozó egyidejű hívásokat, ahogyan a minta is teszi egy munkamenetenkénti asyncio.Lock használatával. Ez nem previous_response_id-stílusú elágaztatás – a beszélgetés elágaztatásához szükséges alkalmazásnak külön forrás- és célazonosítókat kell elfogadnia, ki kell másolnia a forrás munkamenetet, és az eredményt a célkulcs alatt kell tárolnia.

Munkafolyamat üzemeltetése eszközként

WorkflowMCPTool egy natív MCP-eszközt származtat a munkafolyamat kezdő-végrehajtó bemeneti típusából, és konvertálja a befejezett munkafolyamat-kimeneteket. Az adatosztály, a pydantic és más objektumalakzatú bemenetek felső szintű MCP-argumentumokká válnak; a primitív bemenetek egy konfigurálható argumentumnévbe vannak csomagolva:

server = Server("agent-framework-hosting-mcp-workflow-sample")
workflow_tool = WorkflowMCPTool(
    WorkflowState(create_workflow, cache_target=False),
    name="draft_content",
)

A munkafolyamat-példányok megőrzik a végrehajtási állapotot, ezért a független hívásokat igénylő alkalmazásoknak egy WorkflowState gyárat kell ellátniuk cache_target=Falsea fent látható módon. Az ellenőrzőpont-helyreállítás, az emberi beavatkozást igénylő válaszok és a folytatási azonosítók továbbra is az alkalmazás tulajdonában maradnak; ha egy munkafolyamat külső bemenetet kér, az adapter kivételt dob ahelyett, hogy üres, sikeres eszközeredményt adna vissza.

A futtatható kiszolgálók teljes készletét – beleértve a sémáját egy kitüntetett függvényből származtatott FastMCP-változatot is – az MCP üzemeltetési mintáiban találhatja meg.

Important

Az MCP-munkamenet azonosítóját és az alkalmazás által definiált session_id argumentumokat ne megbízható bemenetként kezelje. A munkamenet állapotának betöltésére vagy mentésére szolgáló bármelyik használata előtt hitelesítse a hívót, és ellenőrizze a jogosultságát, továbbá a tartós particionálást a hitelesített bérlő, felhasználó vagy munkaterület alapján képezze, ne a közvetlen értékből.

Következő lépések

Mélyedjen el: