mcp server
hull
hull is the shared monorepo core for the wet, crg and mnemo self-hosted stack
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
{
"mcpServers": {
"hull": {
"command": "uvx",
"args": [
"n24q02m-hull"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 21, 2026hull — shared core for the wet / crg / mnemo self-hosted stack
hull is the shared monorepo core for the wet, crg and mnemo self-hosted stack.
It owns everything the three products share — token auth, per-task model configuration, per-user rate limiting, local SQLite storage, the HTTP MCP server lifecycle, web scraping/search infrastructure, and a local embedding daemon — for wet (search), crg (code graph) and mnemo (memory).
Install
hull ships as one PyPI dist, n24q02m-hull. The wheel carries all three
import packages; the heavy stacks are opt-in extras:
pip install n24q02m-hull # hull_core only (crg, mnemo)
pip install "n24q02m-hull[web]" # + hull_web scraping/browser stack (wet)
pip install "n24q02m-hull[embedding]" # + hull_embedding_daemon server stack
pip install "n24q02m-hull[mteb]" # + pyarrow for model_selection MTEB fetchers
pip install "n24q02m-hull[embedding,embedding-gguf]" # + llama.cpp runtime for *-GGUF models
import hull_web without the [web] extra raises ImportError naming the
missing modules and the install command.
The TypeScript core ships to npm as @n24q02m/hull, at the same version as
the PyPI dist (see packages/core-ts):
npm install @n24q02m/hull
Packages
| Source dir | Import package | Extra | Purpose |
|---|---|---|---|
packages/core-py | hull_core | (base; MTEB boards need [mteb]) | Auth (3 modes), per-task model cells, limiter, ~/.hull/ SQLite WAL storage, server start + /mcp endpoint, CLI, SSRF-safe HTTP, lifecycle lock, model_selection leaderboard picker + runtime registry (refresh → eval-on-change → promote) |
packages/embedding-daemon | hull_embedding_daemon | [embedding] | Local ONNX/GGUF embedding server (FastAPI) |
packages/web | hull_web | [web] | Search (SearXNG), scraping strategies, stealth browsers, fingerprinting, HTTP/SSRF security |
packages/core-ts | @n24q02m/hull (npm) | n/a | TypeScript core: MCP Streamable HTTP transport, OAuth 2.1 authorization server, credential storage, relay client |
Runtime model
- Python 3.13. Dev with
uv, always-on with docker. hull server startis the only way to run a server; MCP is an HTTP endpoint athttp://host:port/mcp— never a spawned subprocess.- The CLI is the control plane + consumer. With the server down the CLI tells you to start it first; there is no hidden local-core mode.
- Provider calls are plain OpenAI-spec HTTP (
httpx). OpenRouter is the pre-wired default. Each task (embed,rerank,chat,jev_score) has its ownbase_url + api_key + modelcell — change provider by editing config, never code. - Storage is local SQLite (WAL) under
~/.hull/. Backup/sync isrcloneoutside this repo.
Auth — one mechanism, three modes
Mode is a config state ([server] auth in ~/.hull/config.toml):
no-auth— localhost-only bind enforced, one shared namespace.token— one shared token (token_hashin config), still one shared namespace.multi—users.tomlmapsuid → {token_hash, enabled, namespace, allowed_roots, limits}; one process serves N users, each isolated to their namespace. Admin is host-side only: editusers.toml, restart.
Token hashes are scrypt (hull token hash). Wrong token → 401; disabled
user → 403; over-limit → 429.
Quick start
uv sync
uv run hull config init # write ~/.hull/config.toml (OpenRouter defaults)
uv run hull token hash mysecret # mint a token_hash for users.toml / config
uv run hull server start # serves http://127.0.0.1:8000/mcp
Development
uv sync --all-extras
uv run pytest -q
uv run ruff check .
uv build
License
Apache-2.0