AutoGen quickstart — governed AG2 tools
This guide gives an AutoGen 0.4+ AssistantAgent a tool generated from the
running Cordum MCP bridge. Calls through that tool retain the bridge's JSON
Schema and pass through Cordum's policy and approval path.
Before you start
- Python 3.10+; Python 3.11 and 3.12 are CI-covered.
- A Cordum core checkout bootstrapped with
./tools/scripts/quickstart.sh. cordum-mcp-bridgeonPATH.OPENAI_API_KEYfor the AG2 model client.- The TLS environment from Framework integrations.
:::warning AutoGen version matrix
Modern autogen-core / autogen-agentchat and legacy pyautogen install
incompatible OpenAI dependency ranges. Use the modern extra for this page and
do not install both extras in one environment.
:::
1. Install
python -m venv .venv
source .venv/bin/activate
pip install "cordum-adapters[autogen]" "autogen-ext[openai]>=0.4"
2. Discover and select a real bridge tool
Save as autogen_quickstart.py:
import asyncio
import os
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from cordum_agent_adapters.audit import CordumConversationLogger
from cordum_agent_adapters.autogen.modern import build_ag2_tools
from cordum_agent_adapters.mcp_client import McpStdioClient
TOOL_NAME = "cordum.workflow.run"
def require_tool(tool_defs: list[dict], name: str) -> list[dict]:
selected = [tool for tool in tool_defs if tool.get("name") == name]
if not selected:
advertised = sorted(str(tool.get("name")) for tool in tool_defs)
raise RuntimeError(f"{name} is not advertised; got {advertised}")
return selected
async def main() -> None:
client = McpStdioClient(
command=["cordum-mcp-bridge"],
env=os.environ.copy(),
)
model = OpenAIChatCompletionClient(
model=os.getenv("OPENAI_MODEL", "gpt-4.1-mini"),
api_key=os.environ["OPENAI_API_KEY"],
)
try:
tool_defs = require_tool(client.list_tools(), TOOL_NAME)
logger = CordumConversationLogger(client)
tools = build_ag2_tools(client, tools=tool_defs, logger=logger)
agent = AssistantAgent(
name="workflow_operator",
model_client=model,
tools=tools,
system_message="Use only the Cordum tools you were given.",
)
result = await agent.run(
task=(
"Start workflow demo-workflow as a dry run with empty input. "
"Report the returned run identifier or the governance outcome."
)
)
print(result.messages[-1].content)
finally:
await model.close()
client.close()
if __name__ == "__main__":
asyncio.run(main())
The explicit require_tool check keeps the example aligned with the running
bridge. If the installed bridge does not advertise the tool, the script stops
before constructing an agent around an imaginary API.
3. Run
Load .env and the TLS variables from the common setup, then run:
python autogen_quickstart.py
Use a workflow identifier that exists in your tenant. The exact response is deployment data, so this guide does not prescribe a fabricated transcript. Inspect the run in the dashboard or query it through the gateway API.
4. Exercise a hard deny
Create a v1 bundle that denies the bridge capability used above:
version: v1
rules:
- id: block-tutorial-workflow-run
match:
capabilities:
- cordum.workflow.run
decision: deny
reason: "Tutorial hard-deny check"
Upload the bundle through PUT /api/v1/policy/bundles/{id} using the HTTPS
gateway and curl --cacert "$CORDUM_TLS_CA". Re-run the script.
A hard deny returns an MCP tool result with isError: true.
McpStdioClient raises McpToolError; the AG2 adapter converts it to an AG2
tool-call error so the model can report the blocked action.
5. Recognize approval holds
The pack bridge keeps an approval-gated job nonterminal and blocks the original
tool call. Set a bounded CORDUM_MCP_CALL_TIMEOUT, then resolve the pending job
from the dashboard in another window. Approval before the timeout lets the same
call continue; a timeout surfaces through the tool-error path. This bridge does
not use an approval-reference retry.