sym-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.
Files changed (31) hide show
  1. sym_mcp-0.1.0/LICENSE +21 -0
  2. sym_mcp-0.1.0/PKG-INFO +274 -0
  3. sym_mcp-0.1.0/README.md +247 -0
  4. sym_mcp-0.1.0/pyproject.toml +51 -0
  5. sym_mcp-0.1.0/setup.cfg +4 -0
  6. sym_mcp-0.1.0/src/sym_mcp/__init__.py +2 -0
  7. sym_mcp-0.1.0/src/sym_mcp/__main__.py +6 -0
  8. sym_mcp-0.1.0/src/sym_mcp/config.py +27 -0
  9. sym_mcp-0.1.0/src/sym_mcp/errors/__init__.py +2 -0
  10. sym_mcp-0.1.0/src/sym_mcp/errors/parser.py +113 -0
  11. sym_mcp-0.1.0/src/sym_mcp/executor/__init__.py +2 -0
  12. sym_mcp-0.1.0/src/sym_mcp/executor/pool.py +182 -0
  13. sym_mcp-0.1.0/src/sym_mcp/executor/sandbox.py +82 -0
  14. sym_mcp-0.1.0/src/sym_mcp/executor/worker_main.py +74 -0
  15. sym_mcp-0.1.0/src/sym_mcp/schemas.py +8 -0
  16. sym_mcp-0.1.0/src/sym_mcp/security/__init__.py +2 -0
  17. sym_mcp-0.1.0/src/sym_mcp/security/ast_guard.py +190 -0
  18. sym_mcp-0.1.0/src/sym_mcp/server.py +193 -0
  19. sym_mcp-0.1.0/src/sym_mcp.egg-info/PKG-INFO +274 -0
  20. sym_mcp-0.1.0/src/sym_mcp.egg-info/SOURCES.txt +29 -0
  21. sym_mcp-0.1.0/src/sym_mcp.egg-info/dependency_links.txt +1 -0
  22. sym_mcp-0.1.0/src/sym_mcp.egg-info/entry_points.txt +2 -0
  23. sym_mcp-0.1.0/src/sym_mcp.egg-info/requires.txt +7 -0
  24. sym_mcp-0.1.0/src/sym_mcp.egg-info/top_level.txt +1 -0
  25. sym_mcp-0.1.0/tests/test_ast_guard.py +47 -0
  26. sym_mcp-0.1.0/tests/test_error_parser.py +55 -0
  27. sym_mcp-0.1.0/tests/test_math_correctness.py +40 -0
  28. sym_mcp-0.1.0/tests/test_perf_guardrails.py +64 -0
  29. sym_mcp-0.1.0/tests/test_pool.py +66 -0
  30. sym_mcp-0.1.0/tests/test_security_adversarial.py +41 -0
  31. sym_mcp-0.1.0/tests/test_server_integration.py +115 -0
sym_mcp-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tyy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
sym_mcp-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: sym-mcp
3
+ Version: 0.1.0
4
+ Summary: SymPy sandbox MCP server based on FastMCP
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/Eis4TY/Sym-MCP
7
+ Project-URL: Repository, https://github.com/Eis4TY/Sym-MCP
8
+ Project-URL: Issues, https://github.com/Eis4TY/Sym-MCP/issues
9
+ Keywords: mcp,sympy,sandbox,agent,llm,math
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: fastmcp>=3.0.0
21
+ Requires-Dist: sympy>=1.13.0
22
+ Requires-Dist: pydantic>=2.8.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
25
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # SymPy Sandbox MCP
29
+
30
+ 一个面向 Agent/LLM 的 SymPy 计算沙箱 MCP 服务。
31
+ 目标是:在保证安全隔离的前提下,提供低延迟、低 token、可稳定重试的数学计算工具。
32
+
33
+ ## 特性
34
+
35
+ - 单工具 `sympy`,输入参数仅 `code`
36
+ - 预热进程池,避免每次请求重复 `import sympy`
37
+ - 双层安全防护:AST 拦截 + 运行时资源限制
38
+ - 统一紧凑 JSON 输出,便于程序解析且节省 token
39
+ - 错误码标准化,方便 Agent 自动纠错重试
40
+
41
+ ## 适用场景
42
+
43
+ - 让 LLM 执行代数化简、求导、积分、方程求解、符号推导
44
+ - 作为 MCP Tool 接入 Codex / Cursor / Claude Desktop / 自建 MCP Client
45
+ - 需要“可控失败 + 低噪声错误信息”的自动化 Agent 工作流
46
+
47
+ ## 快速开始
48
+
49
+ ### 1) 环境要求
50
+
51
+ - Python 3.11+
52
+ - Linux / macOS(推荐 Linux 作为生产环境)
53
+
54
+ ### 2) 安装(清华源优先)
55
+
56
+ ```bash
57
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e .
58
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e ".[dev]"
59
+ ```
60
+
61
+ ### 3) 启动服务(stdio)
62
+
63
+ ```bash
64
+ python -m sym_mcp.server
65
+ ```
66
+
67
+ ### 4) 验证工具可用
68
+
69
+ ```bash
70
+ fastmcp list --command 'python -m sym_mcp.server'
71
+ ```
72
+
73
+ ## 通过 PyPI 安装(推荐给最终用户)
74
+
75
+ ```bash
76
+ pip install -U sym-mcp
77
+ ```
78
+
79
+ 安装后可直接运行:
80
+
81
+ ```bash
82
+ sym-mcp
83
+ ```
84
+
85
+ 或临时运行(不落地安装,推荐给体验用户):
86
+
87
+ ```bash
88
+ uvx sym-mcp
89
+ ```
90
+
91
+ ## 工具接口(对外契约)
92
+
93
+ ### Tool 名称
94
+
95
+ - `sympy`
96
+
97
+ ### 输入
98
+
99
+ - `code: str`
100
+
101
+ 约定:
102
+ - 代码必须使用 `print()` 输出最终结果
103
+ - 如果不 `print`,`out` 可能为空字符串
104
+
105
+ ### 输出(固定为紧凑 JSON 字符串)
106
+
107
+ 成功:
108
+
109
+ ```json
110
+ {"ok":1,"out":"x**2/2","meta":{"trunc":0,"ms":23}}
111
+ ```
112
+
113
+ 失败:
114
+
115
+ ```json
116
+ {"ok":0,"code":"E_RUNTIME","line":3,"err":"ZeroDivisionError: division by zero","hint":"运行时错误。请根据行号检查变量类型、零除、未定义变量等问题后重试。","meta":{"trunc":0,"ms":31}}
117
+ ```
118
+
119
+ 字段定义:
120
+
121
+ - `ok`: `1` 成功,`0` 失败
122
+ - `out`: 成功输出文本(来自 stdout)
123
+ - `code`: 错误码
124
+ - `line`: 用户代码报错行号;无则 `null`
125
+ - `err`: 精简错误信息(去除 traceback 噪声)
126
+ - `hint`: 修复建议(按配置等级生成)
127
+ - `meta.trunc`: 是否发生截断(`1/0`)
128
+ - `meta.ms`: 执行耗时(毫秒)
129
+
130
+ ## 错误码说明
131
+
132
+ - `E_AST_BLOCK`: AST 安全拦截(危险导入/调用/双下划线穿透)
133
+ - `E_SYNTAX`: 语法错误
134
+ - `E_TIMEOUT`: 超时(死循环或计算过慢)
135
+ - `E_MEMORY`: 内存限制触发
136
+ - `E_RUNTIME`: 一般运行时错误
137
+ - `E_WORKER`: Worker 通讯/状态异常
138
+ - `E_INTERNAL`: 服务内部异常
139
+
140
+ ## 给 LLM/Agent 的调用规范(建议直接放系统提示)
141
+
142
+ 1. 仅写数学代码,禁止文件、网络、系统调用。
143
+ 2. 仅导入 `sympy` / `math`。
144
+ 3. 最终答案必须 `print()`。
145
+ 4. 多个结果使用多行 `print()`。
146
+ 5. 收到失败结果时,只修改 `line` 附近最小范围代码并重试。
147
+ 6. `E_TIMEOUT` 先缩小规模再算;`E_MEMORY` 先减小对象维度;`E_AST_BLOCK` 删除不安全语句。
148
+
149
+ 推荐模板:
150
+
151
+ ```python
152
+ import sympy as sp
153
+ x = sp.Symbol("x")
154
+ expr = (x + 1)**5
155
+ print(sp.expand(expr))
156
+ ```
157
+
158
+ ## 安全模型
159
+
160
+ ### 执行前(AST 白名单)
161
+
162
+ - 仅允许 `sympy` / `math` 导入
163
+ - 禁止 `eval/exec/open/__import__` 等危险能力
164
+ - 禁止双下划线属性穿透(如 `__class__`)
165
+
166
+ ### 执行中(OS 资源限制)
167
+
168
+ - 子进程 CPU 时间限制 + 超时强杀
169
+ - 子进程内存限制(`setrlimit`)
170
+ - Worker 异常自动重建,不影响主服务
171
+
172
+ ## 架构总览
173
+
174
+ - `src/sym_mcp/server.py`: MCP 入口与工具注册
175
+ - `src/sym_mcp/security/ast_guard.py`: AST 安全校验
176
+ - `src/sym_mcp/executor/worker_main.py`: Worker 进程执行循环
177
+ - `src/sym_mcp/executor/pool.py`: 异步预热进程池
178
+ - `src/sym_mcp/executor/sandbox.py`: 受限执行环境与输出捕获
179
+ - `src/sym_mcp/errors/parser.py`: 错误降噪与错误码映射
180
+ - `src/sym_mcp/config.py`: 运行配置
181
+
182
+ ## 配置项(环境变量)
183
+
184
+ - `SYMMCP_POOL_SIZE`:进程池大小,默认 `10`
185
+ - `SYMMCP_EXEC_TIMEOUT_SEC`:单次执行超时秒数,默认 `3`
186
+ - `SYMMCP_MEMORY_LIMIT_MB`:单 worker 内存上限 MB,默认 `150`
187
+ - `SYMMCP_QUEUE_WAIT_SEC`:队列等待超时秒数,默认 `2`
188
+ - `SYMMCP_LOG_LEVEL`:日志级别,默认 `INFO`
189
+ - `SYMMCP_MAX_OUTPUT_CHARS`:输出截断阈值,默认 `1200`
190
+ - `SYMMCP_HINT_LEVEL`:提示等级(`none/short/medium`),默认 `medium`
191
+
192
+ ## 本地开发
193
+
194
+ ### 运行测试
195
+
196
+ ```bash
197
+ PYTHONPATH=src pytest -q
198
+ ```
199
+
200
+ ### 基准压测
201
+
202
+ ```bash
203
+ PYTHONPATH=src python scripts/benchmark.py --concurrency 100 --total 500
204
+ ```
205
+
206
+ ## MCP 客户端接入示例(stdio)
207
+
208
+ 示例命令:
209
+
210
+ ```bash
211
+ fastmcp call \
212
+ --command 'python -m sym_mcp.server' \
213
+ --target sympy \
214
+ --input-json '{"code":"import sympy as sp\nx=sp.Symbol(\"x\")\nprint(sp.factor(x**2-1))"}'
215
+ ```
216
+
217
+ 示例配置(安装为命令 `sym-mcp` 后):
218
+
219
+ ```json
220
+ {
221
+ "mcpServers": {
222
+ "sympy-sandbox": {
223
+ "command": "sym-mcp",
224
+ "args": []
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ 示例配置(使用 `uvx`):
231
+
232
+ ```json
233
+ {
234
+ "mcpServers": {
235
+ "sympy-sandbox": {
236
+ "command": "uvx",
237
+ "args": ["sym-mcp"]
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ ## 常见问题
244
+
245
+ ### 1) 为什么结果为空?
246
+
247
+ 通常是代码未 `print` 最终结果。请显式 `print(...)`。
248
+
249
+ ### 2) 为什么返回 JSON 字符串而不是纯文本?
250
+
251
+ 为便于 Agent 稳定解析并减少 token,返回固定结构化紧凑 JSON。
252
+
253
+ ### 3) macOS 下内存限制有时不稳定?
254
+
255
+ `setrlimit` 在不同系统语义不同。生产建议优先 Linux。
256
+
257
+ ### 4) 可以支持 HTTP/SSE 吗?
258
+
259
+ 当前主交付是 `stdio`。后续可按 FastMCP 方式扩展 HTTP/SSE 传输层。
260
+
261
+ ## 已知边界
262
+
263
+ - 当前为“受限 Python 执行”,不是内核虚拟化级别隔离
264
+ - 内存限制依赖 OS 层实现,跨平台表现会有差异
265
+ - 输出会按阈值截断,请调用方检查 `meta.trunc`
266
+
267
+ ## 贡献建议
268
+
269
+ - 提交 PR 前先运行 `PYTHONPATH=src pytest -q`
270
+ - 新增能力时请同步更新:
271
+ - 错误码文档
272
+ - README 示例
273
+ - 对应单元测试 / 集成测试
274
+ - 发布流程见 [PUBLISHING.md](./PUBLISHING.md)
@@ -0,0 +1,247 @@
1
+ # SymPy Sandbox MCP
2
+
3
+ 一个面向 Agent/LLM 的 SymPy 计算沙箱 MCP 服务。
4
+ 目标是:在保证安全隔离的前提下,提供低延迟、低 token、可稳定重试的数学计算工具。
5
+
6
+ ## 特性
7
+
8
+ - 单工具 `sympy`,输入参数仅 `code`
9
+ - 预热进程池,避免每次请求重复 `import sympy`
10
+ - 双层安全防护:AST 拦截 + 运行时资源限制
11
+ - 统一紧凑 JSON 输出,便于程序解析且节省 token
12
+ - 错误码标准化,方便 Agent 自动纠错重试
13
+
14
+ ## 适用场景
15
+
16
+ - 让 LLM 执行代数化简、求导、积分、方程求解、符号推导
17
+ - 作为 MCP Tool 接入 Codex / Cursor / Claude Desktop / 自建 MCP Client
18
+ - 需要“可控失败 + 低噪声错误信息”的自动化 Agent 工作流
19
+
20
+ ## 快速开始
21
+
22
+ ### 1) 环境要求
23
+
24
+ - Python 3.11+
25
+ - Linux / macOS(推荐 Linux 作为生产环境)
26
+
27
+ ### 2) 安装(清华源优先)
28
+
29
+ ```bash
30
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e .
31
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e ".[dev]"
32
+ ```
33
+
34
+ ### 3) 启动服务(stdio)
35
+
36
+ ```bash
37
+ python -m sym_mcp.server
38
+ ```
39
+
40
+ ### 4) 验证工具可用
41
+
42
+ ```bash
43
+ fastmcp list --command 'python -m sym_mcp.server'
44
+ ```
45
+
46
+ ## 通过 PyPI 安装(推荐给最终用户)
47
+
48
+ ```bash
49
+ pip install -U sym-mcp
50
+ ```
51
+
52
+ 安装后可直接运行:
53
+
54
+ ```bash
55
+ sym-mcp
56
+ ```
57
+
58
+ 或临时运行(不落地安装,推荐给体验用户):
59
+
60
+ ```bash
61
+ uvx sym-mcp
62
+ ```
63
+
64
+ ## 工具接口(对外契约)
65
+
66
+ ### Tool 名称
67
+
68
+ - `sympy`
69
+
70
+ ### 输入
71
+
72
+ - `code: str`
73
+
74
+ 约定:
75
+ - 代码必须使用 `print()` 输出最终结果
76
+ - 如果不 `print`,`out` 可能为空字符串
77
+
78
+ ### 输出(固定为紧凑 JSON 字符串)
79
+
80
+ 成功:
81
+
82
+ ```json
83
+ {"ok":1,"out":"x**2/2","meta":{"trunc":0,"ms":23}}
84
+ ```
85
+
86
+ 失败:
87
+
88
+ ```json
89
+ {"ok":0,"code":"E_RUNTIME","line":3,"err":"ZeroDivisionError: division by zero","hint":"运行时错误。请根据行号检查变量类型、零除、未定义变量等问题后重试。","meta":{"trunc":0,"ms":31}}
90
+ ```
91
+
92
+ 字段定义:
93
+
94
+ - `ok`: `1` 成功,`0` 失败
95
+ - `out`: 成功输出文本(来自 stdout)
96
+ - `code`: 错误码
97
+ - `line`: 用户代码报错行号;无则 `null`
98
+ - `err`: 精简错误信息(去除 traceback 噪声)
99
+ - `hint`: 修复建议(按配置等级生成)
100
+ - `meta.trunc`: 是否发生截断(`1/0`)
101
+ - `meta.ms`: 执行耗时(毫秒)
102
+
103
+ ## 错误码说明
104
+
105
+ - `E_AST_BLOCK`: AST 安全拦截(危险导入/调用/双下划线穿透)
106
+ - `E_SYNTAX`: 语法错误
107
+ - `E_TIMEOUT`: 超时(死循环或计算过慢)
108
+ - `E_MEMORY`: 内存限制触发
109
+ - `E_RUNTIME`: 一般运行时错误
110
+ - `E_WORKER`: Worker 通讯/状态异常
111
+ - `E_INTERNAL`: 服务内部异常
112
+
113
+ ## 给 LLM/Agent 的调用规范(建议直接放系统提示)
114
+
115
+ 1. 仅写数学代码,禁止文件、网络、系统调用。
116
+ 2. 仅导入 `sympy` / `math`。
117
+ 3. 最终答案必须 `print()`。
118
+ 4. 多个结果使用多行 `print()`。
119
+ 5. 收到失败结果时,只修改 `line` 附近最小范围代码并重试。
120
+ 6. `E_TIMEOUT` 先缩小规模再算;`E_MEMORY` 先减小对象维度;`E_AST_BLOCK` 删除不安全语句。
121
+
122
+ 推荐模板:
123
+
124
+ ```python
125
+ import sympy as sp
126
+ x = sp.Symbol("x")
127
+ expr = (x + 1)**5
128
+ print(sp.expand(expr))
129
+ ```
130
+
131
+ ## 安全模型
132
+
133
+ ### 执行前(AST 白名单)
134
+
135
+ - 仅允许 `sympy` / `math` 导入
136
+ - 禁止 `eval/exec/open/__import__` 等危险能力
137
+ - 禁止双下划线属性穿透(如 `__class__`)
138
+
139
+ ### 执行中(OS 资源限制)
140
+
141
+ - 子进程 CPU 时间限制 + 超时强杀
142
+ - 子进程内存限制(`setrlimit`)
143
+ - Worker 异常自动重建,不影响主服务
144
+
145
+ ## 架构总览
146
+
147
+ - `src/sym_mcp/server.py`: MCP 入口与工具注册
148
+ - `src/sym_mcp/security/ast_guard.py`: AST 安全校验
149
+ - `src/sym_mcp/executor/worker_main.py`: Worker 进程执行循环
150
+ - `src/sym_mcp/executor/pool.py`: 异步预热进程池
151
+ - `src/sym_mcp/executor/sandbox.py`: 受限执行环境与输出捕获
152
+ - `src/sym_mcp/errors/parser.py`: 错误降噪与错误码映射
153
+ - `src/sym_mcp/config.py`: 运行配置
154
+
155
+ ## 配置项(环境变量)
156
+
157
+ - `SYMMCP_POOL_SIZE`:进程池大小,默认 `10`
158
+ - `SYMMCP_EXEC_TIMEOUT_SEC`:单次执行超时秒数,默认 `3`
159
+ - `SYMMCP_MEMORY_LIMIT_MB`:单 worker 内存上限 MB,默认 `150`
160
+ - `SYMMCP_QUEUE_WAIT_SEC`:队列等待超时秒数,默认 `2`
161
+ - `SYMMCP_LOG_LEVEL`:日志级别,默认 `INFO`
162
+ - `SYMMCP_MAX_OUTPUT_CHARS`:输出截断阈值,默认 `1200`
163
+ - `SYMMCP_HINT_LEVEL`:提示等级(`none/short/medium`),默认 `medium`
164
+
165
+ ## 本地开发
166
+
167
+ ### 运行测试
168
+
169
+ ```bash
170
+ PYTHONPATH=src pytest -q
171
+ ```
172
+
173
+ ### 基准压测
174
+
175
+ ```bash
176
+ PYTHONPATH=src python scripts/benchmark.py --concurrency 100 --total 500
177
+ ```
178
+
179
+ ## MCP 客户端接入示例(stdio)
180
+
181
+ 示例命令:
182
+
183
+ ```bash
184
+ fastmcp call \
185
+ --command 'python -m sym_mcp.server' \
186
+ --target sympy \
187
+ --input-json '{"code":"import sympy as sp\nx=sp.Symbol(\"x\")\nprint(sp.factor(x**2-1))"}'
188
+ ```
189
+
190
+ 示例配置(安装为命令 `sym-mcp` 后):
191
+
192
+ ```json
193
+ {
194
+ "mcpServers": {
195
+ "sympy-sandbox": {
196
+ "command": "sym-mcp",
197
+ "args": []
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ 示例配置(使用 `uvx`):
204
+
205
+ ```json
206
+ {
207
+ "mcpServers": {
208
+ "sympy-sandbox": {
209
+ "command": "uvx",
210
+ "args": ["sym-mcp"]
211
+ }
212
+ }
213
+ }
214
+ ```
215
+
216
+ ## 常见问题
217
+
218
+ ### 1) 为什么结果为空?
219
+
220
+ 通常是代码未 `print` 最终结果。请显式 `print(...)`。
221
+
222
+ ### 2) 为什么返回 JSON 字符串而不是纯文本?
223
+
224
+ 为便于 Agent 稳定解析并减少 token,返回固定结构化紧凑 JSON。
225
+
226
+ ### 3) macOS 下内存限制有时不稳定?
227
+
228
+ `setrlimit` 在不同系统语义不同。生产建议优先 Linux。
229
+
230
+ ### 4) 可以支持 HTTP/SSE 吗?
231
+
232
+ 当前主交付是 `stdio`。后续可按 FastMCP 方式扩展 HTTP/SSE 传输层。
233
+
234
+ ## 已知边界
235
+
236
+ - 当前为“受限 Python 执行”,不是内核虚拟化级别隔离
237
+ - 内存限制依赖 OS 层实现,跨平台表现会有差异
238
+ - 输出会按阈值截断,请调用方检查 `meta.trunc`
239
+
240
+ ## 贡献建议
241
+
242
+ - 提交 PR 前先运行 `PYTHONPATH=src pytest -q`
243
+ - 新增能力时请同步更新:
244
+ - 错误码文档
245
+ - README 示例
246
+ - 对应单元测试 / 集成测试
247
+ - 发布流程见 [PUBLISHING.md](./PUBLISHING.md)
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sym-mcp"
7
+ version = "0.1.0"
8
+ description = "SymPy sandbox MCP server based on FastMCP"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.11"
12
+ keywords = ["mcp", "sympy", "sandbox", "agent", "llm", "math"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Topic :: Scientific/Engineering :: Mathematics",
20
+ "Topic :: Software Development :: Libraries :: Python Modules",
21
+ ]
22
+ dependencies = [
23
+ "fastmcp>=3.0.0",
24
+ "sympy>=1.13.0",
25
+ "pydantic>=2.8.0",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/Eis4TY/Sym-MCP"
30
+ Repository = "https://github.com/Eis4TY/Sym-MCP"
31
+ Issues = "https://github.com/Eis4TY/Sym-MCP/issues"
32
+
33
+ [project.scripts]
34
+ sym-mcp = "sym_mcp.server:main"
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=8.0.0",
39
+ "pytest-asyncio>=0.23.0",
40
+ ]
41
+
42
+ [tool.pytest.ini_options]
43
+ asyncio_mode = "auto"
44
+ asyncio_default_fixture_loop_scope = "function"
45
+ testpaths = ["tests"]
46
+
47
+ [tool.setuptools]
48
+ package-dir = { "" = "src" }
49
+
50
+ [tool.setuptools.packages.find]
51
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """sym_mcp package."""
2
+
@@ -0,0 +1,6 @@
1
+ from sym_mcp.server import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
6
+
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass(frozen=True)
8
+ class Settings:
9
+ pool_size: int = 10
10
+ exec_timeout_sec: float = 3.0
11
+ memory_limit_mb: int = 150
12
+ queue_wait_sec: float = 2.0
13
+ log_level: str = "INFO"
14
+ max_output_chars: int = 1200
15
+ hint_level: str = "medium"
16
+
17
+
18
+ def load_settings() -> Settings:
19
+ return Settings(
20
+ pool_size=int(os.getenv("SYMMCP_POOL_SIZE", "10")),
21
+ exec_timeout_sec=float(os.getenv("SYMMCP_EXEC_TIMEOUT_SEC", "3")),
22
+ memory_limit_mb=int(os.getenv("SYMMCP_MEMORY_LIMIT_MB", "150")),
23
+ queue_wait_sec=float(os.getenv("SYMMCP_QUEUE_WAIT_SEC", "2")),
24
+ log_level=os.getenv("SYMMCP_LOG_LEVEL", "INFO"),
25
+ max_output_chars=max(100, int(os.getenv("SYMMCP_MAX_OUTPUT_CHARS", "1200"))),
26
+ hint_level=os.getenv("SYMMCP_HINT_LEVEL", "medium"),
27
+ )
@@ -0,0 +1,2 @@
1
+ """Error parsing helpers."""
2
+