Microsoft Agent Framework MCP: connect an agent to Sume
Connect a Microsoft Agent Framework agent to Sume's hosted MCP server with MCPStreamableHTTPTool, a key header, allowed_tools, and approval_mode.

In Python, Microsoft Agent Framework connects an agent to a remote MCP server through MCPStreamableHTTPTool: give it a name and the server's url, pass it to the agent as a tool, and the agent can call that server's tools. For Sume's hosted MCP server, the URL is https://mcp.sume.com/mcp, and a Sume API key travels in an Authorization: Bearer header set with static_headers or a header_provider.
Agent Framework's side comes from Microsoft Learn's Using MCP tools with Agents, MCPStreamableHTTPTool reference, and tool approval pages; Sume's side comes from MCP OAuth and API keys, MCP tools and gates, and Jobs and results, all read on 2026-09-28. Sume has no official Agent Framework connector: this is the framework's own MCP client talking to Sume's remote server, and Sume's basics page says hosted MCP still works but is not part of the primary path today. Pydantic AI MCP server covers another Python framework.
How do I connect an Agent Framework agent to Sume?
Microsoft notes that minimal Python installs might need mcp --pre installed before MCPStreamableHTTPTool works. The example gives the agent four Sume tools and holds generate_video for a person's approval:
import asyncio
import os
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIChatClient
async def main() -> None:
key = os.environ["SUME_API_KEY"]
sume = MCPStreamableHTTPTool(
name="Sume",
url="https://mcp.sume.com/mcp",
header_provider=lambda _kwargs: {"Authorization": f"Bearer {key}"},
allowed_tools=["tools_schema", "generate_video", "jobs_wait", "jobs_result"],
approval_mode={"always_require_approval": ["generate_video"]},
)
async with Agent(
client=OpenAIChatClient(),
name="VideoAgent",
instructions="Preview paid calls with dry_run=true. Wait with jobs_wait; never resubmit.",
tools=sume,
) as agent:
result = await agent.run("A 5-second clip of waves at sunset.")
for request in result.user_input_requests:
print(request.function_call.name, request.function_call.arguments)
asyncio.run(main())Should the key go in static_headers or header_provider?
Microsoft's page names both: static_headers for fixed credentials and header_provider for values derived from each run. Its complete API-key example uses a header_provider that returns the Authorization header, as the code above does; that provider authenticates both connection-time and tool-call requests. Both paths add headers only to requests for the configured origin and remove them from cross-origin redirects, and when both supply the same header, the header_provider value wins.
header_providerreceives only the run's hostfunction_invocation_kwargs, never tool arguments the model writes, so the model can't change which key is sent.- Use it for per-user keys. Sume API keys and spend resolve to a workspace, so the key decides which workspace pays.
- Sume accepts
Authorization: Bearerorx-api-key. Send one: in current code, a request carrying both is refused withSend only one MCP credential. - Microsoft asks you to review any API keys or other credentials shared with remote MCP servers.
Which Sume tools should the agent see?
An API-key session sees Sume's full hosted tool set, paid tools included. allowed_tools narrows what the agent gets, and approval_mode takes "always_require", "never_require", or a dict listing tool names under always_require_approval or never_require_approval. Use Sume's raw tool names: if a configured name matches several remote names after normalization, Agent Framework raises ToolExecutionException. Sume's authentication docs ask for explicit confirmation before write or paid generation.
| Tool | Sume group | Example's `allowed_tools` | Example's `approval_mode` |
|---|---|---|---|
tools_schema | Discovery | Kept | Not listed |
generate_video | Paid | Kept | always_require_approval |
jobs_wait, jobs_result | Jobs, read | Kept | Not listed |
jobs_cancel | Jobs, write | Dropped | Not reached |
What happens when a paid call needs approval?
An agent run that needs approval completes with user_input_requests instead of a final answer. Each request carries the function call's name and arguments. Show them to a person, pass request.to_function_approval_response(True) (or False) back to the agent in a new run with the conversation so far, and repeat until no requests remain. Human in the loop AI agents covers where that approval belongs.
Approve after a preview. Sume's playbook for paid tools is to call with dry_run=true, confirm the estimate, balance, and queue behavior, then submit with a fresh idempotency_key, which every paid tool requires. max_spend_usd caps a call only when you pass it. Because approval_mode names tools, not arguments, the dry-run call to generate_video asks for approval too.
Will long Sume jobs time out, and what else should I know?
- One Sume
jobs_waitcall holds for up to 55 seconds, or 50 whentimeout_secondsis omitted. The API reference listsrequest_timeout, the default timeout in seconds for all requests; if you set it, keep it above 55. - On
wait_slice_expired, the agent should calljobs_waitagain with the same ids and never resubmit the paid create. - This is the local MCP tool: your process calls Sume. Microsoft also documents hosted MCP tools for Foundry agents, where the backing AI service executes the MCP tools; that is a separate setup.
- Hosted MCP can't read files from your laptop.
Sources
- Microsoft Learn: Using MCP tools with Agents (read 2026-09-28)
- Microsoft Learn: agent_framework.MCPStreamableHTTPTool class (read 2026-09-28)
- Microsoft Learn: Using function tools with human in the loop approvals (read 2026-09-28)
- Microsoft Learn: Using hosted MCP tools (read 2026-09-28)
- MCP OAuth and API keys
- MCP tools and gates
- Jobs and results
- Authentication
- Sume basics
Related posts
More in Integrations
- n8n Google Sheets Trigger: start a video from each new row
n8n's Google Sheets Trigger polls a sheet and fires on added or updated rows. Key each row's video run on a row id so an edit doesn't bill twice.
- n8n human in the loop: approve each AI video before posting
In n8n, a Send and Wait for Response step pauses the workflow until a person approves or declines. Put it after the video is made and before it is posted.
- n8n MCP Server Trigger: give Claude a video tool
n8n's MCP Server Trigger makes a workflow an MCP server with its own URL. How to connect Claude and attach a tool that generates a video over HTTPS.
- n8n RSS Feed Trigger: start a video for each new feed item
n8n's RSS Feed Trigger polls a feed and emits items newer than the last one it saw. Send each item's text to a video run keyed on its guid.
Written by Sume