A binary-safe Python client for the Obsidian Local REST API, shaped for building and maintaining Karpathy-style LLM research wikis inside an Obsidian vault.
Ships with a bundled Claude Code skill (ccobsr-research) that teaches Claude how to bootstrap research topics, capture sources, compile a wiki, query it, and file outputs back in — all via this CLI, with the Obsidian vault as the single source of truth.
- Python 3.14+
- uv
- Obsidian with the Local REST API community plugin enabled
- Claude Code CLI (
claude) — for the bundled skill
uv tool install . --python 3.14Or from GitHub:
uv tool install "ccobsr @ git+https://github.com/monkut/ccobsr-research-cli" --python 3.14Or run directly with uvx:
uvx --from . --python 3.14 ccobsr --helpccobsr talks to Obsidian through the community plugin Local REST API by Adam Coddington. The plugin runs inside Obsidian and exposes the vault over HTTP(S) on localhost. Obsidian must be open with your target vault loaded for ccobsr to reach it.
- Open Obsidian → Settings → Community plugins.
- If Restricted mode is on, click Turn off restricted mode (community plugins are opt-in).
- Click Browse, search for
Local REST API, select the plugin by Adam Coddington, and click Install. - After install, click Enable (or toggle it on in the installed plugins list).
- Still in Settings, scroll the left sidebar down to Community plugins → Local REST API (plugin options).
- Copy the API Key shown at the top of the plugin settings panel. Treat this like a password — anything with the key can read and write your vault.
- Note the HTTPS and HTTP port numbers. Defaults are:
- HTTPS:
https://127.0.0.1:27124(self-signed cert, recommended) - HTTP:
http://127.0.0.1:27123(off by default; enable only if you need it for a specific client)
- HTTPS:
The plugin generates a self-signed TLS cert on first run so traffic between ccobsr and Obsidian is encrypted even on localhost. Because the cert isn't signed by a public CA, most clients (curl, Python, browsers) refuse it by default.
ccobsr defaults to not verifying the cert (CCOBSR_VERIFY_SSL=false) since the endpoint is bound to 127.0.0.1. If you want strict verification:
- In the plugin settings, click Download certificate and save the
.crtfile. - Trust it at the OS level (e.g.
sudo trust anchor obsidian-local-rest-api.crton Fedora, or add it to your system keychain on macOS). - Export
CCOBSR_VERIFY_SSL=true.
Add these to your shell profile (~/.bashrc, ~/.zshrc, etc.):
export OBSIDIAN_API_URL="https://127.0.0.1:27124"
export OBSIDIAN_API_KEY="<paste the API key from the plugin settings>"Reload your shell (exec $SHELL) or source the profile.
With Obsidian running and your vault open:
ccobsr lsYou should see the top-level folders of your vault listed, one per line. If you get Could not reach Obsidian Local REST API..., Obsidian is not running or the plugin is disabled. If you get HTTP 401, your OBSIDIAN_API_KEY is wrong or not exported into the current shell.
Set these environment variables (e.g. in your shell profile):
export OBSIDIAN_API_URL="https://127.0.0.1:27124" # default
export OBSIDIAN_API_KEY="<key from the Obsidian Local REST API plugin settings>"Optional:
| Variable | Default | Description |
|---|---|---|
CCOBSR_VERIFY_SSL |
false |
Verify the self-signed cert on the local API. Default off. |
CCOBSR_REQUEST_TIMEOUT |
30 |
Request timeout in seconds. |
CCOBSR_RESEARCH_ROOT |
Research |
Vault folder prefix for research topics. |
CCOBSR_HOME |
~/.ccobsr |
Local config/log directory. |
LOG_LEVEL |
INFO |
Logging verbosity. |
ccobsr <command> [options]
| Command | Description |
|---|---|
bootstrap <topic> |
Create Research/<topic>/ with the full folder skeleton + seeded README, index, log, manifest, taxonomy |
capture <topic> <file> --kind {articles,papers,images,datasets,transcripts,repos,clips} |
Upload a source file into _raw/ and append a row to manifest.md |
log <topic> "<message>" |
Append a JST-stamped entry to log.md |
ls [path] |
List a vault folder |
get <path> [-o FILE] [--note-json] |
Download a file (binary-safe) |
put <path> --file FILE / --content TEXT |
Upload bytes or literal content |
append <path> --content TEXT / --file FILE |
Append markdown content to a file |
delete <path> |
Delete a vault file |
search text <query> |
Full-text search |
search jsonlogic '<expr>' |
Frontmatter search via JsonLogic |
install [--directory DIR] |
Install bundled skills to ~/.claude/skills |
Canonical Karpathy-style loop. See the bundled skill at ccobsr/skills/ccobsr-research/SKILL.md for the full method.
# 1. Bootstrap a topic
ccobsr bootstrap llm-agent-memory
# 2. Capture a primary source
ccobsr capture llm-agent-memory ~/Downloads/mem-gpt.pdf --kind papers --slug packer-2023-memgpt
# 3. (LLM) read the file, compile a sources/ page + claims/ pages
ccobsr get "Research/llm-agent-memory/_raw/papers/packer-2023-memgpt.pdf" -o /tmp/mem.pdf
ccobsr put "Research/llm-agent-memory/sources/packer-2023-memgpt.md" --content "---
type: source
...
---
## Summary
..."
# 4. Log it
ccobsr log llm-agent-memory "compiled [[sources/packer-2023-memgpt]]: +3 claims, +1 concept"
# 5. Query later
ccobsr search jsonlogic '{"and":[
{"==":[{"var":"frontmatter.type"},"claim"]},
{">=":[{"var":"frontmatter.verifiability"},3]}
]}'PDFs, images, and datasets all work — the Obsidian Local REST API accepts */* on PUT, and ccobsr guesses the Content-Type from the file extension. Round-trip byte-identity is verified by the tests.
ccobsr put "Research/topic/_raw/images/diagram.png" --file ./diagram.png
ccobsr get "Research/topic/_raw/images/diagram.png" -o /tmp/roundtrip.pngccobsr installCopies the skill to ~/.claude/skills/ccobsr-research/, where Claude Code auto-discovers it. The skill encodes:
- Evidence-first methodology — primary sources preferred,
verifiabilityandpopularityrequired on every source/claim - WORM
_raw/rule — never re-write a captured source - Evidence precedes synthesis —
sources/must exist beforeclaims/;claims/must exist beforesynthesis/ - JST timestamps everywhere
- Single source of truth — the Obsidian vault; no filesystem sidecar
ccobsr/
__init__.py # Package version
cli.py # argparse entry point and handlers
definitions.py # MIME map, CaptureKind enum, bootstrap templates
functions.py # REST API client + research workflow helpers
settings.py # env vars and logging
skills/
ccobsr-research/
SKILL.md # the bundled skill definition
tests/
test_ccobsr.py # unit tests (url build, hash, guessing)
pyproject.toml
LICENSE
README.md
pre-commit install
uv sync
uv run poe check # ruff
uv run poe typecheck # pyright
uv run poe test # pytest- askcc-cli — sibling one-shot Claude Code CLI executor;
ccobsrborrows its packaging and skill-install layout. - Obsidian Local REST API — the upstream plugin.
- Karpathy's "LLM Knowledge Bases" — the pattern this tool implements.