kb-mcp-server
Provides tools to search and retrieve documents from a pgvector knowledge base stored in Supabase, including semantic search, document listing, and content retrieval.
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., "@kb-mcp-serversearch knowledge base for onboarding steps"
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.
kb-mcp-server
把 ai-customer-service-saas 的 pgvector 知识库检索能力封装为标准 MCP Server:Tools / Resources / Prompts 三类协议消息全覆盖,Claude Desktop / MCP Inspector / Cursor 等任意 MCP 客户端零代码接入。
🏗 架构与数据流
flowchart LR
A[Claude Desktop<br/>Inspector<br/>Cursor]
B[server.py<br/>FastMCP]
C[kb.py<br/>纯函数]
D[SiliconFlow<br/>BAAI/bge-m3<br/>1024 维]
E[Supabase<br/>pgvector + RPC]
A -- stdio JSON-RPC --> B
B -- 调用 --> C
C -- HTTPS embeddings --> D
D -- 向量 --> C
C -- RPC match_document_chunks<br/>+ documents 表 --> E
E -- 检索结果 --> C
C -- 结构化返回 --> B
B -- JSON-RPC --> A关键路径:客户端通过 stdio 与本 Server 通信(MCP 标准传输);Server 把查询文本送 SiliconFlow 生成 1024 维向量,再用 Supabase 的 match_document_chunks RPC 在 pgvector 上做 cosine 相似度检索,过滤 user_id = KB_TENANT_ID 实现租户隔离,最后把命中片段 + 文档标题拼回客户端。
Related MCP server: local-rag-mcp
🎯 三类消息设计
MCP 协议有三种"客户端 ↔ Server"消息类型,本项目各自落地一例,三者触发方式不同:
类型 | 名称 | 何时触发 | 客户端入口 |
Tool |
| 模型决策调用 —— 模型在对话中判断需要时自行触发 | 通常无需用户操作,模型自动调 |
Resource |
| 客户端主动读取 —— 用户/客户端把它作为上下文挂载 | Desktop 的"附件/资源"面板手动选择 |
Prompt |
| 用户主动选用 —— 把原始问题包装成"先检索后作答 + 列来源"的指令 | Desktop 的 Prompts 面板 / 斜杠菜单 |
3 Tools(模型决策调用)
search_knowledge_base(query: str, top_k: int = 5)— 语义检索,返回[{content, similarity, document_title}];top_k钳制到[1, 20];阈值min_similarity = 0.3由kb.search内部控制,不暴露给工具层(见 设计决策)。list_documents()— 列出全部文档及元数据(id、标题、类型、状态、片段数、创建时间)。get_document_content(document_id: str)— 按 UUID 拉取并拼接全文(按 chunk 的metadata.index升序);超 8000 字符自动截断并标注原始长度。
1 Resource(客户端主动读取)
kb://documents— 文档清单的只读快照,数据结构与list_documents一致。区别在触发方式:Resource 是客户端把它作为对话起手的背景资料,不依赖模型决策。
1 Prompt(用户主动选用)
kb_qa(question: str)— 模板把用户问题包装为:基于知识库回答以下问题。请先调用 search_knowledge_base 检索相关片段,仅基于检索结果作答,不要编造;回答末尾列出来源文档标题。 问题:{question}
📋 前置条件
Python 3.11(已用
.python-version锁定)uv 包管理器
一个 Supabase 项目(免费档即可),含两张表 + 一个 RPC,SQL 见下方折叠块
一个 SiliconFlow API key(
BAAI/bge-m3embedding,1024 维)
create extension if not exists vector;
create extension if not exists pgcrypto;
create table public.documents (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users(id) on delete cascade,
title text not null,
content_type text not null check (content_type in ('pdf','txt','url','docx')),
source_url text,
status text not null default 'processing' check (status in ('processing','ready','failed')),
error_message text,
char_count int default 0,
chunk_count int default 0,
created_at timestamptz default now()
);
create index documents_user_id_idx on public.documents(user_id);
create table public.document_chunks (
id uuid primary key default gen_random_uuid(),
document_id uuid not null references public.documents(id) on delete cascade,
user_id uuid not null references auth.users(id) on delete cascade,
content text not null,
embedding vector(1024),
metadata jsonb default '{}'::jsonb,
created_at timestamptz default now()
);
create index document_chunks_user_id_idx on public.document_chunks(user_id);
create index document_chunks_document_id_idx on public.document_chunks(document_id);
create index document_chunks_embedding_idx on public.document_chunks
using ivfflat (embedding vector_cosine_ops) with (lists = 100);
create or replace function match_document_chunks(
query_embedding vector(1024),
tenant_id uuid,
match_count int default 5,
min_similarity float default 0.3
)
returns table (id uuid, document_id uuid, content text, similarity float, metadata jsonb)
language sql stable as $$
select dc.id, dc.document_id, dc.content,
1 - (dc.embedding <=> query_embedding) as similarity,
dc.metadata
from public.document_chunks dc
where dc.user_id = tenant_id
and 1 - (dc.embedding <=> query_embedding) > min_similarity
order by dc.embedding <=> query_embedding
limit match_count;
$$;ℹ️ RLS 与完整业务 schema(聊天/反馈/订阅等)见 ai-customer-service-saas 仓库。本 SQL 仅为让本 MCP Server 的检索路径在你自己的 Supabase 项目中可复现,不包含写入/管理/分析等业务表。Server 通过 Service Role Key 调用,会绕过 RLS,因此所有 SQL 都显式带
user_id = tenant_id过滤,租户隔离不依赖 RLS。
🚀 Quickstart
1. 安装 uv(Windows PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"macOS / Linux 见 uv 官方文档。
2. 克隆仓库 + 准备环境变量
git clone https://github.com/<你的用户名>/kb-mcp-server.git
cd kb-mcp-server
Copy-Item .env.example .env编辑 .env 填入四个值:
SUPABASE_URL=https://<your-project>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...
SILICONFLOW_API_KEY=sk-...
KB_TENANT_ID=<在你 Supabase auth.users 表里的 uuid>3. 用 Inspector 调试(强烈推荐先走这一步)
npx @modelcontextprotocol/inspector uv run server.py浏览器自动打开 → Transport 选 STDIO → Connect → 切到 Tools 标签 → List Tools,应看到三个工具。在 search_knowledge_base 输入你知识库里有的关键词,验证能返回中文 JSON。
4. 接入 Claude Desktop
把 claude_desktop_config.example.json 的内容合并到:
%APPDATA%\Claude\claude_desktop_config.json按模板把 4 个占位符替换为真值(路径用 \\ 双反斜杠;env 必须显式列全 4 个变量,Desktop 不继承终端环境变量)。
完全退出 Desktop(系统托盘右键 Quit,不是只关窗)→ 重启 → 输入框右下角应出现工具图标,展开能看到 knowledge-base 服务器。
🪤 Windows 踩坑记录
坑 | 现象 | 解法 |
stdio 禁 print | 一行 | 所有日志用 |
Desktop 改配置不生效 | 改了 config 重启 Desktop 工具仍未出现 | 系统托盘右键 Quit 才算完全退出,只关窗后台还在 |
| 终端能跑通,Desktop 起 Server 报缺 key | Desktop 配置 |
| Desktop 启动 Server 报 |
|
JSON 路径反斜杠 | 配置文件 parse 失败 | Windows 路径用 |
PowerShell GBK 渲染 | 中文输出看着是乱码 | 是显示问题而非数据问题;用 |
supabase 超时参数 |
| 用 |
🧭 设计决策
阈值 min_similarity = 0.3(与 SaaS 生产同源)
服务端把阈值锁定在 0.3,与上游 SaaS 生产值保持一致(同源)。弱命中(similarity 在 0.3~0.5 之间)由客户端模型凭返回的 similarity 字段自行甄别,服务端不在 MCP 层做精排。服务端精排(reranker)在 aisc V2 已另行验证,不在本项目范围。
阈值由 kb.search 的 min_similarity 形参控制(默认 0.3),透传给 RPC 第四参数;search_knowledge_base Tool 不暴露此参数,业务行为锁定 0.3,只在测试/调试时用 python -c "import kb; kb.search(..., min_similarity=0.99)" 覆盖零命中分支。
固定 KB_TENANT_ID 租户隔离
租户 id 由环境变量写死,绝不作为工具参数暴露(否则等价于把租户穿越能力直接交给 LLM)。所有 SQL/RPC 都显式 .eq("user_id", KB_TENANT_ID)。
全只读最小权限
本 Server 不暴露任何写入/删除操作。即便 Service Role Key 拥有全表写权限,工具层也仅提供 search / list / get_content 三个只读出口。
Service Role Key 绕 RLS → SQL 显式过滤
因为用 Service Role Key 直连,会绕过 Postgres RLS。这正是租户隔离不依赖 RLS、必须自己在 SQL 里显式过滤 user_id 的原因。
HTTP 超时 15s
embedding 与 RPC 正常 1-3s 完成,15s 是 5 倍余量;超时归 server 兜底 检索服务暂时不可用:{ClassName}。避免不可达或慢链路把客户端挂死。
异常文案"检索服务暂时不可用:{ClassName}"
故意保留异常类名(AuthenticationError / ConnectError / APITimeoutError / APIError / BadRequestError),让模型和运维能粗略区分故障类型,无需 isinstance 分支爆炸。完整堆栈走 logger.exception 进 stderr(铁律 1)。
✅ 手测清单
13 条用例覆盖正常路径 / Resource+Prompt / 已覆盖兜底 / 异常路径,详见 tests/manual_test.md,每条带"如何制造"+ 还原检查。
🐍 自写 Client(协议两侧)
除了 Claude Desktop / Inspector 这类现成客户端,本仓库还附带一个最小 Python Client client_demo.py,用官方 SDK 的 stdio_client + ClientSession 把 server.py 作为子进程拉起,在同一 stdio 通道上把 Tools / Resources / Prompts 三类消息从客户端侧全覆盖。
前置:在仓库根目录跑,且 .env 已填真值(子进程 server 会继承父进程环境)。
uv run python client_demo.py预期输出(节选):
============================================================
✅ 已连接 kb-mcp-server(stdio 子进程)
============================================================
[1/4] list_tools → 工具清单:
- search_knowledge_base: 语义检索知识库,返回与查询最相关的若干片段(含相似度与所属文档标题)。
- list_documents: 列出当前知识库的全部文档及元数据(id、标题、类型、状态、片段数、创建时间)。
- get_document_content: 按 document_id 拉取并拼接单篇文档全文。
[2/4] call_tool('search_knowledge_base', ...) →
命中 3 条
首条 similarity = 0.7240
首条 document_title = lantu-x10-manual
首条 content 前 100 字:...
[3/4] read_resource('kb://documents') → 文档标题清单:
- lantu-x10-manual(chunk_count=...)
[4/4] get_prompt('kb_qa', question='滤网怎么保养?') → 渲染后模板:
[user] 基于知识库回答以下问题。请先调用 search_knowledge_base 检索相关片段...任何一步失败会直接 raise(非零退出码),便于 CI / 面试现场快速定位。
📜 License
🙏 致谢
本 MCP Server 复用 ai-customer-service-saas 已部署的 Supabase 向量库与 SiliconFlow embedding,实现"零迁移"接入。MCP 协议与 SDK 来自 Anthropic 官方。
Available Tools
3 toolsget_document_contentA
按 document_id 拉取并拼接单篇文档全文。
何时使用:用户要看某文档完整内容,或 search 命中后需要更完整上下文时。
参数 document_id 必须是合法 UUID(可从 list_documents 或 search_knowledge_base
的返回中获取)。超 8000 字符会自动截断并在末尾标注原始字符数。
| Name | Required | Description | Default |
|---|---|---|---|
| document_id | Yes |
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 the full burden. It discloses automatic truncation at 8000 characters with original character count noted, which is a key behavioral trait. However, it doesn't mention idempotency or read-only nature, but for a fetch operation this is sufficient.
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 concise with four sentences, front-loaded with the main purpose. Every sentence adds value without waste.
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 simple nature (one required param, output schema exists), the description is complete. It covers truncation behavior and parameter source, which is sufficient for the AI agent to correctly invoke the tool.
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 0%, so the description must add meaning. It clarifies that document_id must be a valid UUID and provides sources (list_documents or search_knowledge_base), which is a significant addition beyond the schema's type definition.
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 clearly states it fetches the full content of a single document by document_id, distinguishing it from sibling tools like list_documents (lists metadata) and search_knowledge_base (searches). The verb '拉取并拼接' (fetch and concatenate) specifies the action and resource.
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 explicitly states when to use: when the user wants to see the full document content or after a search for more context. It also specifies that document_id must be a valid UUID obtainable from other tools, providing clear usage context and exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_documentsA
列出当前知识库的全部文档及元数据(id、标题、类型、状态、片段数、创建时间)。
何时使用:用户询问"知识库里有什么"、需要清单概览,或在调用 get_document_content
前需要先获取 document_id 时。无参数。
| 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?
No annotations provided, so description must cover behavioral traits. It lists output fields but does not explicitly state read-only nature or any destructive potential. As a list tool, it's implicitly safe, but more explicit disclosure would improve transparency.
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 concise: two sentences without filler, clearly structured with purpose and usage guidelines. Every sentence adds value.
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 an output schema exists (context signal), the description still lists key metadata fields (id, title, type, status, fragment count, creation time), making it complete for a list tool. No gaps.
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 zero parameters, and the description confirms '无参数'. Since schema coverage is 100% and parameters are none, the baseline is 4, and the description adds clear confirmation.
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 clearly states the tool lists all documents and metadata from the current knowledge base, using specific verb '列出' and resource '当前知识库的全部文档及元数据'. It distinguishes itself from siblings like 'get_document_content' by focusing on listing all 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 explicitly states when to use: when user asks '知识库里有什么', needs an overview, or before calling get_document_content to obtain document_id. It mentions no parameters. While it provides good context, it lacks explicit when-not-to-use or alternatives beyond the sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_knowledge_baseA
语义检索知识库,返回与查询最相关的若干片段(含相似度与所属文档标题)。
何时使用:用户提问涉及具体业务、产品、政策等知识库内容时,先调用本工具拿到
相关片段再作答,并在回答中标注片段来源文档。
参数:
- query(必填):用户原话或主题关键词
- top_k(默认 5):返回片段数,上限 20(超过会被自动钳制)
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description discloses behavioral traits: returns fragments with similarity and document title, auto-clamps top_k to 20. Adequate for a search 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?
The description is concise and front-loaded with the core purpose. Every sentence adds value without redundancy.
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 an output schema exists, the description adequately covers usage, parameter semantics, and return format (fragments with similarity and title). No gaps for this simple tool.
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 0%, but the tool description provides meaningful descriptions for both parameters: query as user's words/topic keywords, and top_k with default, max, and clamping behavior. This adds significant value beyond the schema.
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 clearly states the tool performs semantic search on a knowledge base, returning relevant fragments with similarity and document title. It distinguishes from sibling tools like get_document_content and list_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 explicitly says when to use (when user's question involves knowledge base content) and instructs to call this tool first before answering. It does not explicitly state when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
3 tool updates
v0.1.0- First observed
get_document_content - First observed
list_documents - First observed
search_knowledge_base
TDQS
Each tool has a distinct purpose: listing documents, searching semantically, and retrieving full content. No ambiguity between them; descriptions clearly differentiate when to use each.
All tool names follow the consistent verb_noun pattern in snake_case (list_documents, search_knowledge_base, get_document_content), making the API predictable.
Three tools cover the core operations for a read-only knowledge base server: list, search, and get content. The count is well-scoped with no redundancy.
The set provides essential read operations, but lacks create/update/delete actions. For a purely retrieval-focused knowledge base, this is nearly complete; minor gap for full CRUD.
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
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
RAG-as-a-service MCP sunucusu — çok-kiracılı koleksiyon yönetimi, metin ingest (chunk+embed+upsert,…
MCP server giving Claude AI access to 22+ NYC public-record databases for real estate due diligence
Related MCP Servers
- AlicenseAqualityBmaintenance基于MCP协议的知识库服务器,内置LLM层,提供结构化知识存储、语义搜索和主动知识推送,支持通过工具进行知识学习、搜索和关联推理。661MIT
- AlicenseNot gradedqualityAmaintenanceA RAG knowledge base MCP server using FastMCP and LanceDB, enabling hybrid search, document ingestion, and full MCP tool/resource/prompt support.MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that enables semantic search over a private knowledge base via pgvector, with GitHub OAuth authentication and a RAG pipeline.18MIT
- FlicenseNot gradedqualityCmaintenanceMCP server exposing a RAG knowledge base as read-only tools (search_knowledge_base, ask_knowledge_base, kb_stats, kb_diagnostic) for AI clients like Claude Desktop and Cursor, enabling token-efficient document retrieval and Q&A.-
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/code-runner-xx/kb-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server