Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

agent-framework-hosting-mcp

MCP conversion helpers for app-owned Agent Framework hosting.

The package deliberately does not choose a web framework or wrap the MCP SDK server lifecycle. It provides two conversion functions and small adapters:

  • mcp_to_run(...) converts native MCP tool arguments into Agent Framework run arguments.
  • mcp_from_run(...) converts an AgentResponse or Message into native MCP ContentBlock values.
  • AgentMCPTool(...) generates the native Tool definition from an agent and keeps listing, parsing, execution, result conversion, and optional AgentState session persistence aligned.
  • WorkflowMCPTool(...) generates the native Tool definition from a workflow's start-executor input type and converts completed workflow outputs.

Application code keeps ownership of the MCP SDK's Server, handler registration, request context, transport, session-key policy, authentication, authorization, and deployment.

For direct conversion, the argument name is part of the app-owned MCP tool contract. Define it once and use the same value in both the native tool schema and mcp_to_run(...):

agent_input_argument = "task"
chat_option_arguments = {
    "reasoning_effort": {
        "type": "string",
        "enum": ["low", "medium", "high"],
    },
}

tool = Tool(
    name="run_agent",
    inputSchema={
        "type": "object",
        "properties": {
            agent_input_argument: {"type": "string"},
            **chat_option_arguments,
        },
        "required": [agent_input_argument],
    },
)
run = mcp_to_run(
    arguments,
    argument_name=agent_input_argument,
    chat_option_arguments=chat_option_arguments,
)

Only names listed in chat_option_arguments are copied to run["options"]; other MCP arguments remain available in the message's raw representation but are not forwarded to the model client. The native MCP schema remains responsible for validating exposed option types and ranges.

For an agent exposed as one MCP tool, use the adapter so the schema and conversion cannot drift:

agent_tool = AgentMCPTool(
    agent,
    name="run_agent",
    argument_description="The request for the hosted agent.",
    parameters={"audience": {"type": "string"}},
    chat_option_parameters={
        "reasoning_effort": {
            "type": "string",
            "enum": ["low", "medium", "high"],
        }
    },
)

@server.list_tools()
async def list_tools():
    return await agent_tool.list_tools()

@server.call_tool()
async def call_tool(name, arguments):
    return await agent_tool.call_tool(name, arguments)

AgentMCPTool uses the agent's name and description unless overridden. parameters adds app-owned JSON Schema properties that remain available in the raw MCP arguments. chat_option_parameters adds properties and explicitly copies their values into Agent Framework chat options.

For a workflow exposed as one MCP tool, use WorkflowMCPTool:

workflow_tool = WorkflowMCPTool(
    WorkflowState(create_workflow, cache_target=False),
    name="run_workflow",
)

The start executor must declare exactly one input type. Dataclass, Pydantic, and other object-shaped inputs become the MCP tool's top-level arguments. Primitive inputs are wrapped in the configurable argument_name property. The adapter validates MCP arguments against that derived type before calling workflow.run(...).

Workflow instances preserve execution state, so applications that need independent calls should supply a WorkflowState factory with cache_target=False, as above. Checkpoint restoration, human-in-the-loop responses, and continuation identifiers remain application-owned contracts. If a workflow requests external input, the adapter raises instead of returning an empty successful tool result.

Pass an existing AgentState plus session_id_parameter to persist an AgentSession:

state = AgentState(agent)
agent_tool = AgentMCPTool(
    state,
    parameters={"session_id": {"type": "string", "minLength": 1}},
    required_parameters={"session_id"},
    session_id_parameter="session_id",
)

The application must authenticate or authorize that session identifier and serialize concurrent calls for the same session. The adapter only performs the AgentState session-store get/run/set sequence. A configured session parameter is always marked required in the generated MCP schema.

The session identifier is an opaque, application-defined key. Neither MCP nor Agent Framework prescribes its format. AgentMCPTool treats it as the key for one mutable conversation: each call loads that session and stores the updated session under the same key. It does not implement previous_response_id-style branching. Branching requires an app-owned contract with separate source and destination identifiers so the application can authorize both, copy the source session, and store the result under the destination key.

MCP tools/call inputs are JSON objects defined by the app's inputSchema; the protocol does not define image, audio, or resource content blocks for tool arguments. This helper therefore converts one selected string argument and does not impose a non-standard multimodal JSON convention.

For non-image/audio binary output, mcp_from_run(...) uses an app-provided content.additional_properties["uri"] when present and otherwise uses the short fallback af://binary; the payload itself is stored only in the MCP resource's blob field.

mcp_from_run(...) targets CallToolResult.content, whose MCP content union does not include sampling-only ToolUseContent. Agent Framework function_call content is therefore omitted from tool results. MCP sampling callbacks use a separate response contract and may convert function calls to ToolUseContent.

MCP tool calls return one final CallToolResult; they do not stream partial content blocks. Streamable HTTP may carry multiple MCP messages, and apps may send progress notifications while work runs, but neither mechanism turns Agent Framework response updates into incremental tool results. Experimental MCP tasks defer retrieval of the same final result.

run = mcp_to_run(arguments)
result = await agent.run(
    run["messages"],
    options=run["options"],
)
content = mcp_from_run(result)

# Native MCP SDK application code returns `content` from its call_tool handler.

The surrounding MCP application still owns the low-level Server, handler registration, Starlette/FastAPI composition, stdio or streamable HTTP transport, request authentication, session-key trust, concurrency, and deployment.

Metadata

Release files for agent-framework-hosting-mcp 1.0.0a261022

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-framework-hosting-mcp 1.0.0a261022
File Size Uploaded Provenance
agent_framework_hosting_mcp-1.0.0a261022.tar.gz 11.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-framework-hosting-mcp 1.0.0a261022
File Interpreter ABI Platform
agent_framework_hosting_mcp-1.0.0a261022-py3-none-any.whl Python 3 none any Details

Total release size: 24.5 kB

Release files / agent_framework_hosting_mcp-1.0.0a261022.tar.gz

Download URL agent_framework_hosting_mcp-1.0.0a261022.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2e018c3f46abd3f9a34a93201fe312501e7e0bb90c7c3663c30dd788ac0f7d6d
BLAKE2b-256 checksum
How to use checksums
4765a9070c65398afdc0bee70a8359838d30230d5ad0bae07a1500ba5744f894
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / agent_framework_hosting_mcp-1.0.0a261022-py3-none-any.whl

Download URL agent_framework_hosting_mcp-1.0.0a261022-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46b600d5589fb91736853706628ec05c4c764a81c093cd3744c23f97cea2ebec
BLAKE2b-256 checksum
How to use checksums
23f2801359c6680dce8a5b5b98da6225fa6007de56e0f8a308bd6cf31fac196c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for agent-framework-hosting-mcp 1.0.0a261022

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page