Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/python-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# @wbx-modified copilot-a3f7·MTN | 2026-04-24 | Python SDK CI
name: python-sdk

on:
push:
branches: [main]
paths:
- "clients/python/**"
- ".github/workflows/python-sdk.yml"
pull_request:
branches: [main]
paths:
- "clients/python/**"
- ".github/workflows/python-sdk.yml"

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: clients/python
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: clients/python/pyproject.toml

- name: Install
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Lint
run: ruff check recall_client tests

- name: Test
run: pytest -q
43 changes: 43 additions & 0 deletions .github/workflows/ts-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# @wbx-modified copilot-a3f7·MTN | 2026-04-24 | TS SDK CI
name: ts-sdk

on:
push:
branches: [main]
paths:
- "clients/typescript/**"
- ".github/workflows/ts-sdk.yml"
pull_request:
branches: [main]
paths:
- "clients/typescript/**"
- ".github/workflows/ts-sdk.yml"

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: clients/typescript
strategy:
matrix:
node-version: ["18", "20", "22"]
steps:
- uses: actions/checkout@v4

- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Install
run: npm install --no-audit --no-fund

- name: Typecheck
run: npx tsc --noEmit

- name: Test
run: npx vitest run --reporter=basic

- name: Build
run: npx tsup src/index.ts --format esm,cjs --dts --clean
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
[![MCP](https://img.shields.io/badge/MCP-compatible-7c3aed)](https://modelcontextprotocol.io)
[![Container](https://img.shields.io/badge/ghcr.io-recallworks%2Frecall-2496ED?logo=docker&logoColor=white)](https://github.com/RecallWorks/Recall/pkgs/container/recall)

[**OSS quickstart**](#five-minute-install) · [**Recall Pro →**](#recall-open-source-vs-recall-pro-vs-hosted) · [**Book a demo**](mailto:sales@recall.works?subject=Recall%20demo) · [**IceWhisperer for Encompass**](https://icewhisperer.ai)

</div>

> Your agent forgets every session. Recall fixes that — with a small,
Expand Down Expand Up @@ -85,8 +87,7 @@ Full walkthrough: [docs/quickstart.md](docs/quickstart.md).
| **MCP-native** | yes, plus plain HTTP | partial / via wrapper |
| **Ops model** | single binary, single container | multi-service stack |

If you want a managed service, that's coming under `enterprise/`. If you want
a brain you fully own, the OSS core is enough.
If you want a managed service, see [Recall Cloud](#recall-open-source-vs-recall-pro-vs-hosted) below. If you want a brain you fully own, this OSS core is enough.

---

Expand Down Expand Up @@ -141,6 +142,41 @@ Security issues: see [SECURITY.md](SECURITY.md).

---

## Recall Open Source vs. Recall Pro vs. Hosted

| Capability | OSS (this repo) | **Recall Pro** | **Recall Cloud** |
|-------------------------------------|:---------------:|:--------------:|:----------------:|
| Single-tenant Docker image | ✅ | ✅ | n/a (hosted) |
| 13 memory tools, MCP + HTTP | ✅ | ✅ | ✅ |
| BYO embedder + LLM | ✅ | ✅ | ✅ |
| Append-only artifacts + auto-snapshot| ✅ | ✅ | ✅ |
| Multi-tenant, SSO, RBAC | — | ✅ | ✅ |
| Audit log + retention policy | — | ✅ | ✅ |
| Cross-session entity graph | — | ✅ | ✅ |
| PII sanitization pipeline | — | ✅ | ✅ |
| Snapshot replication / DR | — | ✅ | ✅ |
| Vendor support + SLA | community | business hours | 24×7 |
| Hosted on our infra | — | — | ✅ |
| **Pricing** | **free** | **from $99/mo per node** | **from $0.10 per 1k tools** |

**Recall Pro** ships from the `enterprise/` tree under a [Business Source License](LICENSE-COMMERCIAL.md) — source-available, 5-seat free Additional Use Grant, converts to MIT after 3 years. Buy a license and the `enterprise/` modules light up alongside your OSS install.

**Recall Cloud** is the hosted multi-tenant version. Same tools, no infra. Reach out for early-access pricing.

➡️ Talk to sales: `sales@recall.works` · Book a 20-min walkthrough: `https://recall.works/demo`

---

## Vertical builds powered by Recall

Recall is the engine. We ship turn-key vertical brains on top of it:

- **[IceWhisperer](https://icewhisperer.ai)** — the memory + workflow brain for ICE Mortgage Technology / Encompass shops. Pre-loaded SDK index, settings recipes, plugin audits, drift detection. Pilots from $250/mo.

If you want a vertical brain for *your* industry, we'll build it. Email `partners@recall.works`.

---

## Maintainers

Reach the maintainers at `maintainers@recall.works`. Issues and PRs welcome on GitHub.
72 changes: 72 additions & 0 deletions clients/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!-- @wbx-modified copilot-a3f7·MTN | 2026-04-24 | Python SDK README | prev: NEW -->
# recall-client (Python)

Official Python SDK for [Recall](https://github.com/RecallWorks/Recall) — open-source memory for AI agents.

## Install

```bash
pip install recall-client
```

## Quick start

```python
from recall_client import RecallClient

with RecallClient("http://localhost:8787", api_key="changeme") as client:
client.remember("the user prefers dark mode", tags=["pref", "ui"])
hits = client.recall("user preferences", limit=5)
for h in hits:
print(f"{h.score:.3f} {h.content}")
```

## Async

```python
import asyncio
from recall_client import AsyncRecallClient

async def main():
async with AsyncRecallClient("http://localhost:8787", api_key="changeme") as c:
await c.remember("async memory works", tags=["async"])
hits = await c.recall("memory")
print(hits)

asyncio.run(main())
```

## Tool surface

The client exposes typed wrappers for the high-traffic tools:

| Method | Recall tool |
|--------|-------------|
| `remember()` | `remember` |
| `recall()` | `recall` |
| `reflect()` | `reflect` |
| `checkpoint()` | `checkpoint` |
| `pulse()` | `pulse` |
| `memory_stats()` | `memory_stats` |
| `forget()` | `forget` |
| `health()` | `GET /health` |

For any tool without a typed wrapper (e.g. `index_file`, `reindex`, `snapshot_index`, `anti_pattern`, `session_close`, `maintenance`), use the generic dispatch:

```python
client.call_tool("index_file", path="/data/notes.md")
client.call_tool("anti_pattern", pattern="don't auto-merge without CI")
```

## Errors

All exceptions derive from `RecallError`:

- `RecallConnectionError` — server unreachable
- `RecallAuthError` — 401/403 (bad/missing API key)
- `RecallServerError` — 5xx
- `RecallToolError` — tool returned an explicit `error`

## License

MIT. See [LICENSE](https://github.com/RecallWorks/Recall/blob/main/LICENSE) at the root of the Recall repo.
55 changes: 55 additions & 0 deletions clients/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# @wbx-modified copilot-a3f7·MTN | 2026-04-24 | Python SDK packaging | prev: NEW
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "recall-client"
version = "0.1.0"
description = "Official Python client for Recall — open-source memory for AI agents"
readme = "README.md"
license = "MIT"
requires-python = ">=3.10"
authors = [{ name = "RecallWorks contributors", email = "maintainers@recall.works" }]
keywords = ["mcp", "memory", "ai-agents", "llm", "vector-search", "recall"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Libraries",
]
dependencies = [
"httpx>=0.27",
]

[project.urls]
Homepage = "https://github.com/RecallWorks/Recall"
Documentation = "https://github.com/RecallWorks/Recall/tree/main/clients/python"
Repository = "https://github.com/RecallWorks/Recall"
Issues = "https://github.com/RecallWorks/Recall/issues"

[project.optional-dependencies]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"respx>=0.21",
"ruff>=0.5",
]

[tool.hatch.build.targets.wheel]
packages = ["recall_client"]

[tool.hatch.build.targets.sdist]
include = ["recall_client/**", "README.md", "pyproject.toml"]

[tool.ruff]
line-length = 100
target-version = "py310"

[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]
46 changes: 46 additions & 0 deletions clients/python/recall_client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# @wbx-modified copilot-a3f7·MTN | 2026-04-24 | Python SDK package init | prev: NEW
"""recall_client — official Python SDK for Recall memory server.

Quick start:

from recall_client import RecallClient

client = RecallClient("http://localhost:8787", api_key="changeme")
client.remember("first memory", tags=["hello"])
hits = client.recall("hello", limit=5)
for h in hits:
print(h.content, h.score)

Async usage:

from recall_client import AsyncRecallClient

async with AsyncRecallClient("http://localhost:8787", api_key="changeme") as c:
await c.remember("async memory")
hits = await c.recall("memory")
"""

from .async_client import AsyncRecallClient
from .client import RecallClient
from .exceptions import (
RecallAuthError,
RecallConnectionError,
RecallError,
RecallServerError,
RecallToolError,
)
from .models import Hit, RememberResult, ToolResult

__version__ = "0.1.0"
__all__ = [
"AsyncRecallClient",
"Hit",
"RecallAuthError",
"RecallClient",
"RecallConnectionError",
"RecallError",
"RecallServerError",
"RecallToolError",
"RememberResult",
"ToolResult",
]
Loading
Loading