mcp-local-semantics
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-local-semanticssearch my meeting notes for anything about budget cuts and rank by relevance"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
๐ง MCP Local Semantics
Four embedding tools an agent can call in a loop, because they cost nothing.
An MCP server that runs a sentence encoder on the machine the agent is already on. Search by meaning, compare texts, cluster them, classify against labels you supply per call โ no embedding API, no key, no network, no per-invocation bill.
The interesting part is not that a local model works. It is that a stateless tool re-embeds its whole corpus on every call, which made the first version 1,040 ms per search. Caching the embeddings took it to 1.2 ms.
๐ง The MCP surface: src/mcp_local_semantics/server.py
๐งฎ The maths, pure NumPy: src/mcp_local_semantics/semantics.py
๐ Related write-up: An MCP server is one Next.js route handler
Measured on CPU
1,000 documents ยท ~18,000 tokens ยท all-MiniLM-L6-v2 ยท no GPU
model load (once, lazily) | 20.99 s |
encode 1,000 documents | 5.58 s โ 179 docs/s, 3,265 tok/s |
| 1040.4 ms |
| 1.2 ms |
speed-up | 893ร (95.2% hit rate) |
same call via | 16.4 ms |
Reproduce with python scripts/bench.py.
The 893ร is the whole design problem
An MCP tool is stateless. The documents arrive as an argument, on every call. So the obvious implementation embeds all 200 of them every time the agent asks a question โ and the realistic agent pattern is one corpus and many questions.
# LocalEncoder.encode โ keyed on the exact string.
missing = [t for t in dict.fromkeys(texts) if t not in self._cache]Embeddings are deterministic for a given model, so a cache hit is not an approximation โ it is the same vector. The cache is bounded and least-recently-used, because an unbounded one is a slow leak in a long-lived server that an agent keeps feeding new text to.
This is the same shape as putting a cache breakpoint on an agent loop's stable prefix: the expensive part of the call is the part that did not change.
On the cost comparison
Embedding those 18,000 tokens against a hosted API at list price would cost about $0.0004. That is nothing, and quoting it as the headline would be dishonest.
The number that matters is the other one. An agent will call a free, instant tool inside a loop. It will not call one that bills per invocation and waits on a network โ and neither will you, when you are deciding whether to let it. Local moves semantic search from a resource to be rationed into an operation the agent can use freely.
The API figure above is computed from published list price and labelled as computed everywhere it appears. It was not measured.
Related MCP server: ClawMem MCP Server
The tools
tool | what it is for |
| rank documents by how well each answers a question, by meaning rather than shared words |
| pairwise similarity, plus the closest and furthest pair โ duplicate detection, odd-one-out |
| group texts by topic without being told the topics |
| assign the best label from a list you supply in the call โ no training, no fixed label set |
The descriptions are the interesting part
A vague tool description means the model never selects the tool at all. Each description here names the situations it applies to, not what the function does:
Rank a list of documents by how well each answers a question, using meaning rather than shared keywords. Use this whenever you have a pile of text and a question about it: finding the relevant passage in notes, picking which of several answers fits, or narrowing a long list before reading it. Runs locally, so it is free to call and safe to call repeatedly.
That last sentence is doing real work. It tells the model something true about the tool's cost, which changes how willing it is to reach for it mid-reasoning.
Running it
pip install -r requirements.txt
python -m mcp_local_semantics.server # stdioClaude Desktop:
{
"mcpServers": {
"local-semantics": {
"command": "python",
"args": ["-m", "mcp_local_semantics.server"]
}
}
}Set MCP_SEMANTICS_ENCODER=hash to run without torch โ useful for smoke-testing the host connection before committing to a 90 MB download.
pytest -q # 36 tests, under a second, no downloads
python scripts/bench.py # the table aboveBuilt against MCP Python SDK v2, where
FastMCPwas renamed toMCPServerand moved tomcp.server.mcpserver. Code written for v1 needs either that change or amcp<2pin.
Design notes
The encoder is an interface, so the maths is testable
Encoder is four lines: text in, an array out. Deliberately narrower than anything sentence-transformers offers โ an interface shaped like the vendor SDK is a second SDK you now maintain.
Two implementations. LocalEncoder is the real one. HashEncoder is a signed hashed bag-of-words: deterministic, no torch, no network. It has no semantic understanding at all โ "car" and "automobile" are orthogonal to it โ and that is fine, because the test suite is asserting properties of the arithmetic: that top-k orders correctly, that MMR de-duplicates, that clustering converges and is deterministic.
The whole suite runs in 0.42 s with no downloads, so CI does not depend on a model host being reachable. Same separation that made an iteration cap testable against a mocked model client.
No similarity threshold, anywhere
top_k returns the best k regardless of score. A fixed cutoff is not scale-invariant across queries โ too strict for short questions, too loose for long ones โ and when it is too strict it fails silently, which is the bug this came out of. There is a test asserting no floor is applied. Callers wanting one can apply it to the scores they get back, having seen them.
Clustering is deterministic on purpose
K-means with k-means++ seeding, written out rather than imported so the tool has no scikit-learn dependency at runtime. Seeded, because a tool an agent calls twice on the same input and gets two answers from is a tool the agent cannot reason about. There is a test for it.
k-means++ rather than uniform seeding because uniform routinely puts two centres inside one cluster and leaves another unclaimed.
Errors come back as results, not exceptions
raise ToolError(
f"texts has {len(texts)} items; the limit is {MAX_TEXTS}. "
f"Split the batch and call again."
)Caught at the MCP boundary and returned as a result. Raising through the transport ends the exchange; returning the message lets the model fix it on the next turn. Every guard-rail message says what to do, not just what was wrong โ and there are tests asserting the messages contain the instruction.
MMR for when the corpus has near-duplicates
Plain top-k over three paraphrases of the same passage returns all three and tells the model one thing. diversity above 0 penalises a candidate by its similarity to what is already selected. At 0 it is exactly top-k; at 1 it ignores the query entirely.
Stack
Python ยท PyTorch (CPU) ยท sentence-transformers ยท MCP Python SDK v2 ยท NumPy ยท pytest
MIT licensed. Built by Ketan Shukla.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Memory system for AI agents with semantic search. Store and recall memories with ease.
Disposable private vector search + semantic RAG for AI agents. x402 pay-per-call, no account.
Universal persistent memory and knowledge retrieval layer for AI agents and LLMs.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables LLMs to autonomously research the web, store knowledge in a local vector database, and retrieve semantic memory without vendor lock-in.-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to maintain persistent, local memory with retrieval-augmented search, knowledge graphs, and context surfacing, without any cloud dependencies.135MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to perform semantic code search locally, finding code by meaning rather than exact keywords.3MIT
- AlicenseNot gradedqualityBmaintenanceProvides a local vector memory store for AI agents with semantic search, offline embeddings, and MCP integration, enabling tools like Claude and Cursor to store and retrieve information without cloud dependencies.8MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ketankshukla/mcp-local-semantics'
If you have feedback or need assistance with the MCP directory API, please join our Discord server