semble-api
python client for the semble api — collaborative bookmarking and knowledge curation on atproto.
built on httpx2 and pydantic, with sync and async clients.
installation
uv add semble-api
quick start
create an api key at semble.so/settings/api-keys, then:
from semble import Semble
client = Semble() # reads SEMBLE_API_KEY from the environment or a local .env
# add a url to your library
result = client.cards.add_url("https://example.com", note="worth a read")
# search your cards
for card in client.cards.search("durable execution"):
print(card.url)
# semantic search across semble
for hit in client.search.semantic("agent memory", threshold=0.7):
print(hit.metadata.title, hit.url)
async is the same surface:
from semble import AsyncSemble
async with AsyncSemble() as client:
profile = await client.actors.get_my_profile(include_stats=True)
feed = await client.feeds.get_following(limit=25)
api surface
resources mirror the network.cosmik.* xrpc namespaces:
| namespace | what's there |
|---|---|
client.cards |
add/search/list urls and notes, metadata, library status |
client.collections |
create/update/delete collections, followers, contributors |
client.connections |
typed links between urls (supports, opposes, explains, ...) |
client.feeds |
global and following activity feeds |
client.notifications |
list, unread count, mark read |
client.search |
semantic search, similar urls, account search |
client.actors |
profiles |
client.graph |
follow/unfollow users and collections |
every endpoint not yet wrapped is reachable via the escape hatch:
client.get("network.cosmik.card.getLibraryStatus", {"url": "https://example.com"})
semble.records has pydantic models for the raw network.cosmik.* pds records, if you're reading or writing them directly (e.g. with pdsx).
configuration
settings come from explicit kwargs, then SEMBLE_* environment variables, then a local .env file (via pydantic-settings):
| setting | kwarg | default |
|---|---|---|
SEMBLE_API_KEY |
api_key |
unauthenticated (public reads work) |
SEMBLE_BASE_URL |
base_url |
https://api.semble.so/xrpc |
SEMBLE_TIMEOUT |
timeout |
30.0 |
the api key is held as a pydantic SecretStr, so it won't leak into logs or reprs.
cli
a small cyclopts cli ships as an extra:
uv add 'semble-api[cli]'
# or run without installing
uvx --from 'semble-api[cli]' semble --help
semble whoami # auth sanity check
semble feed 10 --following # activity feeds
semble search "durable execution" # semantic search
semble library pdewey.com # anyone's library (or yours, with no handle)
semble add https://example.com --note "worth a read"
semble rm <card-id>
output 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:
semble feed 25 | jq -r '.card.url'
semble search "agent memory" | jq -r '.metadata.title'
semble feed --pretty
mcp server
the mcp extra ships a semble-mcp entry point that exposes this sdk to mcp clients via fastmcp 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 sandbox. intermediate results stay in the sandbox; only the final answer returns to the model's context.
create an api key at semble.so/settings/api-keys, then:
claude mcp add semble -e SEMBLE_API_KEY=your-key -- uvx --from 'semble-api[mcp]' semble-mcp
for other mcp clients (claude desktop, cursor, ...), the equivalent json config:
{
"mcpServers": {
"semble": {
"command": "uvx",
"args": ["--from", "semble-api[mcp]", "semble-mcp"],
"env": { "SEMBLE_API_KEY": "your-key" }
}
}
}
the 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.
examples
scripts/roundtrip.py exercises the write paths end to end (add url → note → collection → cleanup). it mutates your real account, so run it deliberately:
uv run scripts/roundtrip.py
development
just test # pytest
just fmt # ruff format + check
just check # ty
see also
- semble for agents — choosing between the sdk, cli, and mcp surfaces when wiring up agents
- semble api docs
- @semble.so/api — official typescript client
- tangled.org/pdewey.com/semble — go client
Metadata
Release files for semble-api 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| semble_api-0.0.2.tar.gz | 95.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| semble_api-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 117.4 kB
Release files / semble_api-0.0.2.tar.gz
| Download URL | semble_api-0.0.2.tar.gz |
|---|---|
| Size | 95.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04d2db59965dcb1454c9780920cbb2f286fd78240b1820d5829e9192a1c6dfbf
|
|
BLAKE2b-256 checksum How to use checksums |
96cd4ca97c8b82f7c7282414b95a718747a4d4722ba5a9c117efb7e9a14865a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / semble_api-0.0.2-py3-none-any.whl
| Download URL | semble_api-0.0.2-py3-none-any.whl |
|---|---|
| Size | 21.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7b27b9a6e849b819104c3a9cac93d822ed9d551b13c62444a841f487cb0ce2a9
|
|
BLAKE2b-256 checksum How to use checksums |
d382dc0db6032ec084f8767305072d798c1f12fd7de85159de89d0d7b70f87fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|