# Connect Open Interpreter to Axiom

**Transport:** stdio (via shell-bridge today; native MCP tracked upstream)
**Auth:** local-stdio (Phase 0)
**Status:** Pending upstream — Open Interpreter doesn't ship a first-party MCP client as of 2026-Q2

Open Interpreter (the `interpreter` CLI) is a code-execution-focused agent
loop. Its tool model is Python-callable, not MCP-spec. Native MCP support
is being discussed upstream; this recipe documents the bridge pattern.

## Install prerequisites

- `pip install open-interpreter`
- Same Axiom prerequisites.

## Configure the connection (shell bridge)

Drop a Python helper into Open Interpreter's custom-tools directory
(or import from anywhere on `PYTHONPATH`):

```python
# ~/.openinterpreter/tools/axiom_mcp.py
"""Bridge Axiom MCP tools into Open Interpreter as native callables."""

import json
import subprocess


def _call_axiom_tool(tool_name: str, args: dict) -> dict:
    """Invoke an Axiom MCP tool by name; return its JSON result."""
    result = subprocess.run(
        ["axi", "mcp", "call", tool_name],
        input=json.dumps(args),
        capture_output=True,
        text=True,
        check=True,
    )
    return json.loads(result.stdout)


def axiom_hooks_list() -> dict:
    """List hooks installed on the local Axiom node."""
    return _call_axiom_tool("axiom_node__hooks_list", {})


def axiom_memory_compose(kind: str, content: str, principal: str = "") -> dict:
    """Write a memory fragment via CompositionService."""
    args = {"kind": kind, "content": content}
    if principal:
        args["principal"] = principal
    return _call_axiom_tool("axiom_memory__compose", args)


def axiom_memory_retrieve(**filters) -> dict:
    """Read memory fragments by (kind, principal, cohort, limit) filter."""
    return _call_axiom_tool("axiom_memory__retrieve", filters)


def axiom_rag_retrieve(query: str, k: int = 5) -> dict:
    """Hybrid retrieval over local RAG store."""
    return _call_axiom_tool("axiom_rag__retrieve", {"query": query, "k": k})
```

Then in your Interpreter session:

```python
from axiom_mcp import axiom_hooks_list, axiom_memory_compose, axiom_rag_retrieve
```

Or, for ad-hoc use without a helper module:

```python
import subprocess, json
result = subprocess.run(
    ["axi", "mcp", "call", "axiom_node__hooks_list"],
    input="{}", capture_output=True, text=True, check=True,
)
print(json.loads(result.stdout))
```

## Verify

```python
>>> axiom_hooks_list()
{'node': '/Users/<you>/.axiom', 'hooks_total': 0, 'events_observed': [], 'by_event': {}}
```

## Notes

- Open Interpreter executes Python in its own runtime. The bridge above
  is sufficient for Axiom tools the user wants to call deliberately;
  it doesn't give Open Interpreter the same auto-discovery a native
  MCP client would.
- The `axi mcp call` CLI verb is a thin synchronous wrapper over the
  same dispatch path the MCP server uses; results are byte-identical.
- Shell-bridge tools incur ~150 ms subprocess overhead per call. Fine
  for interactive use; use the native MCP client when one ships.

## What we'd need upstream

Open Interpreter would need an MCP-client mode (`interpreter --mcp <server>`)
that registers MCP tools as native Python callables in the agent's
namespace. Spec-compliant MCP-over-stdio is a small implementation; a
PR upstream is the right next step.

## Troubleshooting

| Symptom | Likely cause | Fix |
|---|---|---|
| `axi: command not found` | venv inactive | Use absolute path in `subprocess.run` |
| `JSONDecodeError` on result | tool exited non-zero | `result.stderr` has the error |
| Slow response | 150ms per call subprocess overhead | Batch related calls; one `axiom_memory_retrieve` is cheaper than N |

## References

- ADR-038 §D7
- Open Interpreter docs: https://docs.openinterpreter.com

_Copyright (c) 2026 B-Tree Ventures, LLC. Apache-2.0 licensed._
