This repository has no description
6.5 kB
159 lines
1# semble-api
2
3python client for the [semble](https://semble.so) api — collaborative bookmarking and knowledge curation on [atproto](https://atproto.com).
4
5built on [httpx2](https://github.com/pydantic/httpx2) and [pydantic](https://docs.pydantic.dev), with sync and async clients.
6
7## installation
8
9```bash
10uv add semble-api
11```
12
13## quick start
14
15create an api key at [semble.so/settings/api-keys](https://semble.so/settings/api-keys), then:
16
17```python
18from semble import Semble
19
20client = Semble() # reads SEMBLE_API_KEY from the environment or a local .env
21
22# add a url to your library
23result = client.cards.add_url("https://example.com", note="worth a read")
24
25# search your cards
26for card in client.cards.search("durable execution"):
27 print(card.url)
28
29# semantic search across semble
30for hit in client.search.semantic("agent memory", threshold=0.7):
31 print(hit.metadata.title, hit.url)
32```
33
34async is the same surface:
35
36```python
37from semble import AsyncSemble
38
39async with AsyncSemble() as client:
40 profile = await client.actors.get_my_profile(include_stats=True)
41 feed = await client.feeds.get_following(limit=25)
42```
43
44## api surface
45
46resources mirror the `network.cosmik.*` xrpc namespaces:
47
48| namespace | what's there |
49| --------------------- | ------------------------------------------------------------------ |
50| `client.cards` | add/search/list urls and notes, metadata, library status |
51| `client.collections` | create/update/delete collections, followers, contributors |
52| `client.connections` | typed links between urls (supports, opposes, explains, ...) |
53| `client.feeds` | global and following activity feeds |
54| `client.notifications`| list, unread count, mark read |
55| `client.search` | semantic search, similar urls, account search |
56| `client.actors` | profiles |
57| `client.graph` | follow/unfollow users and collections |
58
59every endpoint not yet wrapped is reachable via the escape hatch:
60
61```python
62client.get("network.cosmik.card.getLibraryStatus", {"url": "https://example.com"})
63```
64
65`semble.records` has pydantic models for the raw `network.cosmik.*` pds records, if you're reading or writing them directly (e.g. with [pdsx](https://github.com/zzstoatzz/pdsx)).
66
67## configuration
68
69settings come from explicit kwargs, then `SEMBLE_*` environment variables, then a local `.env` file (via [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)):
70
71| setting | kwarg | default |
72| ----------------- | ---------- | ----------------------------- |
73| `SEMBLE_API_KEY` | `api_key` | unauthenticated (public reads work) |
74| `SEMBLE_BASE_URL` | `base_url` | `https://api.semble.so/xrpc` |
75| `SEMBLE_TIMEOUT` | `timeout` | `30.0` |
76
77the api key is held as a pydantic `SecretStr`, so it won't leak into logs or reprs.
78
79## cli
80
81a small [cyclopts](https://github.com/BrianPugh/cyclopts) cli ships as an extra:
82
83```bash
84uv add 'semble-api[cli]'
85# or run without installing
86uvx --from 'semble-api[cli]' semble --help
87
88semble whoami # auth sanity check
89semble feed 10 --following # activity feeds
90semble search "durable execution" # semantic search
91semble library pdewey.com # anyone's library (or yours, with no handle)
92semble add https://example.com --note "worth a read"
93semble rm <card-id>
94```
95
96output is machine-readable by default — lists are ndjson, single results are one json object, keys match the api's camelCase — so it pipes straight into jq or an agent. add `--pretty` to any command for human-formatted output:
97
98```bash
99semble feed 25 | jq -r '.card.url'
100semble search "agent memory" | jq -r '.metadata.title'
101semble feed --pretty
102```
103
104## mcp server
105
106the `mcp` extra ships a `semble-mcp` entry point that exposes this sdk to mcp clients via [fastmcp code mode](https://gofastmcp.com/servers/transforms/code-mode): three meta-tools (`search` / `get_schema` / `execute`) instead of one tool per endpoint, with model-written python composing sdk calls in a [monty](https://github.com/pydantic/monty) sandbox. intermediate results stay in the sandbox; only the final answer returns to the model's context.
107
108create an api key at [semble.so/settings/api-keys](https://semble.so/settings/api-keys), then:
109
110```bash
111claude mcp add semble -e SEMBLE_API_KEY=your-key -- uvx --from 'semble-api[mcp]' semble-mcp
112```
113
114for other mcp clients (claude desktop, cursor, ...), the equivalent json config:
115
116```json
117{
118 "mcpServers": {
119 "semble": {
120 "command": "uvx",
121 "args": ["--from", "semble-api[mcp]", "semble-mcp"],
122 "env": { "SEMBLE_API_KEY": "your-key" }
123 }
124 }
125}
126```
127
128the key is optional — without it the server is limited to public reads. the server also picks up `SEMBLE_API_KEY` from the environment or a `.env` in the working directory, so inside a checkout of this repo a plain `claude mcp add semble -- uv run --directory /path/to/this/repo semble-mcp` works too.
129
130hosted (http) deployments resolve auth per request instead: send your key as an `x-semble-api-key` header and it's used only for the calls that request triggers — one shared server url serves many users without holding anyone's identity. no header means public reads. a hosted instance runs at `https://semble.fastmcp.app/mcp`:
131
132```bash
133claude mcp add semble --transport http https://semble.fastmcp.app/mcp -H "x-semble-api-key: your-key"
134```
135
136`requirements.horizon.txt` exists for hosting platforms whose builders can't install extras from pyproject.toml.
137
138## examples
139
140`scripts/roundtrip.py` exercises the write paths end to end (add url → note → collection → cleanup). it mutates your real account, so run it deliberately:
141
142```bash
143uv run scripts/roundtrip.py
144```
145
146## development
147
148```bash
149just test # pytest
150just fmt # ruff format + check
151just check # ty
152```
153
154## see also
155
156- [semble for agents](docs/agent-surfaces.md) — choosing between the sdk, cli, and mcp surfaces when wiring up agents
157- [semble api docs](https://docs.cosmik.network/semble-api)
158- [@semble.so/api](https://npmx.dev/package/@semble.so/api) — official typescript client
159- [tangled.org/pdewey.com/semble](https://tangled.org/pdewey.com/semble) — go client