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

# Integrations

> Drop-in support for LangChain, Anthropic, OpenAI, and MCP.

The SDK integrates with major AI frameworks. Each integration captures tool calls automatically — no need to wrap every function with `@quint.guard()`.

## Anthropic Messages API

```python theme={null}
import anthropic
import quint_agent
from quint_agent.integrations.anthropic import guarded_dispatch

quint_agent.init(api_key="qak_...")
client = anthropic.Anthropic()

tools_map = {
    "read_file": read_file,
    "run_command": run_command,
    "query_db": query_db,
}

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=4096,
    tools=[...],  # your tool definitions
    messages=[{"role": "user", "content": "Analyze the codebase"}],
)

for block in response.content:
    if block.type == "tool_use":
        # guarded_dispatch captures + policy-checks before executing
        result = guarded_dispatch(block.name, block.input, tools_map)
```

`guarded_dispatch` handles the full lifecycle:

1. Emits a `tool_call` event with the tool name and arguments
2. Evaluates the call against your YAML policy
3. If blocked, raises `ToolBlockedError` (return this as a tool error to Claude)
4. If allowed, executes the function and emits a `tool_result` event

## LangChain

```python theme={null}
from langchain_anthropic import ChatAnthropic
from langchain.agents import create_tool_calling_agent, AgentExecutor
from quint_agent.integrations.langchain import QuintCallbackHandler

quint_agent.init(api_key="qak_...")

llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools)

# The callback handler captures every tool call automatically
executor.invoke(
    {"input": "What files are in the project?"},
    config={"callbacks": [QuintCallbackHandler()]},
)
```

The callback handler hooks into LangChain's event system:

* `on_tool_start` → emits `tool_call` + runs policy check
* `on_tool_end` → emits `tool_result`
* `on_tool_error` → emits `tool_error`

## MCP (Model Context Protocol)

```python theme={null}
from quint_agent.integrations.mcp import QuintMCPClient

quint_agent.init(api_key="qak_...")

async with mcp_client() as session:
    guarded = QuintMCPClient(session)

    # Every call_tool goes through Quint's policy engine
    result = await guarded.call_tool("read_file", {"path": "/etc/hosts"})
```

`QuintMCPClient` wraps the MCP session and intercepts `call_tool`:

* Captures the tool name and arguments
* Runs policy evaluation
* Delegates to the underlying MCP session if allowed

## OpenAI Function Calling

```python theme={null}
from openai import OpenAI
from quint_agent.integrations.openai import guarded_function_call

quint_agent.init(api_key="qak_...")
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o",
    tools=[...],
    messages=[{"role": "user", "content": "Read the config"}],
)

for choice in response.choices:
    for call in choice.message.tool_calls or []:
        result = guarded_function_call(
            call.function.name,
            json.loads(call.function.arguments),
            tools_map,
        )
```

## Using without a framework

If you're building a custom agent loop, use `@quint.guard()` directly:

```python theme={null}
import quint_agent

quint_agent.init(api_key="qak_...")

@quint_agent.guard()
def read_file(path: str) -> str:
    return open(path).read()

@quint_agent.guard()
def write_file(path: str, content: str) -> None:
    with open(path, "w") as f:
        f.write(content)

@quint_agent.guard(name="shell")  # custom tool name
def run(cmd: str) -> str:
    import subprocess
    return subprocess.check_output(cmd, shell=True, text=True)
```

The `@guard()` decorator works with both sync and async functions.
