Metadata-Version: 2.4
Name: opc-mcp
Version: 0.2.0
Summary: MCP server for order center database access
Project-URL: Homepage, https://github.com/zhouxinhai/opc-mcp
Project-URL: Repository, https://github.com/zhouxinhai/opc-mcp
Project-URL: Issues, https://github.com/zhouxinhai/opc-mcp/issues
Author-email: zhouxinhai <your.email@example.com>
License-Expression: MIT
License-File: LICENSE
Keywords: database,mcp,mysql,oracle,order-center
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: jaydebeapi>=1.2.0
Requires-Dist: mcp[cli]>=1.0.0
Requires-Dist: mysql-connector-python>=9.7.0
Requires-Dist: pydantic>=2.0
Requires-Dist: pymysql>=1.1.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: sqlparse>=0.5.0
Description-Content-Type: text/markdown

# OPC-MCP

订单中心数据库 MCP 服务，通过 MCP 协议暴露数据库查询能力，供 AI 助手动态查询和排查订单问题。

## 功能

- **配置驱动工具** — 在 `config.yaml` 中定义 SQL 模板，自动生成 MCP 工具
- **`run_query`** — 动态执行任意 SELECT 查询，支持命名参数、LIKE 自动检测、分页
- **`query_table_desc`** — 查询表结构信息（列名、数据类型、注释），表名大小写不敏感
- **多连接池** — 支持多个数据库（opc、smc 等），连接池名称大小写不敏感
- **安全防护** — 仅允许 SELECT 语句，拒绝多语句注入，参数化查询

## 安装

```bash
pip install -e .
```

## 配置

编辑 `config.yaml`：

```yaml
server:
  host: "0.0.0.0"
  port: 8000

pools:
  opc:
    host: 10.0.0.1
    port: 1521
    user: readonly
    password: xxx
    database: opc_db
    pool_size: 5
  smc:
    host: 10.0.0.2
    port: 1521
    user: readonly
    password: xxx
    database: smc_db
    pool_size: 3

tools:
  query_sub_order:
    description: "查询子订单信息"
    pool: opc
    sql: "SELECT * FROM or_sub_order WHERE 1=1 AND order_id = :order_id AND status = :status"
    params:
      order_id:
        type: str
        description: "订单号"
      status:
        type: str
        description: "订单状态"
    limit:
      default: 50
      max: 100
    offset:
      default: 0
```

## 启动

```bash
# Streamable HTTP 模式（默认）
uv run opc-mcp --config config.yaml

# SSE 模式
uv run opc-mcp --config config.yaml --mode sse

# stdio 模式（本地进程通信）
uv run opc-mcp --config config.yaml --mode stdio

# 指定日志级别
uv run opc-mcp --config config.yaml --log-level DEBUG
```

### 连接地址

| 模式                    | 连接方式                      |
| ----------------------- | ----------------------------- |
| Streamable HTTP（默认） | `http://localhost:8000/mcp` |
| SSE                     | `http://localhost:8000/sse` |
| stdio                   | 通过 stdin/stdout 通信        |

### MCP 客户端配置

Streamable HTTP 模式：

```json
{
  "mcpServers": {
    "opc-mcp": {
      "url": "http://localhost:8000/mcp"
    }
  }
}
```

SSE 模式：

```json
{
  "mcpServers": {
    "opc-mcp": {
      "url": "http://localhost:8000/sse"
    }
  }
}
```

stdio 模式（通过 `cwd` 指定项目目录）：

- uv启动方式

```json
{
  "mcpServers": {
    "opc-mcp-stdio": {
      "command": "uv",
      "args": [
        "run",
        "opc-mcp",
        "--config",
        "config.yaml",
        "--mode",
        "stdio"
      ],
      "cwd": "D:/code/python/opc-mcp"
    }
  }
}
```

- uvx启动方式

```json
{
	"mcpServers": {
	  "opc-mcp-stdio": {
		"command": "uvx",
		"args": [
		  "--from", "D:/code/python/opc-mcp",
		  "opc-mcp",
		  "--config", "D:/code/python/opc-mcp/config.yaml",
		  "--mode", "stdio"
		]
	  }
	}
}
```

## MCP 工具

### run_query

动态执行 SELECT 查询，支持命名参数和分页。

**参数：**

| 参数   | 类型    | 必填 | 说明                                    |
| ------ | ------- | ---- | --------------------------------------- |
| sql    | string  | 是   | SELECT SQL，使用 `:param_name` 占位符 |
| params | object  | 否   | 命名参数，key 大小写不敏感              |
| pool   | string  | 否   | 连接池名称，默认 `opc`                |
| limit  | integer | 否   | 返回行数限制，默认 50，最大 200         |
| offset | integer | 否   | 分页偏移量，默认 0                      |

**示例：**

```json
{
  "sql": "SELECT * FROM or_dict_def WHERE dict_type = :dict_type AND dict_class = :dict_class",
  "params": {"dict_type": 18, "dict_class": 1},
  "pool": "opc"
}
```

支持 JOIN、GROUP BY、子查询、UNION、聚合等复杂查询。LIKE 条件自动检测并包裹 `%`。

### query_table_desc

查询表的列结构信息。

**参数：**

| 参数       | 类型   | 必填 | 说明               |
| ---------- | ------ | ---- | ------------------ |
| table_name | string | 是   | 表名，大小写不敏感 |
| pool       | string | 是   | 连接池名称         |

**示例：**

```json
{
  "table_name": "or_dict_def",
  "pool": "opc"
}
```

**返回：**

```json
{
  "table_name": "OR_DICT_DEF",
  "count": 5,
  "columns": [
    {"table_name": "OR_DICT_DEF", "column_name": "DICT_TYPE", "data_type": "NUMBER", "comments": "字典类型"},
    {"table_name": "OR_DICT_DEF", "column_name": "DICT_NAME", "data_type": "VARCHAR2", "comments": "字典名称"}
  ]
}
```

## PrefabSQL 工具

用于 SQL 代码双向溯源的工具集。从 `SMC_PREFAB_SQL_STATEMENT` 表加载 SQL 配置到本地 SQLite 缓存，支持：

- **正向追踪**：sqlId → SQL 语句 → 操作类型 → 涉及的表
- **反向溯源**：表名 → 相关 sqlId 列表

### create_prefab_sql_cache

创建或刷新本地 SQLite 缓存。首次调用时从数据库加载数据。

**参数：**

| 参数           | 类型    | 必填 | 说明                               |
| -------------- | ------- | ---- | ---------------------------------- |
| force_refresh  | boolean | 否   | 强制刷新缓存，默认 false           |

**配置（config.yaml）：**

```yaml
prefab_sql:
  enabled: true
  pool: smc
  sql: "SELECT SQL_ID, SQL_STATEMENT FROM SMC_PREFAB_SQL_STATEMENT ORDER BY SQL_ID"
```

**示例：**

```json
{"force_refresh": true}
```

**返回：**

```json
{"status": "success", "count": 1234, "cache_path": "~/.prefab-sql/cache.db"}
```

### query_sql_by_id

根据 sqlId 查询 SQL 语句。

**参数：**

| 参数    | 类型   | 必填 | 说明                |
| ------- | ------ | ---- | ------------------- |
| sql_id  | string | 是   | SQL ID（如 10511206）|

**示例：**

```json
{"sql_id": "10511206"}
```

**返回：**

```json
{
  "status": "found",
  "data": {
    "sql_id": "10511206",
    "sql_statement": "INSERT INTO or_message_delay_req ...",
    "operation_type": "INSERT",
    "tables": ["OR_MESSAGE_DELAY_REQ"]
  }
}
```

### find_sql_by_table

根据表名查找相关的 sqlId。

**参数：**

| 参数       | 类型    | 必填 | 说明                         |
| ---------- | ------- | ---- | ---------------------------- |
| table_name | string  | 是   | 表名（支持模糊匹配）         |
| limit      | integer | 否   | 返回数量限制，默认 100       |

**示例：**

```json
{"table_name": "or_message_delay_req", "limit": 50}
```

**返回：**

```json
{
  "status": "success",
  "table_name": "or_message_delay_req",
  "count": 3,
  "data": [
    {"sql_id": "10511206", "operation_type": "INSERT", "tables": ["OR_MESSAGE_DELAY_REQ"]},
    {"sql_id": "10511207", "operation_type": "SELECT", "tables": ["OR_MESSAGE_DELAY_REQ"]}
  ]
}
```

### prefab_sql_stats

获取缓存统计信息。

**返回：**

```json
{
  "status": "success",
  "stats": {
    "total_count": 1234,
    "by_operation_type": {"SELECT": 800, "INSERT": 300, "UPDATE": 100, "DELETE": 34},
    "cache_path": "~/.prefab-sql/cache.db"
  }
}
```

## 测试

```bash
pytest tests/ -v
```

## 项目结构

```
src/opc_mcp/
  main.py             # 入口，服务创建与启动
  config.py           # 配置模型（AppConfig, ToolConfig, PoolConfig）
  pool_manager.py     # 连接池管理
  handlers.py         # 工具执行逻辑
  register.py         # MCP 工具注册
  tools.py            # SQL 校验、参数绑定等工具函数
  prefab_sql_cache.py # PrefabSQL SQLite 缓存管理
  sql_parser.py       # SQL 解析（提取表名、操作类型）
```
