内容
# beds24-mcp-server
Beds24 API 的 MCP 服务器 + 命令行工具 + 软件开发工具包。两个互补的层,构建在同一个数据源上:
1. **语义搜索** — 在引用的 Markdown 文档(`beds24-search`)上建立向量索引。回答诸如 *"定价如何传播?"*、 *"渠道源 ID 是什么?"* 之类的问题。
2. **模式验证** — 解析 `apiV2.yaml` 并验证草稿有效载荷(`beds24-validate`)。回答 *"我的 POST /bookings 有效载荷有什么问题?"* 之类的问题。
`knowledge/` + `knowledge/apiV2.yaml` 目录中的 Markdown 文档是 **数据源**。`.beds24/` 向量索引是一个可重新生成的缓存(`bun run index`)。软件开发工具包(`src/sdk/`)具有零 MCP 依赖,因此可以从其他存储库导入(数据平台、工作流等)。
## 安装
### 全局安装(推荐 — 随处可用)
```bash
npm install -g beds24-mcp-server
```
这将发布 `beds24-mcp-server` 命令。然后自动配置你的工具:
```bash
beds24-mcp-server setup # 检测 Claude Code / Cursor / Windsurf / VS Code,写入它们的 MCP 配置
```
就这样 — `setup` 写入配置,运行 `bun install`(如果需要),并构建向量索引。重启你的工具;工具就会出现。
运行 `beds24-mcp-server setup --dry-run` 预览写入内容而无需实际修改,或者使用 `--harness claude --harness cursor` 选择特定的工具。如果要稍后构建索引,可以使用 `--skip-index`。
### 本地安装 / 从源码安装
```bash
bun install
bun run index # 从 knowledge/*.md 构建向量索引(一次性,大约 30 秒)
# 或者在第一次启动服务器时自动索引
```
要从源码安装配置工具:
```bash
bun run setup # 与全局命令相同的检测 + 配置写入
```
## 在其他存储库中使用软件开发工具包
软件开发工具包没有 MCP 依赖 — 只需将其指向事实 + YAML:
```ts
import { Beds24Validator, Beds24Search } from "beds24-mcp-server/sdk";
const validator = Beds24Validator.create({ factsDir: "path/to/knowledge" });
const result = await validator.validate("POST /bookings", "request", payload);
// result.valid, result.errors — 将错误反馈给你的 LLM 以修复调用
```
这允许你在 dagster 资产、inngest 函数或命令行工具中运行模式验证 — 无需 MCP 服务器。
## 使用客户端
一个无依赖的 HTTP 客户端(全局 `fetch`,Node 18+),具有 24 小时令牌身份验证、401 自动令牌刷新、请求验证和信用额度跟踪:
```ts
import { Beds24Client } from "beds24-mcp-server/client";
const client = new Beds24Client({ apiKey: "...", propKey: "..." });
const { data, credits } = await client.request("GET /bookings", {
arrival: "2026-08-01",
departure: "2026-08-05",
});
// credits.remaining / credits.resetsIn — 5 分钟速率限制窗口
```
`apiV2.yaml` 中的每个 `METHOD /path` 都可以通过 `client.request(key, body)` 访问。请求正文在发送前会根据模式进行验证(快速失败,节省信用额度)。抛出带有 `status`、`code`、`retryable` 和 `creditsRemaining` 的 `Beds24Error`。
## 配置(你的工具)
所有工具都使用相同的 MCP JSON 格式;唯一不同的地方是 **配置文件位置**。
共享块(粘贴到下面的 `command` / `args` 中)。**如果通过 npm 安装,请优先使用全局命令** — 它在重新安装时存活并且不会硬编码检出路径:
```json
{
"command": "beds24-mcp-server",
"args": ["serve"]
}
```
备用方案(替换 `/ABSOLUTE/PATH/to/beds24-mcp`):
```json
{
"command": "bun",
"args": ["run", "/ABSOLUTE/PATH/to/beds24-mcp/src/server.ts"]
}
```
> 运行 `beds24-mcp-server setup`(或 `bun run setup`)自动写入这些文件 — 无需手动编辑。
### Claude Code
项目级 `.mcp.json`(已提交,与团队共享)**或** 用户级 `~/.claude/.mcp.json`(仅限您):
```json
{
"mcpServers": {
"beds24": {
"command": "bun",
"args": ["run", "/ABSOLUTE/PATH/to/beds24-mcp/src/server.ts"]
}
}
}
```
重启 Claude Code。工具出现在每个会话中。
### Cursor
全局 `~/.cursor/mcp.json`(所有项目)或项目 `.cursor/mcp.json`:
```json
{
"mcpServers": {
"beds24": {
"command": "bun",
"args": ["run", "/ABSOLUTE/PATH/to/beds24-mcp/src/server.ts"]
}
}
}
```
打开 **Cursor 设置 → MCP**;服务器应该显示绿色。如果不是,请单击 **重启所有服务器**(它必须在您的 `$PATH` 上解析 `bun` — 从 shell 启动 Cursor 或将 bun 路径添加到配置的 `env` 中)。
### Windsurf
`~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"beds24": {
"command": "bun",
"args": ["run", "/ABSOLUTE/PATH/to/beds24-mcp/src/server.ts"]
}
}
}
```
重新加载窗口 / 重启 Windsurf 以获取它。
### VS Code (Copilot)
项目级 `.vscode/mcp.json`:
```json
{
"servers": {
"beds24": {
"command": "bun",
"args": ["run", "/ABSOLUTE/PATH/to/beds24-mcp/src/server.ts"]
}
}
}
```
> 注意:VS Code 使用 `servers`(不是 `mcpServers`)。编辑后重启 VS Code。
### 任何其他工具(OpenCode、goose、…)
格式相同 — 在工具的设置中查找“MCP 服务器”,并注册一个名为 `beds24` 的服务器,带有上述 `command` / `args` 块。
### 故障排除
- **"bun not found"** — 工具不会继承你的 shell `$PATH`。从终端启动它,或将 bun 目录添加到服务器的 `env`(例如 `"env": { "PATH": "/Users/you/.bun/bin:/usr/bin:/bin" }`)。
- **重启后无工具** — 服务器在第一次运行时自动索引并记录到 stderr。打开工具的 MCP/output 面板并查找 `[beds24] MCP server connected on stdio.`。如果显示错误,请重新运行 `bun install && bun run index`。
- **过时事实** — 更新 `knowledge/` 后,运行 `bun run index`(或删除 `.beds24/` 并重启;它会重新构建)。
## 工具
| 工具 | 输入 | 输出 |
|------|-------|--------|
| `beds24_search` | `query: string`, `topK?: number` | 顶部命中 `{text, sourceFile, headingPath, lines, score}` |
| `beds24_schema` | `endpoint: string`, `direction: "request"\|"response"` | 解析的字段列表 `{name, type, required, description, enum?}` |
| `beds24_validate` | `endpoint: string`, `direction`, `payload: object` | `{valid, errors: [{path, message, expected, actual}]}` |
| `beds24_howto` | `task: string` | 搜索命中 + 匹配模式 + 步骤摘要 |
| `beds24_status` | — | `{factsFiles, chunksIndexed, dbSize}` |
## 源代码布局
```
.
├── knowledge/ # 事实 + OpenAPI 规范(数据源)
│ ├── index.md, api-v2/, pricing/, system-logic/ ...
│ └── apiV2.yaml
├── src/
│ ├── sdk/ # 可重复使用的 TS 软件开发工具包(无 MCP 依赖 — 从其他存储库导入)
│ │ ├── index.ts # 重新导出
│ │ ├── db.ts # libsql 存储 + sqlite-vec 余弦索引
│ │ ├── embed.ts # 本地嵌入模型(Xenova/all-MiniLM-L6-v2)
│ │ ├── chunk.ts # Markdown 分割器(感知标题,保持引用)
│ │ ├── indexer.ts # 遍历事实 → 章节块 → 嵌入 → 存储
│ │ ├── search.ts # 向量搜索 + 章节查找
│ │ ├── schema.ts # 解析 apiV2.yaml → 解析 $ref/allOf/oneOf
│ │ └── validate.ts # 草稿有效载荷 → 结构化 LLM 友好错误
│ ├── server.ts # MCP 上的薄包装(仅在此处依赖 MCP)
│ └── cli.ts # 薄 CLI 包装(`beds24-mcp-server index|status`)
├── .beds24/ # 生成的向量索引(gitignored)
└── package.json
```
## 索引策略(重要)
事实已经按语句 + 源 + 日期分割。**不要分割成固定大小的块** — 这会破坏引用并混淆无关的事实(“向量汤”)。
相反,在 **章节(`##`)/ 子章节(`###`)** 边界处分割。每个索引条目 = 一个章节,存储其标题路径、完整文本(内联引用)、源文件和行范围。查询准确地落在相关的引用章节上。
结构化表格内容(`schemas-*.md` 文件和 `version-reference.md`)更好地通过 **模式/验证** 工具(精确查找)而不是向量搜索来提供服务 — 将精确字段问题路由到那里,将模糊的“它如何工作?”问题路由到搜索。
## 刷新
当事实发生变化时:`bun run index` 重新构建索引。服务器在启动时自动索引,如果 `.beds24/` 丢失。