Skip to content

Commit 6d776b2

Browse files
authored
feat(knowledgebase): migrate to MCP 2026 and add Viking API Key authentication (#428)
* feat: migrate knowledgebase server to MCP 2026 * feat(knowledgebase): support Viking API key authentication * feat(knowledgebase): expose document metadata in search results * fix(knowledgebase): prefer API key authentication * docs(knowledgebase): install from PyPI
1 parent 00ad809 commit 6d776b2

8 files changed

Lines changed: 1190 additions & 415 deletions

File tree

server/mcp_server_knowledgebase/README.md

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ allowing you to add doc to your collections and get doc processing info by doc_i
1212
### Prerequisites
1313

1414
- Python 3.10 or higher
15-
- API credentials (AK/SK)
15+
- A Viking Knowledge Base API key or VolcEngine AK/SK credentials
1616

1717
### Installation
1818

@@ -30,21 +30,31 @@ uv pip install -e .
3030

3131
### Configuration
3232

33-
The server requires the following environment variables:
33+
The server requires at least one authentication method:
3434

35-
- `VOLCENGINE_ACCESS_KEY`: Your VolcEngine access key
36-
- `VOLCENGINE_SECRET_KEY`: Your VolcEngine secret key
35+
- API key: set `VIKING_API_KEY`. Requests use
36+
`Authorization: Bearer <VIKING_API_KEY>`.
37+
- AK/SK: set both `VOLCENGINE_ACCESS_KEY` and `VOLCENGINE_SECRET_KEY`.
38+
Requests use VolcEngine SignerV4 authentication.
39+
40+
When both methods are configured, `VIKING_API_KEY` takes precedence and AK/SK
41+
is ignored. When no API key is configured, AK and SK must be provided together.
42+
The server rejects configurations with no usable authentication method.
3743

3844
Optional environment variables:
39-
- `KNOWLEDGE_BASE_PROJECT`: Your viking knowledge base project name
40-
- `KNOWLEDGE_BASE_REGION`: Your viking knowledge base region,if not provided, will use `cn-north-1` as default
41-
- `PORT`: Port for the FastMCP server (default: 8000)
45+
- `KNOWLEDGE_BASE_PROJECT`: Viking Knowledge Base project name (default: `default`)
46+
- `KNOWLEDGE_BASE_REGION`: Viking Knowledge Base region (default: `cn-north-1`)
47+
- `MCP_SERVER_HOST`: Streamable HTTP bind host (default: `127.0.0.1`)
48+
- `MCP_SERVER_PORT`: Streamable HTTP port; falls back to `PORT` (default: `8000`)
49+
- `STREAMABLE_HTTP_PATH`: Streamable HTTP endpoint path (default: `/mcp`)
50+
- `KNOWLEDGE_BASE_TIMEOUT`: Upstream request timeout in seconds (default: `30`)
4251

4352
## Usage
4453

4554
### Running the Server
4655

47-
The server can be run with either stdio transport (for MCP integration) or SSE transport:
56+
The server supports stdio for local integrations and stateless Streamable HTTP
57+
for remote deployments:
4858

4959
```bash
5060
python -m mcp_server_knowledgebase.server --transport stdio
@@ -53,9 +63,25 @@ python -m mcp_server_knowledgebase.server --transport stdio
5363
Or:
5464

5565
```bash
56-
python -m mcp_server_knowledgebase.server --transport sse
66+
python -m mcp_server_knowledgebase.server --transport streamable-http
5767
```
5868

69+
The Streamable HTTP endpoint is `http://127.0.0.1:8000/mcp` by default.
70+
Set `MCP_SERVER_HOST=0.0.0.0` when running behind a trusted gateway.
71+
72+
### MCP protocol compatibility
73+
74+
This server uses MCP Python SDK 2.x and speaks protocol revision `2026-07-28`.
75+
Modern clients use the stateless per-request protocol and `server/discover`;
76+
the same process also supports older handshake-based clients automatically.
77+
Legacy HTTP+SSE is intentionally not exposed because it is deprecated by the
78+
`2026-07-28` specification.
79+
80+
The HTTP endpoint does not turn the configured API key or VolcEngine AK/SK into
81+
client authentication. Protect remote deployments with an authentication
82+
gateway or MCP-compatible OAuth, and never expose the service credentials to
83+
callers.
84+
5985
### Available Tools
6086

6187
#### add_doc
@@ -66,7 +92,7 @@ Add a document to a collection in your project.
6692
add_doc(
6793
collection_name="collection_name",
6894
add_type="url",
69-
doc_id="_mcp_server_auto_gen_doc_id_xxxxxxx",
95+
doc_id="mcp_server_auto_gen_doc_id_xxxxxxx",
7096
doc_name="doc_xxxx",
7197
doc_type="pdf",
7298
url="http://xxxxx.pdf"
@@ -76,8 +102,8 @@ add_doc(
76102
Parameters:
77103
- `collection_name` (required): the name of the collection you want to add document .
78104
- `add_type` (required): the type of the document to add. so far only support "url" now.
79-
- `doc_id` (required): you should generate a unique doc_id based on user's given url and timestamp, the doc_id can only use English letters, numbers, and underscores , and must start with an English letter. It cannot be empty. Length requirement: [1, 128], you can use a format like "_mcp_server_auto_gen_doc_id_xxxxxxx.
80-
- `doc_name` (required): the name of the document to add. you can1 generate a unique doc_name based on user given url and timestamp. the length of doc_name must between 1 and 256. you can use a format like "_mcp_server_auto_gen_doc_name_xxxxxxx.
105+
- `doc_id` (required): you should generate a unique doc_id based on user's given url and timestamp, the doc_id can only use English letters, numbers, and underscores , and must start with an English letter. It cannot be empty. Length requirement: [1, 128], you can use a format like "mcp_server_auto_gen_doc_id_xxxxxxx".
106+
- `doc_name` (required): the name of the document to add. You can generate a unique doc_name based on the user-provided URL and timestamp. The length of doc_name must be between 1 and 256; for example, "mcp_server_auto_gen_doc_name_xxxxxxx".
81107
- `doc_type` (required): the type of the document to add. for structured document, we support xlsx, csv,jsonl, for unstructured document, wu support txt, doc, docx, pdf, markdown, faq.xlsx, pptx". you should judge the doc_type based on user's given url and judge if we support this doc type. if supported, assign this parameter.
82108
- `url` (required): the url of the document to add. user should give a valid url, we will add the doc to the collection.
83109

@@ -88,7 +114,7 @@ Get information about document by collection_name and doc_id .
88114
```python
89115
get_doc(
90116
collection_name="collection_name",
91-
doc_id="_mcp_server_auto_gen_doc_id_xxxxxxx",
117+
doc_id="mcp_server_auto_gen_doc_id_xxxxxxx",
92118
)
93119
```
94120

@@ -128,19 +154,24 @@ Search for knowledge in the configured collection based on a query.
128154
search_knowledge(
129155
query="How to reset my password?",
130156
limit=3,
131-
collection_name=None,
157+
collection_name="collection_name",
132158
doc_filter=None,
133159
)
134160
```
135161

136162
Parameters:
137163
- `query` (required): The search query string
138-
- `limit` (optional): Maximum number of results to return (default: 3)
139-
- `collection_name` (optional): Knowledge base collection name to search. If not provided, llm will choose some collections to search based on the description of collection
164+
- `limit` (optional): Maximum number of results to return, from 1 to 100 (default: 3)
165+
- `collection_name` (required): Knowledge Base collection name to search
140166
- `doc_filter` (optional): the filter is used to filter search results(default: None), which is structured as a JSON object with the following key components:
141167
- `op` (string, required): specifies the query operator that defines the filtering logic. Valid values are 'must' and 'must_not', 'must' means results must satisfy the condition (inclusion filter),'must_not' means results must not satisfy the condition (exclusion filter).
142168
- `field` (string, required): indicates the specific document field to apply the filter on (e.g., "doc_id").
143169
- `conds` (array, required): contains the concrete values used for filtering. The data type of elements in the array depends on the field.
170+
171+
Each result contains the chunk `id` and `content`, plus the source document's
172+
`doc_id` and `doc_name`. The metadata fields are `null` when Viking does not
173+
provide them. A non-null `doc_id` can be passed directly to `get_doc`.
174+
144175
## MCP Integration
145176

146177
To add this server to your MCP configuration, add the following to your MCP settings file:
@@ -152,12 +183,11 @@ To add this server to your MCP configuration, add the following to your MCP sett
152183
"command": "uvx",
153184
"args": [
154185
"--from",
155-
"git+https://github.com/volcengine/mcp-server#subdirectory=server/mcp_server_knowledgebase",
186+
"mcp-server-knowledgebase>=0.2.0",
156187
"mcp-server-knowledgebase"
157-
],
188+
],
158189
"env": {
159-
"VOLCENGINE_ACCESS_KEY": "your-access-key",
160-
"VOLCENGINE_SECRET_KEY": "your-secret-key",
190+
"VIKING_API_KEY": "your-viking-api-key",
161191
"KNOWLEDGE_BASE_PROJECT": "your-project-name",
162192
"KNOWLEDGE_BASE_REGION": "your-region"
163193
}
@@ -166,12 +196,17 @@ To add this server to your MCP configuration, add the following to your MCP sett
166196
}
167197
```
168198

199+
You may alternatively or additionally configure both
200+
`VOLCENGINE_ACCESS_KEY` and `VOLCENGINE_SECRET_KEY`. If all three variables are
201+
set, `VIKING_API_KEY` takes precedence.
202+
169203
## Troubleshooting
170204

171205
### Common Issues
172206

173207
1. **Authentication Errors**
174-
- Verify your AK/SK credentials are correct
208+
- Verify your API key or AK/SK credentials are correct
209+
- Ensure at least one authentication method is configured
175210
- Check that you have the necessary permissions for the collection
176211

177212
2. **Connection Timeouts**

server/mcp_server_knowledgebase/README_zh.md

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Viking Knowledge Base MCP Server 是一个模型上下文协议(Model Context Pr
2020
### 前置准备
2121
- Python 3.10+
2222
- UV
23-
- API credentials (AK/SK)
23+
- 知识库 API Key 或火山引擎 AK/SK
2424

2525
### 安装
2626
克隆仓库:
@@ -36,10 +36,20 @@ git clone git@github.com:volcengine/mcp-server.git
3636
cd mcp-server/server/mcp_server_knowledgebase
3737
uv run mcp-server-knowledgebase
3838

39-
# 使用sse模式启动(默认为stdio)
40-
uv run mcp-server-knowledgebase -t sse
39+
# 使用无状态 Streamable HTTP 模式启动(默认为 stdio)
40+
uv run mcp-server-knowledgebase -t streamable-http
4141
```
4242

43+
Streamable HTTP 默认地址为 `http://127.0.0.1:8000/mcp`。在可信网关后部署时,
44+
可设置 `MCP_SERVER_HOST=0.0.0.0`
45+
46+
Server 使用 MCP Python SDK 2.x,支持 `2026-07-28` 协议修订版及
47+
`server/discover` 无状态协商,同时由 SDK 自动兼容旧版握手客户端。
48+
旧 HTTP+SSE 已被新协议弃用,因此本 Server 不再提供 SSE 启动模式。
49+
50+
Streamable HTTP 本身不会把知识库 API Key 或火山引擎 AK/SK 转换成 MCP 调用方认证。
51+
远程部署必须放在认证网关之后或接入兼容 MCP 的 OAuth,且不得向调用方暴露服务凭证。
52+
4353
使用客户端与服务器交互:
4454
```
4555
Trae | Cursor | Claude Desktop | Cline | ...
@@ -49,15 +59,26 @@ Trae | Cursor | Claude Desktop | Cline | ...
4959

5060
### 环境变量
5161

62+
鉴权至少需要配置一种方式:配置 `VIKING_API_KEY`,或同时配置
63+
`VOLCENGINE_ACCESS_KEY``VOLCENGINE_SECRET_KEY`。API Key 模式会通过
64+
`Authorization: Bearer <VIKING_API_KEY>` 请求头鉴权;AK/SK 模式继续使用
65+
SignerV4。两种方式可以同时配置,此时 `VIKING_API_KEY` 优先,AK/SK 会被
66+
忽略。未配置 API Key 时,AK 和 SK 必须同时提供;没有可用鉴权方式时服务将
67+
启动失败。
68+
5269
以下环境变量可用于配置MCP服务器:
5370

5471
| 环境变量 | 描述 | 默认值 |
5572
|--------------------------|-----------------|-------|
73+
| `VIKING_API_KEY` | 知识库 API Key(配置时优先使用) | - |
5674
| `VOLCENGINE_ACCESS_KEY` | 火山引擎账号ACCESSKEY | - |
5775
| `VOLCENGINE_SECRET_KEY` | 火山引擎账号SECRETKEY | - |
58-
| `KNOWLEDGE_BASE_PROJECT` | 知识库所属项目 | - |
76+
| `KNOWLEDGE_BASE_PROJECT` | 知识库所属项目 | `default` |
5977
| `KNOWLEDGE_BASE_REGION` | 知识库区域 | cn-north-1 |
60-
| `PORT` | MCP server监听端口 | `8000` |
78+
| `MCP_SERVER_HOST` | Streamable HTTP 监听地址 | `127.0.0.1` |
79+
| `MCP_SERVER_PORT` | Streamable HTTP 端口(兼容 `PORT`| `8000` |
80+
| `STREAMABLE_HTTP_PATH` | Streamable HTTP 路径 | `/mcp` |
81+
| `KNOWLEDGE_BASE_TIMEOUT` | 上游请求超时(秒) | `30` |
6182

6283

6384
## 可用工具
@@ -76,7 +97,7 @@ Knowledge Base MCP Server 提供以下功能
7697
add_doc(
7798
collection_name="collection_name",
7899
add_type="url",
79-
doc_id="_mcp_server_auto_gen_doc_id_xxxxxxx",
100+
doc_id="mcp_server_auto_gen_doc_id_xxxxxxx",
80101
doc_name="doc_xxxx",
81102
doc_type="pdf",
82103
url="http://xxxxx.pdf"
@@ -96,7 +117,7 @@ Parameters:
96117
```python
97118
get_doc(
98119
collection_name="collection_name",
99-
doc_id="_mcp_server_auto_gen_doc_id_xxxxxxx",
120+
doc_id="mcp_server_auto_gen_doc_id_xxxxxxx",
100121
)
101122
```
102123

@@ -128,14 +149,18 @@ list_collections()
128149
search_knowledge(
129150
query="How to reset my password?",
130151
limit=3,
131-
collection_name=None
152+
collection_name="collection_name"
132153
)
133154
```
134155

135156
Parameters:
136157
- `query` (必须): 搜索查询字符串
137-
- `limit` (可选): 返回的最大结果数(默认值:3)
138-
- `collection_name` (可选): 要搜索的知识库名称。如果未提供,LLM将根据您账号列表下的知识库描述选择自动选择要搜索的知识库
158+
- `limit` (可选): 返回的最大结果数,范围 1–100(默认值:3)
159+
- `collection_name` (必须): 要搜索的知识库名称
160+
161+
每条结果包含分块的 `id``content`,以及来源文档的 `doc_id`
162+
`doc_name`;Viking 未提供文档元数据时,这两个字段为 `null`。非空的
163+
`doc_id` 可以直接传给 `get_doc`
139164

140165

141166
### uvx 启动
@@ -146,12 +171,11 @@ Parameters:
146171
"command": "uvx",
147172
"args": [
148173
"--from",
149-
"git+https://github.com/volcengine/mcp-server#subdirectory=server/mcp_server_knowledgebase",
174+
"mcp-server-knowledgebase>=0.2.0",
150175
"mcp-server-knowledgebase"
151-
],
176+
],
152177
"env": {
153-
"VOLCENGINE_ACCESS_KEY": "your-access-key",
154-
"VOLCENGINE_SECRET_KEY": "your-secret-key",
178+
"VIKING_API_KEY": "your-viking-api-key",
155179
"KNOWLEDGE_BASE_PROJECT": "your-project-name",
156180
"KNOWLEDGE_BASE_REGION": "your-region"
157181
}
@@ -160,5 +184,8 @@ Parameters:
160184
}
161185
```
162186

187+
也可以额外或改为同时配置 `VOLCENGINE_ACCESS_KEY`
188+
`VOLCENGINE_SECRET_KEY`。三个变量均配置时,优先使用 `VIKING_API_KEY`
189+
163190
## 证书
164191
volcengine/mcp-server is licensed under the [MIT License](https://github.com/volcengine/mcp-server/blob/main/LICENSE).
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
[project]
22
name = "mcp-server-knowledgebase"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
description = "MCP server for Viking Knowledge Base Service"
55
readme = "README.md"
66
requires-python = ">=3.10"
77
license = {text = "MIT"}
88
dependencies = [
9-
"mcp[cli]>=1.5.0",
9+
"mcp[cli]>=2.1.1,<3",
1010
"volcengine>=1.0.171",
1111
"aiohttp>=3.11.14",
12-
"deprecated>=1.2.18",
1312
]
1413

1514
[project.scripts]
@@ -18,4 +17,3 @@ mcp-server-knowledgebase = "mcp_server_knowledgebase.server:main"
1817
[build-system]
1918
requires = ["hatchling"]
2019
build-backend = "hatchling.build"
21-

server/mcp_server_knowledgebase/src/mcp_server_knowledgebase/common/auth.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import json
2-
import sys
3-
import requests
42

53
from volcengine.auth.SignerV4 import SignerV4
64
from volcengine.base.Request import Request
75
from volcengine.Credentials import Credentials
86
from mcp_server_knowledgebase.config import config
97

10-
def prepare_request(method, path, ak, sk, params=None, data=None, doseq=0):
8+
9+
def prepare_request(
10+
method, path, ak=None, sk=None, params=None, data=None, doseq=0, *, api_key=None
11+
):
12+
ak = ak.strip() if isinstance(ak, str) else ak
13+
sk = sk.strip() if isinstance(sk, str) else sk
14+
api_key = api_key.strip() if isinstance(api_key, str) else api_key
15+
16+
if not api_key:
17+
if bool(ak) != bool(sk):
18+
raise ValueError("AK and SK must be configured together")
19+
if not ak or not sk:
20+
raise ValueError("Configure an authentication method: VIKING_API_KEY or AK/SK")
21+
1122
if params:
1223
for key in params:
1324
if (
@@ -28,12 +39,15 @@ def prepare_request(method, path, ak, sk, params=None, data=None, doseq=0):
2839
"Accept": "application/json",
2940
"Content-Type": "application/json",
3041
}
42+
if api_key:
43+
mheaders["Authorization"] = f"Bearer {api_key}"
3144
r.set_headers(mheaders)
3245
if params:
3346
r.set_query(params)
3447
r.set_path(path)
3548
if data is not None:
3649
r.set_body(json.dumps(data))
37-
credentials = Credentials(ak, sk, "air", config.region)
38-
SignerV4.sign(r, credentials)
39-
return r
50+
if not api_key:
51+
credentials = Credentials(ak, sk, "air", config.region)
52+
SignerV4.sign(r, credentials)
53+
return r

0 commit comments

Comments
 (0)