Skip to main content

Local agent harness: central skill library, Obsidian + SQLite FTS5 memory, background curator — served over MCP.

Project description

OyHub

A local, always-on agent harness that fixes skill sprawl and context exhaustion.

Engineers using AI assistants hit two walls: skills scattered across projects with nothing organized in one place, and context windows that fill up and forget everything between sessions. OyHub is an MCP server you install once on your machine — Claude Desktop, Claude Code, and Cursor connect to it and gain:

  • One central skill library with per-project activation. Skills live in ~/.oyhub/skills (agentskills.io-compatible SKILL.md format). Activate a project and only its relevant skills appear — your Kubernetes skills stay out of your React sessions.
  • Persistent memory that survives any context window. Curated facts go to your Obsidian vault as plain markdown (human-readable, editable, graph-linked). Full conversation history goes to SQLite + FTS5 — full-text searchable recall at zero LLM cost. Instead of context running out, the assistant retrieves the five messages that matter.
  • Loop engineering in the background. A curator loop runs on idle: archives stale skills (never deletes — archive is recoverable), dedupes memory entries, pins protect anything you care about, and every action is logged to a Curator Log.md note in your vault so the loop's work stays visible.
  • Injection-scanned writes. Memory and skills persist into every future session's context, so anything flowing into them is scanned at write time — instruction-override phrasing and credential-exfil link shapes are refused with a reason. Legitimate engineering content (curl commands, env var names) passes.
  • Safe under concurrent clients. Multiple assistants can run OyHub against the same state simultaneously: SQLite runs in WAL mode with busy timeouts, and all shared JSON/markdown writes go through file-locked atomic read-modify-write.
  • Web dashboard + REST API. oyhub dashboard serves a local FastAPI app: skill usage stats, memory browser, full-text session search, curator log — plus a JSON API for scripting against your hub.
  • Observability built in. Every tool call is recorded (tool, latency, status) in the shared SQLite DB; the dashboard exposes a Prometheus /metrics endpoint, and docker compose --profile observability up starts a provisioned Grafana with a ready-made OyHub dashboard (call rates, latencies, error rates).
  • CI/CD + Docker from day one. GitHub Actions runs lint + tests on a 6-way OS/Python matrix, builds the Docker image, cuts a GitHub release on every version tag, and publishes to PyPI via trusted publishing.

Zero runtime dependencies — Python stdlib only. No API key: the connected assistant is the intelligence; OyHub is the harness.

Install

git clone https://github.com/Asanovichoff/oyhub && cd oyhub
python3 -m oyhub doctor   # health check

Set where memory lives (your existing Obsidian vault):

export OYHUB_VAULT=~/Documents/MyVault

Connect Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "oyhub": {
      "command": "python3",
      "args": ["-m", "oyhub"],
      "env": {
        "PYTHONPATH": "/path/to/oyhub",
        "OYHUB_VAULT": "/Users/you/Documents/MyVault"
      }
    }
  }
}

Note: Claude Desktop ignores a cwd field — PYTHONPATH is what makes python3 -m oyhub importable. Alternatively, pip3 install -e /path/to/oyhub once, then use "command": "oyhub" with no args or PYTHONPATH.

Connect Claude Code

claude mcp add oyhub --env PYTHONPATH=/path/to/oyhub --env OYHUB_VAULT=~/Documents/MyVault -- python3 -m oyhub

Or after pip3 install -e /path/to/oyhub: claude mcp add oyhub -- oyhub

Docker

docker compose run --rm oyhub          # stdio MCP server
docker compose run --rm --entrypoint python oyhub -m oyhub doctor

Dashboard & observability

pip install "oyhub[dashboard]"
oyhub dashboard                        # web UI + API at http://127.0.0.1:8400

Full observability stack (dashboard + Prometheus + Grafana, pre-provisioned):

docker compose --profile observability up
# dashboard http://localhost:8400 · prometheus http://localhost:9090 · grafana http://localhost:3000

The core MCP server stays dependency-free — FastAPI/uvicorn are an optional extra used only by the dashboard process.

The tools it exposes

Tool What it does
project_activate Scope skills + memory to a project (creates profile if new)
skill_add / skill_view / skill_list / skill_search Central library; list shows the compact index (60-char descriptions), bodies load on demand
memory_add / memory_snapshot Curated memory in your Obsidian vault, project-scoped or global
session_log / session_search / session_recent FTS5-indexed history: log important turns, search them later with context windows
curator_run / curator_pin Run maintenance now; pin skills the curator must never touch

A typical day

  1. Start a session: Claude calls project_activate("webapp") and memory_snapshot — it now knows your conventions and this project's facts, without you repeating them.
  2. Work normally. When something worth keeping comes up, Claude calls memory_add ("staging DB is read-only") or skill_add (a deploy procedure it just worked out).
  3. Next week, in a fresh session: "how did we fix that CORS issue?" → session_search("CORS") returns the exact exchange. Nothing was lost when the old context window died.
  4. Meanwhile the curator has deduped memory and archived skills untouched for 90 days — check Curator Log.md in Obsidian to see what it did.

Architecture

Claude / Cursor  ──MCP (stdio JSON-RPC)──►  oyhub/server.py
                                              │
                    ┌─────────────────────────┼─────────────────────┐
                    ▼                         ▼                     ▼
             skills.py                 memory.py               curator.py
      central library + index    Obsidian vault (curated)   idle-triggered loop:
      per-project activation     SQLite FTS5 (raw recall)   archive stale, dedupe,
      usage tracking             frozen-snapshot reads      log actions to vault

Design lineage: the frozen-snapshot memory, 60-char skill index, archive-never-delete curator, and idle-triggered maintenance are patterns from Hermes Agent (Nous Research, MIT), adapted for a keyless MCP harness.

Development

pip install -e ".[dev]"
ruff check oyhub tests && pytest tests/ -q   # what CI runs

25 tests, all offline — including concurrency tests (parallel writers, no lost updates), injection-guard tests, and dashboard API tests. CI matrix: Ubuntu + macOS × Python 3.10–3.12, plus a Docker build + smoke test. Tag v* to cut a GitHub release and publish to PyPI (trusted publishing — configure once under PyPI → Publishing).

Roadmap

  • LLM-assisted curation (summarize/consolidate memory notes, improve skill descriptions)
  • Skill import from agentskills.io and Claude skill bundles
  • Session auto-logging middleware
  • Vector search as an optional complement to FTS5

MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oyhub-0.3.0.tar.gz (28.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oyhub-0.3.0-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

File details

Details for the file oyhub-0.3.0.tar.gz.

File metadata

  • Download URL: oyhub-0.3.0.tar.gz
  • Upload date:
  • Size: 28.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oyhub-0.3.0.tar.gz
Algorithm Hash digest
SHA256 ddc3cbe3743cc4920a47d41300e6de0f56798705b4fa4e85f900826950943a2a
MD5 bac77338d8c69e497b9184a297161f36
BLAKE2b-256 c15ea2fd0f234585ddc6ee7e74aa834602c74c59e2f13bc1258b33bfa6e089b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for oyhub-0.3.0.tar.gz:

Publisher: ci.yml on Asanovichoff/oyhub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oyhub-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: oyhub-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 25.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oyhub-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5295b1b0a3159439bd005b7f199a85107d7db2ffac37c44c658f16da9fac2293
MD5 947df46ff2daafdcb1c0c51378babb67
BLAKE2b-256 7d5fa50971a5c1dd3f7308750fa71145b5b8cf5c903ef58abeec79f758fe7fb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for oyhub-0.3.0-py3-none-any.whl:

Publisher: ci.yml on Asanovichoff/oyhub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page