> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rotascale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrations overview

> Four ways to get an agent's work under governance, eleven runtimes with a one-line adapter, and the rule for choosing between them.

RotaGrant governs the **action**, not the framework. You keep whatever
orchestration you already chose; these adapters exist so you do not write the
same wiring twice.

## Four ways in

They differ in one thing that matters more than convenience: whether the check
is *on the causal path* or beside it.

<CardGroup cols={2}>
  <Card title="SDK" icon="code" href="/sdk/python">
    A few lines. You decide where authority is asked for, which means you can
    also decide not to — enforcement here is cooperative.
  </Card>

  <Card title="Middleware" icon="layer-group" href="/sdk/middleware">
    One line per runtime. Captures what your framework was already doing, so
    the trajectory fills in without hand-instrumenting each call.
  </Card>

  <Card title="MCP proxy" icon="shield-halved" href="/sdk/mcp-proxy">
    Zero code in the agent. It sits **between** the decision and the tool call,
    so an agent cannot route around a check it never makes.
  </Card>

  <Card title="OpenTelemetry" icon="chart-line" href="/guides/capture-with-otel">
    Nothing deployed alongside the agent. Point a collector at the receiver and
    existing spans become governed records.
  </Card>
</CardGroup>

<Note>
  **Capture and enforcement are different questions.** Middleware and OTel
  capture what happened. Only the proxy — and a resource verifying a capability
  token — can refuse an action the agent did not ask permission for. Choosing an
  adapter is choosing how much you record; choosing the proxy is choosing what
  can be stopped.
</Note>

## Supported runtimes

<CardGroup cols={2}>
  <Card title="OpenAI" href="/integrations/openai">
    <code>watch\_openai</code>
  </Card>

  <Card title="Anthropic" href="/integrations/anthropic">
    <code>watch\_anthropic</code>
  </Card>

  <Card title="Google Gemini" href="/integrations/gemini">
    <code>watch\_gemini</code>
  </Card>

  <Card title="AWS Bedrock" href="/integrations/bedrock">
    <code>watch\_bedrock</code>
  </Card>

  <Card title="LangChain" href="/integrations/langchain">
    <code>watch\_langchain</code>
  </Card>

  <Card title="LangGraph" href="/integrations/langgraph">
    <code>watch\_langgraph</code>
  </Card>

  <Card title="Google ADK" href="/integrations/adk">
    <code>watch\_adk</code>
  </Card>

  <Card title="CrewAI" href="/integrations/crewai">
    <code>watch\_crew</code>
  </Card>

  <Card title="AWS Strands" href="/integrations/strands">
    <code>watch\_strands</code>
  </Card>

  <Card title="AutoGen" href="/integrations/autogen">
    <code>watch\_autogen</code>
  </Card>

  <Card title="MCP" href="/integrations/mcp">
    <code>watch\_mcp</code>
  </Card>
</CardGroup>

## Function reference

Everything below is exported from `rotascale.middleware`.

| Function          | Wraps                         | Runtime       |
| ----------------- | ----------------------------- | ------------- |
| `watch_openai`    | `chat.completions.create`     | OpenAI        |
| `watch_anthropic` | `messages.create`             | Anthropic     |
| `watch_gemini`    | `generate_content`            | Google Gemini |
| `watch_bedrock`   | `converse` and `invoke_model` | AWS Bedrock   |
| `watch_langchain` | the callback interface        | LangChain     |
| `watch_langgraph` | the graph callback interface  | LangGraph     |
| `watch_adk`       | an ADK agent, in place        | Google ADK    |
| `watch_crew`      | a `Crew`                      | CrewAI        |
| `watch_strands`   | a Strands agent               | AWS Strands   |
| `watch_autogen`   | a `GroupChat`                 | AutoGen       |
| `watch_mcp`       | an MCP client session         | MCP           |

## What they all do, and what none of them do

Every adapter **records steps**: model calls, tool calls, retrievals and
delegations, written onto the open trajectory with taint propagated.

None of them asks for authority. That stays an explicit call, because a
middleware that silently authorised would make an import into a spend decision:

```python theme={"system"}
with client.witness(agent) as trajectory:
    trajectory.authorize(GRANT, {{"tools": ["issue_refund"]}}, amount_minor=4_500)
    issue_refund(...)
```

Capture **fails open** and enforcement **fails closed**. Losing a record must
never stop the work; losing a decision must never let it through.

## Content capture

Every adapter takes `capture_content=False`, which records shape and metadata —
model, latency, token counts, tool names — and not the text.

Use it where the prompt or the response is the sensitive part. The governance
record is just as complete: what an agent *did* is the governed fact, and the
words it used to do it are usually the part you are least able to store.
