wk-ocr-mcp 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wk-ocr-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for OCR text recognition service (RapidOCR + OpenVINO)
|
|
5
|
+
Project-URL: Homepage, https://github.com/your-org/wk-ocr-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/your-org/wk-ocr-mcp
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: claude-code,mcp,ocr,rapidocr,text-recognition
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: httpx>=0.27.0
|
|
20
|
+
Requires-Dist: mcp>=1.0.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# OCR MCP Server
|
|
24
|
+
|
|
25
|
+
MCP (Model Context Protocol) 服务器,让 Claude Code / Cursor / Windsurf 等 AI 编码工具通过 MCP 协议直接调用 OCR 文字识别服务。
|
|
26
|
+
|
|
27
|
+
## 功能
|
|
28
|
+
|
|
29
|
+
| Tool | 说明 |
|
|
30
|
+
|------|------|
|
|
31
|
+
| `ocr_recognize` | 图片文字识别 - 从任意包含文字的图片中提取文本内容 |
|
|
32
|
+
| `ocr_table` | 表格识别 - 从图片中提取表格的行列结构化数据 |
|
|
33
|
+
| `ocr_health` | 服务健康检查 - 验证后端 OCR 服务是否正常运行 |
|
|
34
|
+
|
|
35
|
+
## 环境变量
|
|
36
|
+
|
|
37
|
+
| 变量 | 默认值 | 说明 |
|
|
38
|
+
|------|--------|------|
|
|
39
|
+
| `OCR_SERVICE_URL` | `http://127.0.0.1:8082` | OCR 后端服务地址 |
|
|
40
|
+
| `OCR_PUBLIC_URL` | `https://gogs.wxapp.info/ocr-api` | 公开访问地址(仅供参考) |
|
|
41
|
+
|
|
42
|
+
## 安装
|
|
43
|
+
|
|
44
|
+
### 方式一:pip 安装
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 方式二:uvx 直接运行(无需安装)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
uvx wk-ocr-mcp
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Claude Code 接入配置
|
|
57
|
+
|
|
58
|
+
在 `~/.claude/settings.json` 中添加:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"ocr": {
|
|
64
|
+
"command": "uvx",
|
|
65
|
+
"args": ["wk-ocr-mcp"],
|
|
66
|
+
"env": {
|
|
67
|
+
"OCR_SERVICE_URL": "https://gogs.wxapp.info/ocr-api"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
或使用 pip 安装后的命令:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"mcpServers": {
|
|
79
|
+
"ocr": {
|
|
80
|
+
"command": "wk-ocr-mcp"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 开发/本地测试
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 克隆后本地安装
|
|
90
|
+
cd /lio/projects/ocr-mcp-server
|
|
91
|
+
pip install -e .
|
|
92
|
+
|
|
93
|
+
# 直接运行
|
|
94
|
+
python -m ocr_mcp_server
|
|
95
|
+
|
|
96
|
+
# 或
|
|
97
|
+
ocr-mcp-server
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## OCR API 端点
|
|
101
|
+
|
|
102
|
+
服务暴露以下 HTTP API(由 `OCR_SERVICE_URL` 指定的后端):
|
|
103
|
+
|
|
104
|
+
- `POST /api/ocr` - 文字识别(form: image_base64)
|
|
105
|
+
- `POST /api/table` - 表格识别(form: image_base64)
|
|
106
|
+
- `GET /api/health` - 健康检查
|
|
107
|
+
|
|
108
|
+
## 使用示例
|
|
109
|
+
|
|
110
|
+
### Claude Code 中使用
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
/ OCR识别截图
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
或通过 MCP tool 直接调用 `ocr_recognize` 或 `ocr_table`。
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# OCR MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) 服务器,让 Claude Code / Cursor / Windsurf 等 AI 编码工具通过 MCP 协议直接调用 OCR 文字识别服务。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
| Tool | 说明 |
|
|
8
|
+
|------|------|
|
|
9
|
+
| `ocr_recognize` | 图片文字识别 - 从任意包含文字的图片中提取文本内容 |
|
|
10
|
+
| `ocr_table` | 表格识别 - 从图片中提取表格的行列结构化数据 |
|
|
11
|
+
| `ocr_health` | 服务健康检查 - 验证后端 OCR 服务是否正常运行 |
|
|
12
|
+
|
|
13
|
+
## 环境变量
|
|
14
|
+
|
|
15
|
+
| 变量 | 默认值 | 说明 |
|
|
16
|
+
|------|--------|------|
|
|
17
|
+
| `OCR_SERVICE_URL` | `http://127.0.0.1:8082` | OCR 后端服务地址 |
|
|
18
|
+
| `OCR_PUBLIC_URL` | `https://gogs.wxapp.info/ocr-api` | 公开访问地址(仅供参考) |
|
|
19
|
+
|
|
20
|
+
## 安装
|
|
21
|
+
|
|
22
|
+
### 方式一:pip 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 方式二:uvx 直接运行(无需安装)
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uvx wk-ocr-mcp
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Claude Code 接入配置
|
|
35
|
+
|
|
36
|
+
在 `~/.claude/settings.json` 中添加:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"mcpServers": {
|
|
41
|
+
"ocr": {
|
|
42
|
+
"command": "uvx",
|
|
43
|
+
"args": ["wk-ocr-mcp"],
|
|
44
|
+
"env": {
|
|
45
|
+
"OCR_SERVICE_URL": "https://gogs.wxapp.info/ocr-api"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
或使用 pip 安装后的命令:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"mcpServers": {
|
|
57
|
+
"ocr": {
|
|
58
|
+
"command": "wk-ocr-mcp"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 开发/本地测试
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# 克隆后本地安装
|
|
68
|
+
cd /lio/projects/ocr-mcp-server
|
|
69
|
+
pip install -e .
|
|
70
|
+
|
|
71
|
+
# 直接运行
|
|
72
|
+
python -m ocr_mcp_server
|
|
73
|
+
|
|
74
|
+
# 或
|
|
75
|
+
ocr-mcp-server
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## OCR API 端点
|
|
79
|
+
|
|
80
|
+
服务暴露以下 HTTP API(由 `OCR_SERVICE_URL` 指定的后端):
|
|
81
|
+
|
|
82
|
+
- `POST /api/ocr` - 文字识别(form: image_base64)
|
|
83
|
+
- `POST /api/table` - 表格识别(form: image_base64)
|
|
84
|
+
- `GET /api/health` - 健康检查
|
|
85
|
+
|
|
86
|
+
## 使用示例
|
|
87
|
+
|
|
88
|
+
### Claude Code 中使用
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
/ OCR识别截图
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
或通过 MCP tool 直接调用 `ocr_recognize` 或 `ocr_table`。
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "wk-ocr-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server for OCR text recognition service (RapidOCR + OpenVINO)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
keywords = ["mcp", "ocr", "text-recognition", "rapidocr", "claude-code"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 4 - Beta",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Topic :: Multimedia :: Graphics",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"mcp>=1.0.0",
|
|
26
|
+
"httpx>=0.27.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
wk-ocr-mcp = "ocr_mcp_server.server:mcp.run"
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/your-org/wk-ocr-mcp"
|
|
34
|
+
Repository = "https://github.com/your-org/wk-ocr-mcp"
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.targets.wheel]
|
|
37
|
+
packages = ["src/ocr_mcp_server"]
|
|
File without changes
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
import base64
|
|
4
|
+
import httpx
|
|
5
|
+
from mcp.server.fastmcp import FastMCP
|
|
6
|
+
|
|
7
|
+
mcp = FastMCP("ocr-service")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _get_service_url() -> str:
|
|
11
|
+
return os.environ.get("OCR_SERVICE_URL", "http://127.0.0.1:8082")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _clean_base64(data: str) -> str:
|
|
15
|
+
"""Extract raw base64 from data URI if needed"""
|
|
16
|
+
if data.startswith("data:"):
|
|
17
|
+
return data.split(",", 1)[1] if "," in data else data
|
|
18
|
+
return data
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def _get_image_base64(image_base64: str = "", image_url: str = "") -> str:
|
|
22
|
+
"""Resolve image source to base64. Returns cleaned base64 string."""
|
|
23
|
+
if image_base64:
|
|
24
|
+
return _clean_base64(image_base64)
|
|
25
|
+
|
|
26
|
+
if image_url:
|
|
27
|
+
async with httpx.AsyncClient(timeout=30.0) as client:
|
|
28
|
+
response = await client.get(image_url)
|
|
29
|
+
response.raise_for_status()
|
|
30
|
+
return base64.b64encode(response.content).decode("utf-8")
|
|
31
|
+
|
|
32
|
+
raise ValueError("Either image_base64 or image_url must be provided")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@mcp.tool()
|
|
36
|
+
async def ocr_recognize(image_base64: str = "", image_url: str = "") -> str:
|
|
37
|
+
"""OCR文字识别 - 从图片或PDF中提取文字内容。
|
|
38
|
+
|
|
39
|
+
适用场景:
|
|
40
|
+
- 截图、照片中的文字提取
|
|
41
|
+
- 扫描文档的文字识别
|
|
42
|
+
- 代码截图转文本
|
|
43
|
+
- 任意包含文字的图片转文本
|
|
44
|
+
|
|
45
|
+
参数:
|
|
46
|
+
- image_base64: 图片的base64编码(纯base64或data URI格式如data:image/png;base64,xxx)
|
|
47
|
+
- image_url: 图片URL地址(服务器自动下载识别,与base64二选一)
|
|
48
|
+
|
|
49
|
+
返回:识别的文字内容、行数、耗时等信息(JSON格式)
|
|
50
|
+
"""
|
|
51
|
+
try:
|
|
52
|
+
b64_data = await _get_image_base64(image_base64, image_url)
|
|
53
|
+
|
|
54
|
+
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
55
|
+
response = await client.post(
|
|
56
|
+
f"{_get_service_url()}/api/ocr",
|
|
57
|
+
data={"image_base64": b64_data},
|
|
58
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
59
|
+
)
|
|
60
|
+
response.raise_for_status()
|
|
61
|
+
return json.dumps(response.json(), ensure_ascii=False, indent=2)
|
|
62
|
+
|
|
63
|
+
except httpx.HTTPStatusError as e:
|
|
64
|
+
return json.dumps({"error": f"OCR服务HTTP错误: {e.response.status_code}", "detail": e.response.text}, ensure_ascii=False)
|
|
65
|
+
except httpx.RequestError as e:
|
|
66
|
+
return json.dumps({"error": f"OCR服务连接失败: {e}"}, ensure_ascii=False)
|
|
67
|
+
except ValueError as e:
|
|
68
|
+
return json.dumps({"error": f"参数错误: {e}"}, ensure_ascii=False)
|
|
69
|
+
except Exception as e:
|
|
70
|
+
return json.dumps({"error": f"OCR识别失败: {e}"}, ensure_ascii=False)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@mcp.tool()
|
|
74
|
+
async def ocr_table(image_base64: str = "", image_url: str = "") -> str:
|
|
75
|
+
"""表格识别 - 从图片中提取表格结构化数据。
|
|
76
|
+
|
|
77
|
+
适用场景:
|
|
78
|
+
- 截图表格转结构化数据
|
|
79
|
+
- 扫描表格的行列提取
|
|
80
|
+
- 任意包含表格的图片转为行列数据
|
|
81
|
+
|
|
82
|
+
参数:
|
|
83
|
+
- image_base64: 图片的base64编码(纯base64或data URI格式)
|
|
84
|
+
- image_url: 图片URL地址(服务器自动下载识别,与base64二选一)
|
|
85
|
+
|
|
86
|
+
返回:表格单元格内容(JSON格式,含行列结构)
|
|
87
|
+
"""
|
|
88
|
+
try:
|
|
89
|
+
b64_data = await _get_image_base64(image_base64, image_url)
|
|
90
|
+
|
|
91
|
+
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
92
|
+
response = await client.post(
|
|
93
|
+
f"{_get_service_url()}/api/table",
|
|
94
|
+
data={"image_base64": b64_data},
|
|
95
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
96
|
+
)
|
|
97
|
+
response.raise_for_status()
|
|
98
|
+
return json.dumps(response.json(), ensure_ascii=False, indent=2)
|
|
99
|
+
|
|
100
|
+
except httpx.HTTPStatusError as e:
|
|
101
|
+
return json.dumps({"error": f"OCR服务HTTP错误: {e.response.status_code}", "detail": e.response.text}, ensure_ascii=False)
|
|
102
|
+
except httpx.RequestError as e:
|
|
103
|
+
return json.dumps({"error": f"OCR服务连接失败: {e}"}, ensure_ascii=False)
|
|
104
|
+
except ValueError as e:
|
|
105
|
+
return json.dumps({"error": f"参数错误: {e}"}, ensure_ascii=False)
|
|
106
|
+
except Exception as e:
|
|
107
|
+
return json.dumps({"error": f"表格识别失败: {e}"}, ensure_ascii=False)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@mcp.tool()
|
|
111
|
+
async def ocr_health() -> str:
|
|
112
|
+
"""OCR服务健康检查 - 检查后端识别服务是否正常运行。
|
|
113
|
+
|
|
114
|
+
适用场景:
|
|
115
|
+
- 启动前验证服务可用性
|
|
116
|
+
- 监控服务状态
|
|
117
|
+
- 排查OCR功能异常原因
|
|
118
|
+
|
|
119
|
+
返回:服务状态信息(JSON格式)
|
|
120
|
+
"""
|
|
121
|
+
try:
|
|
122
|
+
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
123
|
+
response = await client.get(f"{_get_service_url()}/api/health")
|
|
124
|
+
response.raise_for_status()
|
|
125
|
+
return json.dumps(response.json(), ensure_ascii=False, indent=2)
|
|
126
|
+
|
|
127
|
+
except httpx.RequestError as e:
|
|
128
|
+
return json.dumps({"error": f"服务不可达: {e}"}, ensure_ascii=False)
|
|
129
|
+
except Exception as e:
|
|
130
|
+
return json.dumps({"error": f"健康检查失败: {e}"}, ensure_ascii=False)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
mcp.run()
|