Skip to main content

Local-first embedding server: vector generation + index/search over HTTP (ONNX on-device or API providers). The reference /embed server for CPersona.

Project description

CEmbedding

Local-first embedding server

Vector embeddings over a tiny HTTP contract. On-device ONNX or any OpenAI-compatible API. The reference /embed server for CPersona.

License: MIT Python


Standalone repository — extracted from the (now private) clotohub-servers monorepo so it can be used on its own. ClotoCore users get this through the in-app marketplace (ClotoHub); everyone else can run it directly as described below.

What it is

A small server that turns text into vectors. It speaks a minimal HTTP contract so anything can call it — its primary consumer is CPersona, whose hybrid search uses it for the vector-similarity layer. It can run a model on-device via ONNX (no API key, no network) or proxy an OpenAI-compatible API.

It also exposes an MCP (stdio) surface and an optional persistent vector index (/index, /search), but the HTTP /embed endpoint is all CPersona needs.

The /embed contract

POST /embed
Request:  { "texts": ["string", ...] }                 # non-empty array, max 100 per batch
Response: { "embeddings": [[float, ...], ...], "dimensions": <int> }

Point any client (e.g. CPersona's CPERSONA_EMBEDDING_URL / generic EMBEDDING_HTTP_URL) at http://127.0.0.1:8401/embed.

Quick Start (on-device ONNX)

Prerequisites: Python 3.10+

# Download a model into ./data/models (jina-v5-nano is what CPersona is tuned for)
uvx --from "cembedding[onnx]" cembedding-download-model --model jina-v5-nano

# Run the server (reads ./data/models from the current directory)
EMBEDDING_PROVIDER=onnx_jina_v5_nano uvx --from "cembedding[onnx]" cembedding

Or install it onto your PATH with pip install "cembedding[onnx]", then run cembedding-download-model --model jina-v5-nano and cembedding.

From source (development):

git clone https://github.com/Cloto-dev/CEmbedding.git
cd CEmbedding
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install ".[onnx]"
python -m cembedding.download_model --model jina-v5-nano
EMBEDDING_PROVIDER=onnx_jina_v5_nano python -m cembedding   # or: python server.py

You should see HTTP embedding endpoint started on http://127.0.0.1:8401/embed. Verify it:

curl -s http://127.0.0.1:8401/embed \
  -H 'content-type: application/json' \
  -d '{"texts":["hello world"]}' | head -c 200

Providers

Set EMBEDDING_PROVIDER:

Value Model Notes
onnx_jina_v5_nano jina-v5-nano (33M, 768d) Local CPU, what CPersona is benchmarked against
onnx_bge_m3 bge-m3 Local CPU, larger / multilingual
onnx_miniml all-MiniLM-L6-v2 (22M, 384d) Local CPU, smallest
mlx_bge_m3 bge-m3 (MLX) Apple Silicon only — pip install ".[mlx]"
api_openai provider's model OpenAI-compatible API; needs EMBEDDING_API_KEY (+ optional EMBEDDING_API_URL, EMBEDDING_MODEL)

Download a local model with cembedding-download-model --model {miniml,jina-v5-nano,bge-m3} (or python -m cembedding.download_model ... from a source checkout; fetched from HuggingFace into ./data/models, not committed to this repo).

Configuration

Env var Default Description
EMBEDDING_PROVIDER api_openai Provider (see table above)
EMBEDDING_HTTP_PORT 8401 HTTP port for /embed
EMBEDDING_INDEX_ENABLED true Enable the persistent vector index endpoints (/index, /search, /remove, /purge)
EMBEDDING_INDEX_DB_PATH data/embedding_index.db SQLite file backing the vector index
EMBEDDING_SEARCH_BACKEND numpy /search matmul backend. numpy (Accelerate BLAS) or mlx (Apple-GPU resident matrix; falls back to numpy when mlx is absent)
ONNX_MODEL_DIR (auto) Override the model directory for ONNX providers
ONNX_EP_PREFERENCE (auto) ONNX execution providers, comma-separated. Empty = auto (CoreML on macOS, DirectML on Windows, else CPU; CPU always ensured)
ONNX_MAX_SEQ_LEN 2048 Max tokenization length (1–8192; MiniLM clamped to 512 internally)
EMBEDDING_API_KEY Required for api_openai
EMBEDDING_API_URL https://api.openai.com/v1/embeddings API endpoint for api_openai

Use with CPersona

Run this server, then tell CPersona to use it:

# CPersona MCP config env
CPERSONA_EMBEDDING_MODE=http
CPERSONA_EMBEDDING_URL=http://127.0.0.1:8401/embed

Without an embedding server CPersona still works (FTS5 + keyword search); adding one enables the vector-similarity layer.

To serve CPersona's remote vector search (CPERSONA_VECTOR_SEARCH_MODE=remote), this server's /index + /search endpoints hold the vectors. v0.6.0 searches a per-namespace resident matrix (one matmul per query, ~21x faster than v0.5.0 at 237k x 384: 131 ms -> 6 ms/query), so a full-corpus semantic recall stays fast at memory-corpus scale. When flipping an existing CPersona deployment to remote mode, first migrate its already-stored vectors:

python scripts/backfill_embedding_index.py \
    --cpersona-db ~/.claude/cpersona.db \
    --index-db data/embedding_index.db \
    --expect-dim 768   # your embedding model's dimension

then restart this server so it reloads the index. Skipping the backfill silently drops every pre-flip memory from semantic recall (the remote branch only falls back to local search on HTTP errors, not on empty results).

License

MIT — see 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

cembedding-0.6.1.tar.gz (31.3 kB view details)

Uploaded Source

Built Distribution

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

cembedding-0.6.1-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file cembedding-0.6.1.tar.gz.

File metadata

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

File hashes

Hashes for cembedding-0.6.1.tar.gz
Algorithm Hash digest
SHA256 d127585321d28e450d3cd5d95776c7708c7b9e137cb59698810061ce29b45102
MD5 9a941f4494239864389ebbc3da78cf2f
BLAKE2b-256 1175643a6d91f2ed4a527c3978ab8f346594d523326f0c69085da1ff38d0f106

See more details on using hashes here.

Provenance

The following attestation bundles were made for cembedding-0.6.1.tar.gz:

Publisher: publish.yml on Cloto-dev/CEmbedding

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

File details

Details for the file cembedding-0.6.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for cembedding-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2d8923e8eb54e502956cb7f5f41f29452193ca3ed2be817a9377e2241b599ce1
MD5 1b887d8851d1e8a75937fbd072e66966
BLAKE2b-256 60e78abd52385677e7918884f212de4bd0f0ab5978341f559e7c53602a61df93

See more details on using hashes here.

Provenance

The following attestation bundles were made for cembedding-0.6.1-py3-none-any.whl:

Publisher: publish.yml on Cloto-dev/CEmbedding

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