Add STACK to the OpenAI Agents SDK as a Streamable HTTP MCP server. The example authenticates the MCP session with an operator API key. Proxy and Intent calls also require a Passport, which supplies the agent attribution and narrowed authority. STACK holds and injects the service credentials.
For the supported authentication methods, see STACK authentication.
Connect the service and approve the fleet policy before starting automated work. The approved provisioner enrolls workers with their own keys. A worker uses its key to obtain a short-lived MCP session, then calls stack_start_mission with the job’s exact access and limits.
Use the returned Passport for calls through STACK. Routine allowed calls require no additional approval. Call stack_renew_mission to continue the same job without resetting its allowance. The client can obtain another session and reconnect with the worker’s key when its MCP session expires.
Interactive OAuth signs the client in as a member. Fleet execution uses the enrolled worker’s identity. Use a client or application runtime that can present the worker’s session token for this flow.
pip install openai-agentsTypeScript users can use @openai/agents with the equivalent MCPServerStreamableHttp primitive.
Sign up at getstack.run (free tier, no credit card). Copy the API key from the dashboard, then export it in your shell:
export STACK_API_KEY="sk_live_..."import os
import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
stack_token = os.environ["STACK_API_KEY"]
async def main() -> None:
async with MCPServerStreamableHttp(
name="STACK",
params={
"url": "https://mcp.getstack.run/mcp",
"headers": {"Authorization": f"Bearer {stack_token}"},
"timeout": 30,
},
) as stack:
agent = Agent(
name="Assistant",
instructions=(
"You are a helpful assistant. Use STACK to access "
"user-authorized services securely. Never store or "
"echo raw credentials."
),
mcp_servers=[stack],
)
result = await Runner.run(agent, "Send a message in #alerts: deploy completed.")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main())The MCP session can call the STACK tools permitted by its Bearer credential — stack_register_agent, stack_issue_passport, stack_proxy_request, stack_get_proxy_operation, stack_invoke_skill, stack_create_dropoff. Proxy and Intent tools require a Passport and are limited by the agent's service grants and the Passport's scope; the operator API key alone does not authorize every connected service.
Enforced-mode agents can route Intents through STACK's approval queue before executing. The agent calls stack_submit_intent, polls stack_get_intent_approval until the status is terminal, then threads the approval id on stack_proxy_request. Rejection auto-revokes the passport.
Bind the flow in the agent's system prompt. Name the intents that require approval, instruct it to submit and poll before firing, and require it to thread approval_id on every subsequent proxy call. The gate checks the call shape against the approved Intent (service, method, URL host, body); mismatch returns 403 with metadata.gate_reason="call_mismatch".
agent = Agent(
name="Assistant",
instructions=(
"You manage Stripe refunds and Slack incident channels.\n"
"Before any stripe.create_refund or slack.archive_channel call:\n"
" 1. stack_submit_intent with the candidate IntentClaim.\n"
" 2. Poll stack_get_intent_approval until status != 'pending'.\n"
" 3. If approved, call stack_proxy_request with approval_id and the persisted job operation id.\n"
" 4. Reuse that id only for the unchanged request; after response loss, call stack_get_proxy_operation.\n"
" 5. If rejected or expired, stop. Do not retry."
),
mcp_servers=[stack],
)The application should create and persist a UUID for each non-GET job before handing the job to the agent. That value becomes authority_request_id. Recovery and authorization details are centralized in Proxy operation recovery.
For backend code, the simplest path is the API key as a Bearer token (the example above). The API key represents an operator (you) and lets your code mint passports for the agents it runs.
If you need per-end-user OAuth on top — for example, an SDK-driven app where each customer logs in and authorises STACK individually — STACK's OAuth 2.1 + DCR endpoint at https://api.getstack.run/.well-known/oauth-authorization-server works the same way as it does for the Workspace Agents path. You implement the standard authorisation-code flow with PKCE and pass the resulting access token in the headers dict instead of the API key.
Full tool reference at /docs/mcp-tools.