Metadata-Version: 2.4
Name: switchy-sdk
Version: 0.2.0
Summary: Official Python SDK for the Switchy AI memory, chat, and MCP server API
Project-URL: Homepage, https://switchy.build
Project-URL: Documentation, https://switchy.build/api-dashboard
Project-URL: Repository, https://github.com/Switchy-AI/switchy
Project-URL: Bug Tracker, https://github.com/Switchy-AI/switchy/issues
Author-email: Switchy AI <contact@switchy.build>
License: MIT
Keywords: ai,knowledge-graph,mcp,memory,openrouter,sdk,switchy
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.25.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# switchy-sdk

Official Python SDK for the [Switchy AI](https://switchy.build) memory, knowledge-graph, and multi-model chat API.

## Install

```bash
pip install switchy-sdk
```

## Quick start

```python
from switchy import Switchy

client = Switchy(api_key="switchy_...")

response = client.chat.complete(
    model="anthropic/claude-sonnet-4",
    message="Summarise my recent project notes",
    memory={"enabled": True, "extractMemories": True},
)

print(response["message"]["content"])
```

## MCP server (v0.2.0)

Switchy is also an MCP server. Use `McpClient` to call its tools from your own
Python code (the same surface Claude Desktop and Cursor talk to).

```python
from switchy import McpClient

mcp = McpClient(api_key="sk_live_...")

# Org-scoped reads + writes — no actor needed.
result = mcp.search_memory(query="launch readiness")
for m in result["memories"]:
    print(m["content"])

mcp.add_memory(content="We picked Ably for realtime in April 2026.", visibility="ORG")

# Acting on behalf of a specific human (required for PRIVATE memory access
# and post_message). The key must carry the act_on_behalf scope.
as_alice = mcp.act_as_user("user_abc123")
as_alice.post_message(
    session_id="cmo5...",
    content="Posting from a script — @claude please draft a reply.",
)
```

There's also an `AsyncMcpClient` with the same surface for `asyncio` callers.

### Errors

| Class | When |
|---|---|
| `McpAuthError` | 401 / 403 — missing key, wrong scope, actor not in org |
| `McpNotFoundError` | 404 — resource doesn't exist OR isn't visible to the caller |
| `McpInvalidParamsError` | 400 — params didn't match the tool's schema |
| `McpRateLimitError` | 429 — `retry_after_ms`, `cap`, `kind` available on the error |
| `McpError` | catch-all base class |

### Key minting + docs

Mint a key at <https://switchy.build/settings#api-keys> (click **Mint MCP key**).
Full install snippets for Claude Desktop / Cursor / generic HTTP live at
<https://switchy.build/docs/mcp>. The OpenAPI spec is at
<https://switchy.build/api/mcp/openapi.json>.

## Streaming

```python
for chunk in client.chat.stream(
    model="openai/gpt-5",
    message="Write a haiku about memory",
):
    if chunk.get("type") == "token":
        print(chunk.get("content", ""), end="", flush=True)
```

## Async

```python
import asyncio
from switchy import AsyncSwitchy

async def main():
    async with AsyncSwitchy(api_key="switchy_...") as client:
        res = await client.chat.complete(
            model="anthropic/claude-sonnet-4",
            message="Hello",
        )
        print(res["message"]["content"])

asyncio.run(main())
```

## Memory

```python
# Create a namespace
client.namespaces.create(name="my-project")

# Store a memory frame
client.memory.create_frame(
    "my-project",
    content="User prefers dark mode and TypeScript",
    metadata={"source": "onboarding"},
)

# Contextual retrieval
relevant = client.memory.context("my-project", query="user preferences", limit=5)
```

## Knowledge graph

```python
client.knowledge_graph.create_entity(
    "my-project", name="AuthService", type="service"
)

client.knowledge_graph.create_relation(
    "my-project", source="AuthService", target="User", type="authenticates"
)
```

## Error handling

```python
from switchy import Switchy, SwitchyError, RateLimitError

try:
    client.chat.complete(model="openai/gpt-5", message="hi")
except RateLimitError as e:
    print(f"Rate limited, retry in {e.retry_after}s (limit={e.limit})")
except SwitchyError as e:
    print(f"API error: {e.code} — {e}")
```

## API reference

- `chat.complete(...)` — single-turn completion
- `chat.stream(...)` — SSE streaming iterator
- `models.list(featured=True)` — list available models (350+)
- `namespaces.{create,list,get,update,delete}` — memory namespace management
- `memory.{create_frame,list_frames,context,semantic,search,bridge,consolidate}` — memory operations
- `knowledge_graph.{create_entity,create_relation,query}` — graph operations
- `sessions.{create,list,get}` — session management

Full OpenAPI spec: https://switchy.build/api/v1/openapi.json

## License

MIT
