VeloxRAG
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., "@VeloxRAGRetrieve documents about climate change and answer: what are the main causes?"
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.
VeloxRAG
A local RAG service that acts as memory for coding agents. It ingests documents and past sessions, retrieves passages with citation-grade offsets, and exposes them to an agent over MCP. Everything runs on your machine: the corpus never leaves it.
It supplies data; composing the answer is the agent's job. That boundary is deliberate — see what it does not do.
Install
curl -fsSL https://raw.githubusercontent.com/ilikebug/veloxrag/main/install.sh | bashInstalls Ollama if it is missing, pulls bge-m3 (about 1.2 GB, once), writes compose.yaml into
~/.veloxrag, starts the stack, and prints the command to connect an agent. Re-running converges
rather than reinstalling, and never touches existing data volumes.
What it needs first:
Docker, running, with Compose 2.23.1 or newer. compose.yaml carries the embedding proxy's nginx configuration inline, and inline
contentonly exists from that version; older Compose parses the file and mounts nothing, which surfaces as the nginx container failing to start. The installer will not install Docker for you — on macOS that is a choice between Docker Desktop and Colima that belongs to you.2 CPUs, 4 GiB of memory and about 4 GB of disk for the Docker VM — the containers idle at roughly 450 MiB in total, so the headroom is for the ingest and the corpus rather than the services. Resources it needs has the measured figures and where to set the limits.
Ollama on the host. The embedding model runs on the host rather than in a container because that is the only place it reaches the GPU: Docker on macOS is a Linux VM with no Metal passthrough, measured at 3.10 chunks/s against 14.20 on the host, and the flat batch curve says the container is compute-bound rather than badly tuned.
install.shhandles it; by hand it isbrew install ollama && brew services run ollama && ollama pull bge-m3(runrather thanstart, which would also register a launch-at-login item).
It also installs a veloxrag command, which is how the stack comes back after a reboot:
veloxrag startThat starts Docker, then Ollama, then the containers, in that order. Nothing is registered to
launch at login — and that ordering is the reason a command is needed rather than merely
convenient. The containers carry restart: unless-stopped, but a daemon-driven restart does not
honour depends_on, which applies only to docker compose up. Measured after a VM stop/start:
three of seven containers returned, and the worker sat in a restart loop having exhausted its
attempts against dependencies that were not up yet. veloxrag start repairs the order and gives a
service that has given up one further nudge — 7 seconds, from that state to healthy.
Command | What it does |
| Docker, Ollama and the containers, in dependency order |
| the containers only; Ollama and Docker are left alone, since other things may be using them |
| the containers only |
| what is running, and whether Ollama and the API answer |
| follow logs, all services or one such as |
Plain docker compose still works from ~/.veloxrag; the command adds the ordering and the
Ollama check, not a wrapper you are obliged to use. If retrieval fails and you would rather check
by hand, Ollama is the first suspect: curl http://127.0.0.1:11434/api/version.
Upgrading from a release that ran the embedding model in a container, pass --remove-orphans
once. Compose only removes containers it still knows about, and the retired embedding-model is
no longer in the file, so it keeps running and holding memory until told otherwise:
cd ~/.veloxrag && docker compose up -d --remove-orphansRelated MCP server: vector-mcp
Connect an agent
claude mcp add --scope user rag-memory -- uvx --from git+https://github.com/ilikebug/veloxrag velox-mcpNo checkout and no token. For a client that takes a config file:
{
"mcpServers": {
"rag-memory": {
"command": "uvx",
"args": ["--from", "git+https://github.com/ilikebug/veloxrag", "velox-mcp"]
}
}
}Working inside a checkout, run it from the working tree so code changes take effect immediately:
claude mcp add --scope user rag-memory -- uv run --project /path/to/VeloxRAG velox-mcpFour read-only tools:
Tool | Purpose |
| Retrieval, with an optional |
| Read a document's text around a character range, to see what a result was cut off from |
| See what is indexed, to narrow a search or notice a gap |
| Which knowledge base is bound, and whether retrieval is ready |
Ingestion, knowledge base creation and key minting are deliberately absent: an agent that can provision storage can also destroy it, and deletion here is real.
The stack has to be up first — the MCP server is only a client. No environment variables are needed; all three exist for departing from the defaults:
Variable | When you need it |
| The service is not at |
| Local trusted auth is switched off; supply an agent key carrying |
| The service holds more than one knowledge base. With exactly one it resolves automatically; with several it refuses to guess, because guessing wrong means searching the wrong memory |
More detail, including why two compose defaults hold only locally, is in docs/mcp.md.
Connecting the MCP server only gives the agent tools to search memory; nothing writes to it, and
searching is left to the agent's own discretion. velox-hook is a separate pair of Claude Code
hooks that record every turn and search on every prompt automatically — off until you add them, and
independent of the MCP connection above:
uv tool install git+https://github.com/ilikebug/veloxrag
~/.local/bin/velox-hook installThe first line puts a stable executable on disk; the second writes the two hook entries into
~/.claude/settings.json, merging with whatever is already in that file rather than replacing it.
They take effect in the next session, not the one already running. velox-hook uninstall reverses
it.
What gets recorded and what deliberately does not, how retrieval is scoped to one project, what it costs per prompt, and how to backfill history you already have, are all in docs/agent-memory.md.
Retrieval
Relevance judgement is left to the agent, not done by a reranker. An agent already reads the passages and reasons about them, which is what a cross-encoder does with a far smaller model. So the useful thing is not another ranking pass but giving that judgement something to work with: retrieve more passages than you need, then widen the promising ones before deciding.
A search hit is a chunk, and the answer frequently sits just past its edge. Every result carries
source.start_offset / source.end_offset, and GET /v1/documents/{id}/content?start=&end=
reads that range back out of the document's normalized text — the same offsets, no second
addressing scheme. Measured over 18 queries on a chat-transcript corpus, widening each hit by 300
characters moved answer-level MRR from 0.645 to 0.724 and took @5 and @10 from 0.89 and 0.94 to
1.00. A passage that looks truncated is worth widening rather than discarding.
What that measurement cannot reach: @10 in-chunk was 0.94, so roughly one query in sixteen returns no candidate holding the answer at all. Closing that needs better retrieval — hybrid search — rather than better judgement.
Chunking defaults to 600 codepoints with 100 overlap, and those defaults are measured rather than
guessed: on English documentation, moving from 1200 to 600 lifted answer-hit MRR from 0.631 to
0.836, the largest single quality gain found. On a chat-transcript corpus the size barely mattered
(600 scored 0.675 against 300's 0.679, inside the noise at that sample size) because transcript
turns are short already. RAG_CHUNK_MAX_CODEPOINTS and RAG_CHUNK_OVERLAP_CODEPOINTS change it;
the worker reads them at process start, so a change needs a worker restart.
Reranking exists in the service but has no engine behind it in the default setup: Ollama exposes
no rerank endpoint. Setting "rerank": true without a configured rerank profile fails with
RERANK_NOT_CONFIGURED.
What runs, and where the data lives
Every host port binds 127.0.0.1 only, and every one is overridable — these defaults are all
ports a developer machine commonly already has taken:
Entry point | Default | Override |
API |
|
|
PostgreSQL |
|
|
Qdrant HTTP / gRPC |
|
|
Redis |
|
|
MinIO API / console |
|
|
Only the host-side mapping changes; containers reach each other by service name. The one exception
is RAG_API_HOST_PORT: an MCP client defaults to http://127.0.0.1:8000, so changing the API
port means setting RAG_MCP_BASE_URL too. make start probes whether 6379 is taken and falls
back to 6380; it does not probe the others.
The MinIO console signs in with the development-only defaults rag-dev / change-me-local, from
MINIO_ROOT_USER and MINIO_ROOT_PASSWORD. They are published placeholders rather than secrets,
and production has to replace them. Note which side the startup check reads:
RAG_ENVIRONMENT=production refuses to start when the client credentials are still the defaults
— RAG_MINIO_ACCESS_KEY still rag-dev, or RAG_MINIO_SECRET_KEY carrying a change-me marker.
MINIO_ROOT_* configures the server and is not covered, so changing one side alone gets a stack
that starts and then cannot authenticate.
What each component owns, which is also the backup priority:
PostgreSQL is the authoritative source for document visibility, jobs, generations, checkpoints and authorization. Losing it cannot be recovered from the others.
MinIO holds original files, normalized text and canonical chunk manifests; it is not a vector database. Vectors can be rebuilt from it, the originals cannot.
Qdrant holds vectors and retrieval payloads, both rebuildable from those canonical artifacts.
Redis only wakes the worker with low latency. Losing it adds delay and no data.
Do not log any secret, token, authentication header, or raw response containing one, and keep credentials out of command line arguments, shell history and Git.
Resources it needs
Measured on the running stack rather than estimated. Idle, the seven containers hold about 450 MiB between them:
Container | Idle memory | What it does under load |
api | 137 MiB | CPU spikes to ~15% while accepting an upload |
worker | 124 MiB | one core to ~70% while chunking; memory flat |
minio | 77 MiB | — |
qdrant | 57 MiB | grows with the index, see below |
postgres | 48 MiB | — |
redis | 6 MiB | — |
embedding (nginx) | 2 MiB | proxy only; the model is on the host |
Memory barely moves during ingestion because the expensive part — embedding — runs in Ollama on the host, not in a container. That is also why a machine that could not previously fit the containerized model can run this: the container side needs well under 1 GiB.
Storage, measured against a small corpus and linear in the number of chunks:
What | Size |
Images, all seven | 1.8 GB |
Ollama plus | about 1.5 GB |
Postgres, empty schema | 65 MiB |
Qdrant | about 30 KB per chunk at 1024 dimensions |
MinIO | roughly the size of the corpus, plus normalized text and chunk manifests |
A rough total: 4 GB of disk covers the images, the model and a corpus of a few thousand chunks. The number that grows is Qdrant, and a cutover doubles it until the retired collection is removed by hand.
Setting the limits
Nothing in compose.yaml caps CPU or memory, deliberately: the ceiling that matters is the one on
the Linux VM your Docker runs in, and a per-container cap below it only turns a slow ingest into a
killed one.
On macOS the VM is where to set it. When Colima is installed but not running, install.sh starts
it with 4 CPUs, 8 GiB and 60 GiB, overridable through VELOX_VM_CPU, VELOX_VM_MEMORY and
VELOX_VM_DISK. A running VM it leaves alone, and so should you by this route:
colima stop && colima start --cpu 4 --memory 8 --disk 60The stop matters. colima start does not resize a running instance, but --save-config defaults
to true, so passing the flags to a live VM rewrites the config without applying it — the machine
keeps its old size until the next restart silently adopts the new one. A Colima disk can also grow
later but not shrink, so err large on that one.
Docker Desktop has the same three under Settings → Resources. 2 CPUs and 4 GiB run the stack; 4 CPUs and 8 GiB leave room for the host Ollama to use the GPU without competing for RAM. On Linux there is no VM and the containers use the host directly.
Give the disk more room than the corpus needs. A full disk fails in two directions at once:
Qdrant refuses writes with No space left on device, and — measured, not theorized — a Docker
build in the same state fails without saying why, so the next thing you try appears broken for an
unrelated reason. docker system df shows where it went; build cache and old images are usually
most of it.
If you do want a per-container cap, compose takes one:
services:
worker:
deploy:
resources:
limits:
memory: 1gHTTP API
The service has no UI. The authoritative contract comes from the service itself, generated from the code so it cannot go stale:
Endpoint | Purpose |
| All 40 operations and their schemas. Point an AI or a tool at this one |
| Swagger UI, interactive (frontend assets come from a CDN, so it needs network) |
| ReDoc |
Step-by-step operations, including minting keys and the order configuration has to happen in, are in docs/api-operations.md. Production requirements and the points of no return are in docs/deployment.md, and the embedding setup is in docs/local-embedding.md.
Three things that make requests fail in ways the error does not explain:
Authentication has three levels and none is skippable. Admin tokens are minted only by the in-container CLI; they sign Agent keys; an Agent key's capabilities decide what it may call. Scope is a hard constraint — a
managekey with an emptyknowledge_base_idscan create knowledge bases but returns 404 for any that already exists.Configuration order is fixed. Provider credential → ProviderConfig → embedding probe → ModelProfile → knowledge base → initial index generation → Agent key → upload → search. Without that generation the knowledge base looks fine while ingest and search both fail. The installer does all of this for you.
Creates need
Idempotency-Key, modifications needIf-Match. Reuse the same idempotency key to retry and a new one once the body changes; GET theETagbefore aPATCH,DELETEorrevoke.
To decide whether the service can work right now, use the readiness probes rather than aggregating configuration state:
GET /health— the API process is alive.GET /ready— the core PostgreSQL and Qdrant dependencies.GET /ready/ingest— additionally Redis, MinIO, and the provider keyring and referenced configuration.GET /ready/retrieve— the retrieval dependencies and the same provider configuration.GET /ready/answer— always 503. Answer generation is outside this layer's responsibility, so this probe never becomes ready; do not wire it into a health check.
The worker scans PostgreSQL for queued jobs, jobs whose retry_wait came due, and running jobs with an expired lease, so losing Redis adds wake-up latency and never loses a committed job. External effects in MinIO, Qdrant and providers all carry deterministic identifiers and PostgreSQL reconciliation facts; a restarted worker resumes from a committed checkpoint rather than trusting uncommitted external state.
Changing the index configuration
The embedding model, chunk size, distance metric and filter schema are frozen by the generation that uses them. Changing one is a cutover: create a second generation on the same knowledge base and the service swaps to it, enrols the existing documents and queues their backfill in one transaction, so the knowledge base id never changes and nothing downstream is reconfigured.
curl -sS -X POST "http://127.0.0.1:8000/v1/admin/knowledge-bases/${KB}/index-generations" \
-H 'Content-Type: application/json' -H "Idempotency-Key: $(uuidgen)" \
-d '{"embedding_profile_id":"'"${PROFILE}"'","distance":"cosine"}'Search returns nothing until the backfill finishes, which is a deliberate trade: a single-user
service can be silent for the minutes a rebuild takes, and the alternative — writing to both
generations during the rebuild — is a locked hot-path change. Watch it with
GET /v1/jobs/{job_id}.
The retired generation's Qdrant collection is not reclaimed yet, so each cutover leaves one behind.
Current limitations
Not yet supported:
PDF, DOCX, OCR or other binary document formats;
document replacement or new versions, and no user-facing delete recovery — a delete is real and cannot be undone;
LLM semantic chunking, and only one chunking strategy is registered;
sparse and hybrid retrieval;
reranking in the default setup, for want of an engine that offers it;
answer generation, and cross-KB search — both by design, see the boundary above;
reclaiming a retired generation's collection.
Development
uv sync --frozen
make check
make verifymake check is the static checking; make verify adds unit, non-acceptance integration, isolated
acceptance and Compose publication verification, combining fresh coverage files against a branch
floor of 80%.
COMPOSE_DISABLE_ENV_FILE=1 make acceptance-ingestion-retrieval
COMPOSE_DISABLE_ENV_FILE=1 make compose-configInside the repository, make start builds the api image from the working tree and refuses to start
when Ollama is not answering. Every Compose operation sets COMPOSE_DISABLE_ENV_FILE=1
explicitly: configuration arrives as explicit environment variables rather than an implicitly read
dotenv file.
If Testcontainers Ryuk races container startup on an M3 Mac:
TESTCONTAINERS_RYUK_DISABLED=true make test-integrationPublishing a release
make build TAG=0.4.0
make push VELOX_IMAGE=docker.io/<your namespace>/veloxrag TAG=0.4.0build produces this machine's architecture in the local image store, for running and inspecting.
push rebuilds rather than pushing what build produced: consumers run both amd64 and arm64, and
buildx cannot hold a multi-architecture manifest locally, so both platforms go straight to the
registry from one invocation. It needs a prior docker login, and VELOX_IMAGE has to match what
compose.yaml resolves to for consumers — otherwise whoever downloads compose.yaml cannot pull
what you pushed. Bump the version in pyproject.toml before building, so the package version
inside the image matches its tag.
License
MIT, see LICENSE.
Available Tools
4 toolslist_documentsB
List what is indexed, so a search can be narrowed or a gap in the memory can be recognised rather than guessed at.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of disclosing behavior. It implies a read-only listing operation ('List') but does not explicitly confirm safety or side effects. It also does not mention pagination, sorting, or limit semantics, although the schema's limit parameter is self-explanatory. The description adds minimal behavioral context beyond the obvious reading of 'list', but for a simple retrieval tool this is borderline adequate—hence a 3.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that leads with the primary action and resource, followed by a purpose clause. It contains no filler, fluff, or redundant information. Every phrase serves a function: the action, the object, and the reason. It is appropriately brief for a tool of this simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple (one optional parameter, output schema present), and the description covers its purpose and when to use it. The only minor omission is clarification of what 'indexed' refers to (e.g., all documents, memory entries), which could confuse an agent. However, given the output schema likely defines the structure and the tool name is clear, the description is largely complete for practical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has a single parameter 'limit' with default/min/max but no description, and schema description coverage is 0%. The tool description does not mention the limit parameter at all, leaving its semantics entirely to inference from the name and constraints. Since the description fails to compensate for the lack of schema documentation, the parameter meaning is not clearly communicable, particularly for agents unaware of common 'limit' conventions. This is a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('List') and a resource ('what is indexed'), indicating it retrieves the set of indexed items. It hints at its purpose relative to siblings ('so a search can be narrowed' contrasts with search_memory, and 'gap in the memory' suggests memory_status), but it does not explicitly name or differentiate those siblings. It is more specific than a tautology and gives a meaningful overview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context for when to use the tool: before a search to narrow scope, or to recognize gaps in memory. However, it does not explicitly state when NOT to use it or name alternative tools (e.g., 'use search_memory for retrieving specific content'). The guidance is implied rather than explicit, so it earns a mid-range score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
memory_statusA
Report which knowledge base this server is bound to and whether the service can answer searches right now.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the behavioral burden. It discloses that this is a read-only status report and indicates liveness, but it does not describe error conditions, what 'bound to' means in concrete terms, or the shape of readiness reporting beyond the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every phrase adds useful information about the tool's scope and current usefulness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no parameters and an output schema exists, so the description does not need to explain return values. It sufficiently covers the core purpose and operational state, though it could mention typical usage context such as 'call before search_memory'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so parameter semantics are trivially satisfied. The description correctly focuses on behavior rather than inputs, and the baseline for zero-parameter tools applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Report') and names the exact resources: the bound knowledge base and service readiness. This clearly distinguishes it from sibling tools that list, search, or read documents.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description conveys a clear diagnostic purpose and implies use as a pre-flight check before searches ('whether the service can answer searches right now'). It does not explicitly name alternatives or exclusions, but the context is strong enough for an agent to infer when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_documentA
Read a document's text around a character range, to see what a search result was cut off from. Pass the document_id and the source.start_offset / source.end_offset of a passage, widened by a few hundred characters on each side. Offsets past either end are clamped rather than refused, and total_codepoints tells a clamped range from an exhausted one.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No | ||
| document_id | Yes | From a search result |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It clearly communicates the read-only nature and discloses important edge-case behavior: offsets past either end are clamped rather than refused, and total_codepoints distinguishes clamped from exhausted ranges. This is strong for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, each earning its place: purpose, how to call it, and a key edge-case behavior. No filler or redundant restatement of the name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with an output schema available, the description covers what, when, how, and the main edge-case. The connection to search results makes its role among siblings clear. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%, so the description must compensate for start and end. It explains that start/end correspond to search-result offsets and recommends widening them. It adds meaning beyond the bare integer schema, but does not fully specify exact inclusivity or default-range behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('read a document's text around a character range') and a clear use case ('to see what a search result was cut off from'). It naturally differentiates itself from sibling tools like search_memory by being the follow-up expansion action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides concrete guidance: pass document_id and source.start_offset/source.end_offset, widened by a few hundred characters. It implies the intended workflow after a search result, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_memoryA
Search indexed memory and return the passages that match. Prefer a specific question over keywords. Retrieving more than you need and picking among them yourself works better than trusting the first result: the ranking is vector similarity, which cannot tell that a passage merely repeats the question. Leave rerank off unless this service has a rerank profile configured — the default setup has none, and asking for it fails with RERANK_NOT_CONFIGURED.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | What to look for, phrased as a question | |
| top_k | No | ||
| rerank | No | ||
| source_type | No | Restrict to one kind, e.g. 'doc' or 'chat' |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility for behavioral disclosure. It reveals that ranking is vector similarity, explains why first results can be misleading, and names the exact failure mode for rerank (RERANK_NOT_CONFIGURED). This goes well beyond a generic search description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and each subsequent sentence earns its place: query phrasing, retrieval strategy, and the rerank pitfall. It is dense but not bloated, and the structure guides the agent from what to do to what to avoid.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, an output schema is present, and the description covers the key decision points: query formulation, retrieval volume, and rerank configuration. Nothing essential for calling this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With only 50% schema coverage, the description compensates well for query and rerank semantics, and it implicitly motivates top_k through 'retrieving more than you need.' source_type is not addressed in the description, but the schema already provides an explanatory description and example for it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Search'), a clear resource ('indexed memory'), and the outcome ('return the passages that match'). This clearly distinguishes search_memory from siblings like read_document and list_documents even without reading the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage guidance: prefer a specific question, retrieve more than needed, and leave rerank off unless a profile is configured. It does not explicitly compare against sibling tools or state when not to use search_memory, but the guidance is strong and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool occupies a distinct role: status readiness, document inventory, passage search, and context reading. There is no real overlap between searching and reading, since read_document is explicitly tied to expanding a search result's context.
Most tools use verb_noun snake_case: list_documents, search_memory, read_document. memory_status breaks the verb pattern as a noun_noun status check, but the naming style is otherwise uniform and clear.
Four tools is a tight, well-scoped set for a read-oriented RAG memory server, and each one has a clear purpose in the search/inspect workflow. No tool feels redundant or missing at the count level.
The retrieval/inspection workflow is closed: an agent can check readiness, list what is indexed, search, and read around any hit. Ingestion and deletion are absent, but they appear to be outside this server's read-only scope rather than a dead end in its described workflow.
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
Make your knowledge agent-ready. One MCP endpoint, 5 connectors, 3 search modes.
The CustomGPT.ai MCP server is a fully managed, RAG-powered endpoint that connects large language models with private knowledge bases and external data sources. It provides tools for retrieval-augmented generation queries (send_message), data ingestion (upload_file), and source listing, enabling AI agents to query private documents like PDFs with high accuracy and real-time citations.
An MCP memory server. One memory your agents share — across models, devices and apps.
NeuralBrain MCP Server - RAG, Vector Memory, LLM Routing, Agent Identity, x402 Payments
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA RAG knowledge base MCP server that adds vector search and reranking capabilities to opencode, supporting multimodal embeddings, multiple knowledge bases, and local storage.1MIT
- AlicenseBqualityAmaintenanceA production-grade MCP server for integrating RAG into AI agents, supporting multiple vector databases with enterprise security and dynamic tool selection.215MIT
- AlicenseNot gradedqualityBmaintenanceIntegrates RAG into AI agents via MCP Server, supporting multiple vector database technologies for collection management and search operations.11MIT
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/ilikebug/veloxrag'
If you have feedback or need assistance with the MCP directory API, please join our Discord server