Fast Embedding MCP SSE
<img width="3534" height="1625" alt="sse_v2" src="https://github.com/user-attachments/assets/38da5650-14fe-41a3-8a9b-3b1f3884a945" />
# Fast Embedding MCP / SSE — Stable Static Embedding server
Serve [`RikkaBotan/stable-static-embedding-fast-retrieval-mrl-en-v2`](https://huggingface.co/RikkaBotan/stable-static-embedding-fast-retrieval-mrl-en-v2)
over an **OpenAI-compatible HTTP API** and an **MCP server (stdio)**.
The model is a ~16M-parameter English static embedding model: **512D** native
with Matryoshka (MRL) truncation to **256 / 128 / 64 / 32**. It is fast (no
attention) and tiny.
## Install
This project uses [uv](https://docs.astral.sh/uv/) for environment management.
Install uv first if you don't have it
([instructions](https://docs.astral.sh/uv/getting-started/installation/)):
```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
```
```powershell
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
Then clone and sync. `uv sync` creates a `.venv`, installs the pinned
dependencies from `uv.lock`, and installs the project itself:
```bash
git clone https://github.com/Rikka-Botan/Fast-Embedding-MCP-SSE.git
cd Fast-Embedding-MCP-SSE
uv sync
```
uv picks a compatible Python (3.10+) automatically — no manual venv or
activation needed; prefix commands with `uv run`. The first server run
downloads the model from Hugging Face (~60 MB) and caches it.
## HTTP API
```bash
uv run python -m sse_embedding.api # serves on http://0.0.0.0:8000
# or, equivalently: uv run sse-api
```
Configurable via `SSE_API_HOST` / `SSE_API_PORT`.
### Endpoints
| Method | Path | Purpose |
|--------|-------------------|----------------------------------------------------|
| POST | `/v1/embeddings` | OpenAI-compatible embeddings (supports `dimensions`)|
| POST | `/similarity` | Cosine similarity matrix between two text sets |
| POST | `/search` | Rank documents against a query (stateless) |
| POST | `/index/add` | Add documents to the in-memory index |
| POST | `/index/query` | Query the in-memory index |
| GET | `/index/stats` | Index size |
| POST | `/index/clear` | Empty the index |
| GET | `/health` | Health check |
#### OpenAI-compatible example
Works with the OpenAI SDK by pointing `base_url` at this server:
```python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")
resp = client.embeddings.create(
model="RikkaBotan/stable-static-embedding-fast-retrieval-mrl-en-v2",
input=["hello world", "good morning"],
dimensions=256, # MRL truncation: 512/256/128/64/32
)
print(len(resp.data[0].embedding)) # 256
```
Or raw:
```bash
curl -X POST http://localhost:8000/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"input": "hello world", "dimensions": 128}'
```
#### Search / index example
```bash
curl -X POST http://localhost:8000/index/add \
-H "Content-Type: application/json" \
-d '{"documents": ["The cat sat on the mat", "Paris is in France"]}'
curl -X POST http://localhost:8000/index/query \
-H "Content-Type: application/json" \
-d '{"query": "Where is Paris?", "top_k": 1}'
```
## MCP server (stdio)
```bash
uv run python -m sse_embedding.mcp_server
# or, equivalently: uv run sse-mcp
```
Tools exposed: `embed_text`, `similarity`, `search`, `index_add`,
`index_query`, `index_stats`, `index_clear`.
### Register with Claude Code
> Requires the [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code).
> If `claude` is not a recognized command, you are likely using the Claude
> Desktop app — use the [Claude Desktop](#register-with-claude-desktop) config
> below instead.
Run from the cloned project directory:
```bash
claude mcp add sse-embedding -- uv run python -m sse_embedding.mcp_server
```
To make the registration work from any directory, pass the project path to uv
with `--directory`:
```bash
claude mcp add sse-embedding -- uv run --directory /path/to/Fast-Embedding-MCP-SSE python -m sse_embedding.mcp_server
```
### Register with Claude Desktop
Add to `claude_desktop_config.json`, replacing `/path/to/...` with the
absolute path where you cloned this repository. `uv run` resolves the project's
environment from the given directory.
**macOS / Linux:**
```json
{
"mcpServers": {
"sse-embedding": {
"command": "uv",
"args": ["run", "--directory", "/path/to/Fast-Embedding-MCP-SSE", "python", "-m", "sse_embedding.mcp_server"]
}
}
}
```
**Windows:**
```json
{
"mcpServers": {
"sse-embedding": {
"command": "uv",
"args": ["run", "--directory", "C:\\path\\to\\Fast-Embedding-MCP-SSE", "python", "-m", "sse_embedding.mcp_server"]
}
}
}
```
If Claude Desktop reports that `uv` was not found, replace `"command": "uv"`
with the absolute path to the uv executable (`which uv` on macOS/Linux,
`(Get-Command uv).Source` in PowerShell), or point `command` directly at the
`.venv` interpreter that `uv sync` created
(`/path/to/Fast-Embedding-MCP-SSE/.venv/bin/python`, or on Windows
`C:\\path\\to\\Fast-Embedding-MCP-SSE\\.venv\\Scripts\\python.exe`) with
`"args": ["-m", "sse_embedding.mcp_server"]`.
## Matryoshka dimensions
Valid `dim` / `dimensions` values are **512, 256, 128, 64, 32**. Smaller
dimensions are faster and smaller with graceful quality degradation.
Truncation is applied to the full 512D vector and the result is renormalized,
so cosine similarity stays valid at any level.
## License
Apache-2.0
TDQS
Scored across 7 tools
Each tool serves a distinct function: embedding, similarity computation, stateless search, and index management. The index_* tools are clearly separated from stateless operations, and search vs index_query are differentiated by whether a persistent index is used.
Naming mixes styles: embed_text uses verb_noun, index_add uses noun_verb, and similarity/index_stats are nouns. While the index_ prefix provides consistency for index operations, the overall pattern is inconsistent.
7 tools is well-scoped for an embedding server, covering core operations without redundancy. Each tool earns its place, and the count is within the ideal range.
Core workflows are covered: text embedding, similarity scoring, stateless search, and a persistent index with add/query/clear. Missing per-document delete/update or retrieval by ID are minor gaps that don't break typical usage.