内容
# 🚀 C64 模型上下文协议(MCP)
[](https://docs.datacontexthub.com/)

[](LICENSE)
---
MCP 资源服务器:
- 对 Keycloak 进行身份验证
- 发现可用的视图、函数和代理系统
- 将选定的项目注册为 MCP 工具
- 通过 FastMCP 提供服务(`streamable-http` 或 `sse`)
---
## 📋 要求
- Python `>=3.12.9`
- 网络访问:
- 认证服务器(`AUTH_HOST` / realm)
- 联结数据 API
- 图形构建服务 API
- M4AI API
## 🔧 安装
```bash
uv sync
```
## ⚙️ 配置
配置从环境变量(和存储库根目录中的 `.env`)中加载。
| 变量 | 默认值 | 描述 |
|---|---|---|
| `MCP_HOST` | `localhost` | MCP 服务器绑定主机 |
| `MCP_PORT` | `8001` | MCP 服务器绑定端口 |
| `MCP_SSL_ENABLED` | `false` | 如果为 `true`,则 MCP 服务器 URL 构建为 `https://...`;否则为 `http://...` |
| `TRANSPORT` | `streamable-http` | MCP 传输(`streamable-http` 或 `sse`) |
| `AUTH_HOST` | `https://auth.example.com/auth` | Keycloak 基本主机,用于构造服务器端身份验证元数据/ introspection 的 OIDC 端点 |
| `AUTH_REALM` | `your-realm` | 与 `AUTH_HOST` 配合使用的 Keycloak Realm |
| `OAUTH_CLIENT_ID` | `your-oauth-client-id` | MCP 资源服务器身份验证设置/ introspection 验证器使用的 OAuth 客户端 ID |
| `OAUTH_CLIENT_SECRET` | `your-oauth-client-secret` | 与 `OAUTH_CLIENT_ID` 配对的 OAuth 客户端密钥 |
| `OAUTH_STRICT` | `false` | OAuth 严格模式标志 |
| `KEYCLOAK_TOKEN_URL` | `${AUTH_HOST}/realms/${AUTH_REALM}/protocol/openid-connect/token` | CLI 登录流程(密码 + 刷新授权)使用的令牌端点 |
| `KEYCLOAK_CLIENT_ID` | `your-keycloak-client-id` | CLI 登录/令牌客户端发送的客户端 ID |
| `KEYCLOAK_SCOPE` | `email profile offline_access` | CLI 登录/令牌客户端请求的范围 |
| `KEYCLOAK_GRANT_TYPE` | `password` | 用户名/密码登录使用的授权类型 |
| `DCH_USERNAME` | 无 | 启动时未提供 `--username` 时的默认用户名 |
| `DCH_PASSWORD` | 无 | 启动时未提供 `--password` 时的默认密码 |
| `DCH_VIEWS` | 无 | 非交互式选择使用的逗号分隔的视图 ID |
| `DCH_FUNCTIONS` | 无 | 非交互式选择使用的逗号分隔的函数 ID |
| `DCH_AGENT_SYSTEMS` | 无 | 非交互式选择使用的逗号分隔的代理系统 ID |
| `GRAPH_BUILDER_SERVICES_BASE_URL` | `https://api.example.com/gbs` | 图形构建服务 API 的基本 URL |
| `LINKED_DATA_API_BASE_URL` | `https://api.example.com/linked-data-api` | 联结数据 API 的基本 URL |
| `M4AI_BASE_URL` | `https://api.example.com/m4ai` | M4AI API 的基本 URL |
### 💡 `AUTH_*` vs `KEYCLOAK_*`
- `AUTH_*` 控制 MCP 服务器如何公开和验证 OAuth/OIDC 集成(发行者/ introspection/授权元数据)。它是面向服务器的身份验证配置。
- `KEYCLOAK_*` 控制此脚本如何登录用户并在启动工具发现期间刷新令牌(`KeycloakAuthClient`)。它是面向客户端的令牌获取配置。
- 在许多设置中,这些都指向同一个 Keycloak Realm,但它们可以根据您的安全模型使用不同的客户端 ID/密钥。
示例 `.env`:
```env
MCP_HOST=localhost
MCP_PORT=8001
MCP_SSL_ENABLED=false
TRANSPORT=streamable-http
AUTH_HOST=https://auth.example.com/auth
AUTH_REALM=your-realm
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-secret
OAUTH_STRICT=false
KEYCLOAK_TOKEN_URL=https://auth.example.com/auth/realms/your-realm/protocol/openid-connect/token
KEYCLOAK_CLIENT_ID=your-keycloak-client-id
KEYCLOAK_SCOPE="email profile offline_access"
KEYCLOAK_GRANT_TYPE=password
DCH_USERNAME=your.username
DCH_PASSWORD=your-password
DCH_VIEWS=view-id-123,view-id-456
DCH_FUNCTIONS=77,81
DCH_AGENT_SYSTEMS=14,21
GRAPH_BUILDER_SERVICES_BASE_URL=https://api.example.com/gbs
LINKED_DATA_API_BASE_URL=https://api.example.com/linked-data-api
M4AI_BASE_URL=https://api.example.com/m4ai
```
## 🗝️ 配置 Keycloak 客户端(用于 MCP 身份验证)
获取此 MCP 服务器所需的凭证的最低设置:
1. 确保您对 Keycloak 具有管理员访问权限。
2. 选择目标 Realm。
3. 进入 `Clients` 并点击 `Create client`。
4. 设置:
- 客户端类型:`OpenID Connect`
- 客户端 ID:您的客户端 ID
- 客户端名称:您的客户端名称
- 描述:可选
5. 点击 `Next`。
6. 启用 `Client authentication`(切换为 ON)。
7. 在身份验证流程中,启用 `Standard flow`。
8. 点击 `Next`。
9. 将 `Valid redirect URIs` 设置为客户端可用的位置,通常为 `http://localhost:*`。
10. 创建/保存客户端。
11. 打开创建的客户端,进入 `Credentials`,复制/创建客户端密钥。
此时,您拥有最低要求的数值:
- 客户端 ID
- 客户端密钥
- Realm
- 身份验证主机
在 `.env` 中使用这些值:
```env
AUTH_HOST=https://<your-keycloak-host>/auth
AUTH_REALM=<your-realm>
OAUTH_CLIENT_ID=<client-id>
OAUTH_CLIENT_SECRET=<client-secret>
KEYCLOAK_CLIENT_ID=<client-id>
KEYCLOAK_TOKEN_URL=https://<your-keycloak-host>/auth/realms/<your-realm>/protocol/openid-connect/token
```
## ▶️ 运行
基本运行:
```bash
uv run python main.py
```
使用显式凭证:
```bash
uv run python main.py --username my.user --password '***'
```
使用环境凭证:
```bash
export DCH_USERNAME=my.user
export DCH_PASSWORD='***'
uv run python main.py
```
启用凭证缓存:
```bash
uv run python main.py --cache-credentials
```
直接从 CLI 选择:
```bash
uv run python main.py \
--views view-id-123,view-id-456 \
--functions 77,81 \
--agent-systems 14,21
```
使用分页/限制:
```bash
uv run python main.py \
--views-limit 50 \
--functions-page-size 50 \
--agent-systems-page-size 50
```
这些值控制交互式选择页面大小。额外的页面在您在选择器 UI 中移动页面时延迟获取。
## 💻 开发
运行 Ruff lint 检查:
```bash
uv run ruff check .
```
使用 Ruff 自动格式化代码库:
```bash
uv run ruff format .
```
## 🤖 Claude 桌面集成
将此 MCP 服务器条目添加到您的 `claude_desktop_config.json` 中,位于 `mcpServers` 下。
使用您自己的本地值作为二进制路径、MCP URL、OAuth 客户端 ID 和客户端密钥。
```json
{
"mcpServers": {
"c64-mcp": {
"command": "/path/to/npx",
"args": [
"mcp-remote",
"<mcp_server_url>",
"--static-oauth-client-info",
"{\"client_id\":\"your-client-id\",\"client_secret\":\"your-client-secret\"}"
]
}
},
...
}
```
## 📝 CLI 选项
```text
--username
--password
--views
--functions
--agent-systems
--cache-credentials
--views-limit
--functions-page-size
--agent-systems-page-size
--selection-config
--output-selection-as-config
```
`--selection-config` 是可选的。如果省略,脚本将使用交互式选择。
`--cache-credentials` 是可选的。如果省略,则不会读取或写入 `.credentials_cache`。
环境凭证也通过 `DCH_USERNAME` 和 `DCH_PASSWORD` 支持。
也可以通过 `--views`、 `--functions`、 `--agent-systems` 或 `DCH_VIEWS`、 `DCH_FUNCTIONS`、 `DCH_AGENT_SYSTEMS` 直接提供选择。
## 🔐 身份验证和令牌缓存
刷新令牌缓存文件:`.credentials_cache`(在 `main.py` 旁边)。
启动身份验证流程,启用 `--cache-credentials`:
1. 尝试缓存的刷新令牌。
2. 如果无效/缺失,则使用 `--username` / `--password`、 `DCH_USERNAME` / `DCH_PASSWORD` 进行身份验证,然后在仍需要时提示。
3. 在可用时保存新的刷新令牌。
4. 继续进行视图/函数/代理系统发现。
启动身份验证流程时未启用 `--cache-credentials`:
1. 跳过读取 `.credentials_cache`。
2. 使用 `--username` / `--password`、 `DCH_USERNAME` / `DCH_PASSWORD` 进行身份验证,然后在仍需要时提示。
3. 不写入 `.credentials_cache`。
4. 继续进行视图/函数/代理系统发现。
在 API 调用期间,如果访问令牌过期(`401`),脚本会刷新并重试。
重要行为:
- 如果启用了凭证缓存,并且没有缓存令牌,则在读取 `--selection-config` 之前会提示登录。
- CLI 标志优先于 `DCH_USERNAME` 和 `DCH_PASSWORD`。
- 对于直接选择,CLI 参数优先于 `DCH_VIEWS`、 `DCH_FUNCTIONS` 和 `DCH_AGENT_SYSTEMS`。
## 🧰 工具选择模式
### 1) 交互模式(默认)
当未提供选择配置、直接选择 CLI 参数或直接选择环境变量时:
- 脚本按需从 API 获取选择页面
- 显示复选框样式的选择器,用于:
- 视图
- 函数
- 代理系统
- 在 TTY 模式下,左右箭头键或 `a` / `d` 移动页面,在提示模式下,`n` 和 `p` 移动页面
- 项目编号在所有页面上全局唯一,因此在浏览结果时,显示的编号保持稳定
- 选定的项目注册为 MCP 工具
### 2) 直接 ID 选择( `--views`、 `--functions`、 `--agent-systems`)
直接在命令行上提供逗号分隔的 ID:
```bash
uv run python main.py \
--views view-id-123,view-id-456 \
--functions 77,81 \
--agent-systems 14,21
```
或通过环境变量:
```bash
export DCH_VIEWS=view-id-123,view-id-456
export DCH_FUNCTIONS=77,81
export DCH_AGENT_SYSTEMS=14,21
uv run python main.py
```
这些使用与 JSON 配置模式相同的 ID 仅解析规则。缺失的类别默认为空选择。
### 3) JSON 配置模式( `--selection-config`)
提供一个定义选择内容的 JSON 文件。
示例:
```json
{
"views": [
"view-id-123",
"view-id-456"
],
"functions": [
77,
81
],
"agent_systems": [
14,
21
]
}
```
也接受:
- `agentSystems`(驼峰式)代替 `agent_systems`
### 📋 配置规则
每个条目在:
- `views` 必须是视图 ID
- `functions` 必须是函数 ID
- `agent_systems` 必须是代理系统 ID
当使用 `--selection-config` 时,服务器直接按 ID 获取每个选定的实体,并使用获取的详细信息按配置文件顺序构建 MCP 工具。
如果任何 ID 无法解析,则启动失败,并显示清晰的 CLI 错误。
使用选择文件运行:
```bash
uv run python main.py --selection-config ./selection.json
```
### 📤 导出终端选择到配置
在交互模式下运行,您可以导出所选项目:
```bash
uv run python main.py --output-selection-as-config ./selection.json
```
这会写入一个包含 `views`、 `functions` 和 `agent_systems` 的 JSON 文件,基于您的终端选择。
导出的配置仅包含 ID。
约束:
- `--selection-config` 和 `--output-selection-as-config` 是互斥的。
- `--selection-config` 不能与 `--views`、 `--functions` 或 `--agent-systems` 组合使用。
- `--output-selection-as-config` 仅在交互模式下有效。
## 💡 注册内容
对于每个选定的实体,脚本获取详细信息并注册一个工具:
- 视图:通过 `execute_view` 执行
- 函数:通过 `execute_function` 执行
- 代理系统:通过流重建分块输出,并返回最终的最后一层结果
参数名称规范化为有效的 Python 标识符,用于工具签名。
## 🧩 示例工作流程
交互式:
```bash
uv run python main.py
```
非交互式,预定义选择:
```bash
uv run python main.py \
--selection-config ./selection.json \
--views-limit 100 \
--functions-page-size 100 \
--agent-systems-page-size 100
```
## 🧯 故障排除
- `Configuration error: Invalid transport ...`
- 将 `TRANSPORT` 设置为 `streamable-http` 或 `sse`。
- `Authentication failed ...`
- 检查用户名/密码和 Keycloak 客户端设置。
- `Failed fetching views/functions/agent systems ...`
- 验证 API 连接性和令牌范围/权限。
- `Selection config contains unknown ...`
- 确保 JSON 中的 ID 存在且可通过详细端点访问。