Skip to main content

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-bridge on PATH.
  • OPENAI_API_KEY for 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.

What's next