内容
<p align="center">
<img src="docs/logo.png" alt="MCP Firebird" width="360">
</p>
<p align="center">
<a href="LICENSE"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/License-Apache_2.0-blue.svg"></a>
<img alt="MCP protocol 2025-03-26" src="https://img.shields.io/badge/MCP-2025--03--26-brightgreen.svg">
<a href="https://github.com/danieleteti/mcp-server-delphi"><img alt="powered by mcp-server-delphi" src="https://img.shields.io/badge/powered%20by-mcp--server--delphi-orange.svg"></a>
<a href="https://github.com/danieleteti/mcp-firebird/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/danieleteti/mcp-firebird/actions/workflows/ci.yml/badge.svg"></a>
</p>
# MCP Firebird
MCP Firebird 是 [Model Context Protocol](https://modelcontextprotocol.io) 的服务端,适用于 **Firebird 2.5 – 5.0**,使用官方 `fbclient` 驱动程序以 Delphi 编写。它允许 AI 助手记录模式,分析查询计划,建议索引(添加和删除),审计模式健康状况,并驱动基于目标的优化 — 默认情况下**只读**。
> 使用 **[mcp-server-delphi](https://github.com/danieleteti/mcp-server-delphi)** 构建 — 该服务端是使用该框架可以构建的完整、现实世界的示例。
- **传输:** stdio(JSON-RPC 2.0,MCP 协议 `2025-03-26`)
- **服务端标识:** `mcp-firebird` v`0.1.0`
- **引擎支持:** Firebird 2.5, 3.0, 4.0, 5.0(运行时检测能力)
- **安全性:** 只读分析;DDL/写入在 `firebird.allow_ddl=true` 后启用
---
## 目录
1. [功能介绍](#功能介绍)
2. [如何使用 mcp-server-delphi](#如何使用-mcp-server-delphi)
3. [先决条件](#先决条件)
4. [构建](#构建)
5. [配置(`.env`)](#配置-env)
6. [手动运行和验证](#手动运行和验证)
7. [连接到 MCP 客户端](#连接到-mcp客户端) — Claude Desktop · Claude Code · Gemini CLI · OpenCode · Cursor / VS Code · 通用
8. [从 Claude 使用](#从-claude使用) — 示例
9. [工具参考](#工具参考)
10. [测试项目](#测试项目)
11. [故障排除](#故障排除)
---
## 功能介绍
### 工具(10)
| 工具 | 参数 | 目的 |
|---|---|---|
| `fb_info` | — | 引擎版本 + 检测到的功能(JSON) |
| `fb_list_tables` | — | 列出用户表 |
| `fb_describe_table` | `table_name` | 列,PK,索引,外键 |
| `fb_generate_documentation` | `table_name?` | 表或整个数据库的 Markdown 文档 |
| `fb_analyze_query` | `sql` | 访问计划分析:NATURAL-scan + external-SORT 检测 |
| `fb_suggest_indexes` | `sql` | 新索引建议(已准备好运行的 DDL) |
| `fb_suggest_index_drops` | `table_name` | 标记重复/冗余前缀/不活动/低选择性索引 |
| `fb_audit_table` | `table_name` | 模式健康审计:缺少 PK,过度索引,过期统计 |
| `fb_evaluate_goal` | `goal_type`,`target`,`threshold` | 确定性目标检查(驱动优化循环) |
| `fb_monitor_transactions` | `stale_minutes?` | 交易/扫描健康状况:OIT/OAT/下一个间隙,阻止长时间运行的交易(及其最后一个 SQL 语句) |
每个建议都带有 **Finding**,准备运行的 **SQL** 和 **Verify** 步骤。
### 提示(2)
- **`optimization_goal`** — 目标驱动循环:设置目标,助手迭代 `fb_*` 工具并重新检查 `fb_evaluate_goal`,直到它报告 `met: true`(带有最大迭代/无进展安全停止)。
- **`health_check`** — 有指导的整个数据库健康审查。
### 资源(1)
- **`firebird://schema`** — 作为单个资源的实时数据库模式。
---
## 如何使用 mcp-server-delphi
每个工具都是一个普通的 Delphi 方法,使用 [mcp-server-delphi](https://github.com/danieleteti/mcp-server-delphi) 中的属性装饰。框架将类转换为 MCP 工具提供程序,从属性生成 JSON-RPC 模式,并将其连接到_stdio_ 传输 — 该存储库中没有协议代码。从 `providers/FirebirdToolsU.pas`:
```pascal
TFirebirdTools = class(TMCPToolProvider)
public
[MCPTool('fb_info', '引擎版本,方言,字符集和检测到的配置 Firebird 数据库的功能')]
function FbInfo: TMCPToolResult;
[MCPTool('fb_describe_table', '表中的列,主键,索引和外键')]
function FbDescribeTable([MCPParam('表名')] const table_name: string): TMCPToolResult;
[MCPTool('fb_analyze_query', '返回并分析 SQL 查询的访问计划(标记 NATURAL 扫描和外部排序)')]
function FbAnalyzeQuery([MCPParam('要分析的 SQL 查询')] const sql: string): TMCPToolResult;
end;
```
提示 (`providers/FirebirdPromptsU.pas`) 和资源 (`providers/FirebirdResourcesU.pas`) 使用相同的属性方法。参见 [mcp-server-delphi](https://github.com/danieleteti/mcp-server-delphi) 存储库以获取完整的属性引用。
---
## 先决条件
- **Windows x64**(服务端是原生 Win64 控制台应用程序)。
- **Delphi 13 Athens**(RAD Studio 37.0)用于构建,带有 **FireDAC**。
- **DMVCFramework** 和 **`mcp-server-delphi`** 库在本地检查(下面的搜索路径)。
- 一个与目标服务器匹配或更新的 **Firebird 客户端库** (`fbclient.dll`)。 5.0 的 `fbclient.dll` 可以连接到 2.5-5.0 服务器。
- 一个可访问的 **Firebird 数据库** 来指向它。
> 要运行 **测试矩阵**,您还需要 `fb_versions/` 下的 Firebird zip-kits 和带有 `pytest` 的 Python 3。参见 [测试项目](#测试项目)。
---
## 构建
项目期望的搜索路径(在 `app/MCPFirebird.dproj` 中设置一次):
```
C:\DEV\mcp-server-delphi\sources
<DMVCFramework>\sources (DMVC 需要的每个 sources 子文件夹)
C:\DEV\mcp-firebird\sources
C:\DEV\mcp-firebird\providers
```
从存储库根目录构建 Win64 调试应用程序:
```powershell
cmd /c _build_app.bat
```
`_build_app.bat` 调用 `rsvars.bat` 然后 `msbuild app\MCPFirebird.dproj /t:Clean;Build /p:Config=Debug /p:Platform=Win64`。
可执行文件位于 **`bin\MCPFirebird.exe`**。
(有一个匹配的 `_build_core.bat` 用于 DUnitX 测试项目。)
---
## 配置(`.env`)
默认情况下,服务端从可执行文件所在文件夹中的 **`.env` 文件** 读取其配置。复制模板并编辑它:
```powershell
Copy-Item bin\.env.example bin\.env
```
### 选择不同的配置文件夹:`--env <dir>`
默认情况下,`.env` 从可执行文件自己的文件夹中读取。传递 **`--env <dir>`** 从另一个文件夹读取它 - 参数是一个 **目录**(包含 `.env` 的文件夹),而不是文件本身:
```powershell
MCPFirebird.exe --env C:\configs\prod # 读取 C:\configs\prod\.env
MCPFirebird.exe --env=C:\configs\prod # --env=<dir> 形式也有效
MCPFirebird.exe --env ..\shared # 相对路径解析为工作目录
MCPFirebird.exe # 无参数 -> 读取 <exe folder>\.env
MCPFirebird.exe --env C:\configs\prod\.env # 错误 -> 停止并打印错误信息(参见下文)
```
> **`--env` 是一个文件夹,永远不是 `.env` 文件。** 如果您指向文件(例如 `...\prod\.env`),服务端拒绝启动并在 stderr 上打印修复方法 - MCP 客户端在服务器日志中显示这些日志 - 而不是静默启动并使用空配置:
>
> ```
> MCPFirebird: --env 必须指向包含 .env 文件的文件夹,而不是文件本身。
> got: C:\configs\prod\.env
> use this: C:\configs\prod
> ```
**如何将 `--env` 从每个 MCP 客户端传递**
**Claude Desktop** (`%APPDATA%\Claude\claude_desktop_config.json`),**Claude Code** (`.mcp.json`),**Cursor** (`.cursor/mcp.json`) 和 **VS Code** (`.vscode/mcp.json`) 都使用相同的形状 - 一个 `command` 加上一个 `args` 数组:
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe",
"args": ["--env", "C:\\configs\\prod"]
}
}
}
```
Claude Code 还可以从 CLI 添加它:
```powershell
claude mcp add firebird -- "C:\DEV\mcp-firebird\bin\MCPFirebird.exe" --env "C:\configs\prod"
```
**Gemini CLI** (`~/.gemini/settings.json`) - 相同的 `mcpServers` 形状:
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe",
"args": [],
"cwd": "C:\\DEV\\mcp-firebird\\app\\bin",
"timeout": 30000,
"trust": false
}
}
}
```
**OpenCode** (`opencode.json`) - 注意区别:`command` 是 **单个数组**,已经 包括参数(没有单独的 `args` 字段):
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"firebird": {
"type": "local",
"command": ["C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe", "--env", "C:\\configs\\prod"],
"enabled": true
}
}
}
```
### 服务多个数据库
使用不同的 `--env` 文件夹注册 **相同的可执行文件**,每个文件夹都包含自己的 `.env`:
```json
{
"mcpServers": {
"firebird-prod": {
"command": "C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe",
"args": ["--env", "C:\\configs\\prod"]
},
"firebird-test": {
"command": "C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe",
"args": ["--env", "C:\\configs\\test"]
}
}
}
```
```
C:\configs\prod\.env <- 生产环境主机/端口/数据库
C:\configs\test\.env <- 测试环境主机/端口/数据库
```
客户端然后显示两个独立的服务端 (`firebird-prod`, `firebird-test`),每个服务端都连接到自己的数据库。
| 键 | 默认值 | 含义 |
|---|---|---|
| `firebird.host` | `localhost` | 服务器主机(TCP)。对于远程数据库,请使用实际主机/ IP。 |
| `firebird.port` | `3050` | 服务器端口 |
| `firebird.database` | *(空)* | 服务器上数据库的完整路径(或别名) |
| `firebird.user` | `SYSDBA` | 登录用户 |
| `firebird.password` | `masterkey` | 登录密码 |
| `firebird.charset` | `UTF8` | 连接字符集 |
| `firebird.client_lib` | *(空)* | 要加载的 `fbclient.dll` 的完整路径 |
| `firebird.allow_ddl` | `false` | **安全门** 用于写入/DDL 工具(M1 工具是只读的) |
| `logger.config.file` | `loggerpro.stdio.json` | 文件日志配置(日志仅写入文件;stdout 保持纯 JSON-RPC) |
`bin\.env` 示例:
```ini
firebird.host=localhost
firebird.port=3050
firebird.database=C:\data\MYAPP.FDB
firebird.user=SYSDBA
firebird.password=masterkey
firebird.charset=UTF8
firebird.client_lib=C:\Program Files\Firebird\Firebird_5_0\fbclient.dll
firebird.allow_ddl=false
logger.config.file=loggerpro.stdio.json
```
> **为什么使用文件而不是客户端传递的环境变量?** dotEnv 策略是 *file-then-env*:`.env` 文件具有优先级,OS 环境变量是后备配置。通过 `bin\.env` 配置与客户端完全相同,因为它相对于 `.exe` 读取,而客户端的工作目录不可预测。保持此文件版本控制之外(它已经 `.gitignore`d)- 它包含凭据。
---
## 运行和手动验证
服务端通过 stdin/stdout 进行 JSON-RPC 通信。您可以在没有任何 MCP 客户端的情况下通过 将 framed JSON 行输入它。
从 PowerShell:
```powershell
$msgs = @(
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"manual","version":"1"}}}'
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"fb_info","arguments":{}}}'
) -join "`n"
$msgs | & .\bin\MCPFirebird.exe
```
预期结果:一个 `initialize` 结果命名 `mcp-firebird`,一个 `tools/list` 包含 10 个 `fb_*` 工具,和 `fb_info` 返回实时 `engine_version`。(日志显示在 `bin\logs\`;stdout 是纯 JSON-RPC。)
---
## 连接到 MCP 客户端
所有客户端都启动 **相同的命令** - `MCPFirebird.exe` 的绝对路径,服务端从 `bin\.env` 中获取数据库连接信息。调整路径到您构建的位置。
### Claude Desktop
编辑 `%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\app\\bin\\MCPFirebird.exe"
}
}
}
```
重启 Claude Desktop。服务端自动显示 `fb_*` 工具和两个提示。
### Claude Code (CLI)
添加一个命令(本地stdio服务端):
```powershell
claude mcp add firebird -- "C:\DEV\mcp-firebird\bin\MCPFirebird.exe"
```
或提交一个项目范围的 `.mcp.json` 到存储库根目录,以便团队成员继承它:
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\app\\bin\\MCPFirebird.exe",
"args": [],
"env": {}
}
}
}
```
使用 `claude mcp list` 验证(或在会话中使用 `/mcp`)。
### Gemini CLI
编辑 `~/.gemini/settings.json`(或项目级别 `.gemini/settings.json`):
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\app\\bin\\MCPFirebird.exe",
"args": [],
"cwd": "C:\\DEV\\mcp-firebird\\app\\bin",
"timeout": 30000,
"trust": false
}
}
}
```
然后在 Gemini CLI 中使用 `/mcp`。
### OpenCode
编辑 `opencode.json`(全局 `~/.config/opencode/opencode.json` 或每个项目)并注册一个 **本地** MCP 服务端 - `command` 是一个 argv 数组:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"firebird": {
"type": "local",
"command": ["C:\\DEV\\mcp-firebird\\app\\bin\\MCPFirebird.exe"],
"enabled": true
}
}
}
```
### Cursor / VS Code
Cursor 读取 `.cursor/mcp.json`;VS Code(和 MCP 感知扩展)读取 `.vscode/mcp.json`。两者使用相同的形状:
```json
{
"mcpServers": {
"firebird": {
"command": "C:\\DEV\\mcp-firebird\\app\\bin\\MCPFirebird.exe"
}
}
}
```
### 任意其他 MCP 客户端
服务端是一个标准的 **stdio** MCP 服务端。无论客户端的配置格式如何,请为其提供:
- **command:** `C:\DEV\mcp-firebird\bin\MCPFirebird.exe`
- **args:** *(无)* - 或 `["--env", "C:\\configs\\prod"]` 使用另一个文件夹中的 `.env`
- **transport:** stdio
- **env:** *(无必需)* - 连接来自 `.env`
> **提示:** 要将不同客户端指向不同数据库,请为每个客户端提供不同的 `--env <dir>`(一个包含其自己的 `.env` 的文件夹)- 无需复制整个 `bin\` 文件夹。 例如,在 Claude Code `.mcp.json` 中:
> ```json
> { "mcpServers": { "firebird": {
> "command": "C:\\DEV\\mcp-firebird\\bin\\MCPFirebird.exe",
> "args": ["--env", "C:\\configs\\prod"] } } }
> ```
---
## 从 Claude 使用
一旦服务端注册完成,您就可以像平常一样与 Claude 交流 - 它会选择合适的 `fb_*` 工具,对您的配置数据库运行它,并将结果转换为可运行的 SQL。下面的交流示例假设了种子演示数据库;请替换为您自己的表和列名。
> **您:** 您连接到哪个 Firebird 版本,哪些功能可用?
Claude 调用 **`fb_info`** 并报告引擎版本、方言、字符集和检测到的功能(MON$ 表、解释计划、BOOLEAN、INT128、时区、并行工作线程)。
> **您:** 列出数据库中的表。
→ **`fb_list_tables`** → `CUSTOMERS`、`ORDERS`、`NOPK_LOG`、`OVERIDX`、`STALE_T_`, …
### 2. 文档模式
> **您:** 文档 `CUSTOMERS` 表。
→ **`fb_describe_table`** → 列,`CUSTOMER_ID` 主键,索引和外键。
> **您:** 为整个数据库生成完整的 Markdown 文档,并将其放入文件中。
→ **`fb_generate_documentation`**(无表 = 整个数据库)。Claude 返回 Markdown;要求它保存文本到 `docs/schema.md` 如果您希望它在磁盘上。
### 3. 诊断慢速查询并修复它
> **您:** 这个查询很慢,为什么?
> `SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'`
→ **`fb_analyze_query`** → *`CUSTOMERS` 上的 **NATURAL 扫描 - `CITY` 列的筛选条件没有有用的索引。*
> **您:** 建议一个修复它的索引。
→ **`fb_suggest_indexes`** → 一个准备好的 DDL 语句和如何验证:
```sql
CREATE INDEX IDX_CUSTOMERS_CITY ON CUSTOMERS (CITY);
-- 验证:重新运行 fb_analyze_query;`CUSTOMERS` 上的 NATURAL 扫描应该消失。
```
> **您:** 还有这个呢?`SELECT * FROM CUSTOMERS ORDER BY CITY`
→ **`fb_analyze_query`** 标记一个 **外部排序**(没有可用的索引用于排序)。
### 4. 清理冗余索引
> **您:** 我可以安全删除ORDERS上的哪些索引?
→ **`fb_suggest_index_drops`** → 标记 `IDX_ORDERS_CUSTOMER_DUP` 为系统外键索引的重复索引,并附带 `DROP INDEX` 语句和验证步骤。
> **您:** 对CUSTOMERS执行相同的操作。
→ 标记冗余的左前缀索引(`IDX_CUST_NAME`)、不活动的索引(`IDX_CUST_CITY`)和低选择性索引(`IDX_CUST_STATUS`)。
### 5. 审计模式健康状况
> **您:** 审计NOPK_LOG表。
→ **`fb_audit_table`** → *"🛑 关键 - 表NOPK_LOG没有主键 …"*,并附带 `ALTER TABLE … ADD CONSTRAINT` 修复。在 `OVERIDX` 上报告索引过多;在 `STALE_T` 上报告统计数据过时,并附带 `SET STATISTICS INDEX …` 修复。
> **您:** 对数据库运行完整的健康检查。
→ Claude 使用 **`health_check`** 提示:`fb_info` → `fb_list_tables` → `fb_suggest_index_drops` → 对每个表进行汇总,并附带所有可立即运行的SQL。
### 6. 以目标为驱动的优化(迭代直至达到目标)
**`optimization_goal`** 提示使Claude循环:测量 → 建议 → 重新测量,直到达到目标(或无法改进)。
> **您:** 使用 `optimization_goal` 提示 - 持续优化,直到此查询不再进行自然扫描:
> `SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'`
Claude:
1. 调用 **`fb_evaluate_goal`** (`goal_type=query_no_natural_scan`) → `met: false` (基线)。
2. 调用 `fb_analyze_query` + `fb_suggest_indexes`,并呈现 `CREATE INDEX IDX_CUSTOMERS_CITY …`。
3. 您运行SQL(默认情况下写入是关闭的 - 请参见 [安全性](#安全性和兼容性))。
4. 再次调用 `fb_evaluate_goal` → `met: true`,并停止并返回结果。
您也可以以数字形式设定目标,例如 *"将此查询时间控制在50毫秒以内"* (`goal_type=query_time_ms`,`threshold=50`)。
---
## 工作会话:优化 `employee.fdb` 上的查询
针对Firebird自带的示例数据库 `employee` (`examples/empbuild/employee.fdb`)进行完整的往返操作。下面输出的结果是工具的直接输出。
> **您:** 分析此Firebird查询并建议改进:
> ```sql
> SELECT emp_no, first_name, last_name, salary
> FROM employee
> WHERE salary > 60000
> ```
**1. 基线 - `fb_analyze_query` 返回(引擎 `3.0.12`):**
```
PLAN (EMPLOYEE NATURAL)
```
> 自然扫描:EMPLOYEE。 为此查询运行 `fb_suggest_indexes` 以获取即刻可运行的DDL。
`NATURAL` 表示Firebird读取 **每条** `EMPLOYEE` 记录,并丢弃 `salary <= 60000` 的记录 - 对 `SALARY` 没有索引可以用于查找。
**2. 确认问题 - `fb_evaluate_goal` (`goal_type=query_no_natural_scan`):**
```json
{ "goal_type": "query_no_natural_scan", "measured": 1.0, "met": false,
"iteration_hint": "plan: PLAN (EMPLOYEE NATURAL)", "engine_version": "3.0.12" }
```
**3. 获取修复 - `fb_suggest_indexes`:**
```sql
CREATE INDEX IDX_EMPLOYEE_SALARY ON EMPLOYEE (salary);
```
> **验证:** 重新运行 `fb_analyze_query`;计划应使用 `IDX_EMPLOYEE_SALARY` 而不再显示 `EMPLOYEE NATURAL`。然后运行 `SET STATISTICS INDEX IDX_EMPLOYEE_SALARY;` 以刷新选择性。
**4. 应用修复** (默认情况下写入是关闭的 - 自己运行DDL,或设置 `firebird.allow_ddl=true`),然后 **重新分析**:计划变为 `PLAN (EMPLOYEE INDEX (IDX_EMPLOYEE_SALARY))`,并且 `fb_evaluate_goal` 返回 `met: true`。
**何时不添加索引。** 收益来自 `salary > 60000` 具有 **选择性** (少量记录)。如果谓词匹配大部分表格(例如 `salary > 0`),自然扫描实际上是更廉价的计划,而索引只会增加写入开销 - 并非每种自然扫描都是错误。
---
## 工具参考
一些调用示例(MCP `tools/call` `arguments`):
```jsonc
// 描述表
{ "name": "fb_describe_table", "arguments": { "table_name": "CUSTOMERS" } }
// 分析查询计划(标记自然扫描和外部排序)
{ "name": "fb_analyze_query", "arguments": { "sql": "SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'" } }
// 为慢查询建议索引
{ "name": "fb_suggest_indexes", "arguments": { "sql": "SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'" } }
// 表上哪些索引可以删除
{ "name": "fb_suggest_index_drops", "arguments": { "table_name": "ORDERS" } }
// 模式健康审计
{ "name": "fb_audit_table", "arguments": { "table_name": "NOPK_LOG" } }
// 目标检查:"此查询不再进行自然扫描"
{ "name": "fb_evaluate_goal",
"arguments": { "goal_type": "query_no_natural_scan",
"target": "SELECT * FROM CUSTOMERS WHERE CITY = 'Rome'",
"threshold": 0 } }
```
`fb_evaluate_goal` 支持的 `goal_type` 值在M1中:`query_no_natural_scan`、`query_time_ms`、`no_redundant_indexes`。有关工具检测的所有问题、引发问题的固定程序和里程碑,请参见 [`docs/firebird-problem-catalog.md`](docs/firebird-problem-catalog.md)。
---
## 测试项目
测试套件针对 **真实Firebird服务器** 运行 **DUnitX核心测试** (2.5 → 5.0),以及 **Python stdio兼容性套件** 和 **核心边界检查**。
### 测试矩阵的前提条件
- Firebird zip-kits存在于 `fb_versions/` 下(`tests/fbkit.versions.psd1`中的路径/端口)。端口:**2.5 → 3070**,3.0 → 3053,4.0 → 3054,5.0 → 3055。
- **一次性**每个工具包:zip-kits不附带可用的 `SYSDBA`。服务器停止后,以嵌入模式创建(适用于3.0/4.0/5.0;2.5开箱即用):
```
<kit>\isql.exe -user SYSDBA "<kit>\security<N>.fdb"
CREATE USER SYSDBA PASSWORD 'masterkey';
COMMIT; QUIT;
```
(`security3.fdb` / `security4.fdb` / `security5.fdb`)。
- 带有 `pytest` 的Python 3(`python -m pip install pytest`)。
### 运行所有测试(一条命令)
```powershell
pwsh tests/run_all.ps1
```
#### 或通过PyInvoke(`tasks.py`)
`tasks.py` 封装了整个构建 + 测试工作流程(`python -m pip install invoke`):
```powershell
invoke --list # 显示所有任务
invoke build # 构建核心测试项目 + MCP应用
invoke core --version 5.0 # 针对一个FB版本的核心套件(启动/种子/测试/停止)
invoke matrix # 针对每个存在的FB版本的完整套件
invoke compliance # Python stdio MCP兼容性套件(在FB 5.0上)
invoke boundary # 强制核心/MVCFramework边界
invoke all # 完整的 run_all.ps1(矩阵 + 边界 + 兼容性)
```
每个存在的工具包:启动服务器 → 播种一个全新的 `TESTDB.FDB` → 运行核心可执行文件 → 停止服务器;然后运行边界检查和Python套件(在5.0上)。预期尾部:
```
==== Core suite on FB 2.5 ==== ... 27 passed / 3 ignored
==== Core suite on FB 3.0 ==== ... 27 passed / 3 ignored
==== Core suite on FB 4.0 ==== ... 27 passed / 3 ignored
==== Core suite on FB 5.0 ==== ... 27 passed / 3 ignored
Core boundary OK: no MVCFramework imports in sources/
7 passed
ALL SUITES PASSED
```
(3个 **被忽略** 的测试是M2待定检测器,保持可见作为待办事项。)
### 针对单个版本运行
```powershell
pwsh tests/fbkit.ps1 -Action start -Version 5.0
pwsh tests/seed/make_seed.ps1 -Version 5.0
$env:FBTEST_PORT='3055'
$env:FBTEST_DB='C:\DEV\mcp-firebird\tests\seed\TESTDB.FDB'
$env:FBTEST_CLIENTLIB=(pwsh tests/fbkit.ps1 -Action client -Version 5.0)
& 'C:\DEV\mcp-firebird\tests\coreproject\MCPFirebirdCoreTests.exe'
pwsh tests/fbkit.ps1 -Action stop -Version 5.0
```
### 仅限Python兼容性
```powershell
pwsh tests/fbkit.ps1 -Action start -Version 5.0
pwsh tests/seed/make_seed.ps1 -Version 5.0
python -m pytest tests/test_mcp_firebird_stdio.py -v
pwsh tests/fbkit.ps1 -Action stop -Version 5.0
```
---
## 故障排除
| 症状 | 可能的原因 / 修复 |
|---|---|
| 客户端显示服务器但 **无工具** | `bin\.env` 缺失或数据库无法访问 — 服务器启动但工具连接失败。 使用[手动烟雾测试](#手动运行和验证)进行测试。 |
| `Your user name and password are not defined` (SQLSTATE 28000) | 错误的凭证,或没有 `SYSDBA` 的zip-kit — 请参见上面的 一次性初始化。 |
| 分析工具在 **远程** 数据库上返回空值 / 没有自然扫描 | 确保 `firebird.host` 是实际主机(计划分析器使用配置的主机)。 |
| `fbclient.dll` 未找到 / 错误位数 | 将 `firebird.client_lib` 设置为 **Win64** `fbclient.dll`;5.0客户端适用于2.5–5.0。 |
| 标准输出有非JSON噪音 | 日志必须仅输出到文件 — 保留 `logger.config.file=loggerpro.stdio.json`。 |
| 另一个Firebird占用端口3050 | 使用不同的端口(测试工具将FB 2.5放在 **3070** 以避免此问题)。 |
---
## 安全性和兼容性
- **默认情况下为只读。** 计划的写入/DDL工具(M3)需要 `firebird.allow_ddl=true`。
- **跨版本。** 能力检测根据连接的引擎调整功能使用(MON$表、解释计划、BOOLEAN、INT128、时区、并行工作线程)到FB 2.5 / 3.0 / 4.0 / 5.0。
- **每个服务器实例的单个配置数据库** (为多个数据库运行多个实例)。
---
## 许可证
根据 **Apache License 2.0** 授权 — 参见 [`LICENSE`](LICENSE) 和 [`NOTICE`](NOTICE)。
MCP Firebird是 [mcp-server-delphi](https://github.com/danieleteti/mcp-server-delphi) 的演示。如果您在Delphi中构建自己的MCP服务器,请从那里开始。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器