sym-mcp 0.0.0.post1.dev3__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 (36) hide show
  1. sym_mcp-0.0.0.post1.dev3/.github/workflows/pypi-publish.yml +59 -0
  2. sym_mcp-0.0.0.post1.dev3/.gitignore +58 -0
  3. sym_mcp-0.0.0.post1.dev3/LICENSE +21 -0
  4. sym_mcp-0.0.0.post1.dev3/PKG-INFO +269 -0
  5. sym_mcp-0.0.0.post1.dev3/PUBLISHING.md +87 -0
  6. sym_mcp-0.0.0.post1.dev3/README.md +242 -0
  7. sym_mcp-0.0.0.post1.dev3/README.zh.md +242 -0
  8. sym_mcp-0.0.0.post1.dev3/pyproject.toml +56 -0
  9. sym_mcp-0.0.0.post1.dev3/scripts/benchmark.py +90 -0
  10. sym_mcp-0.0.0.post1.dev3/setup.cfg +4 -0
  11. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/__init__.py +2 -0
  12. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/__main__.py +6 -0
  13. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/config.py +27 -0
  14. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/errors/__init__.py +2 -0
  15. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/errors/parser.py +114 -0
  16. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/executor/__init__.py +2 -0
  17. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/executor/pool.py +182 -0
  18. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/executor/sandbox.py +82 -0
  19. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/executor/worker_main.py +65 -0
  20. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/schemas.py +8 -0
  21. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/security/__init__.py +2 -0
  22. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/security/ast_guard.py +190 -0
  23. sym_mcp-0.0.0.post1.dev3/src/sym_mcp/server.py +153 -0
  24. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/PKG-INFO +269 -0
  25. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/SOURCES.txt +34 -0
  26. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/dependency_links.txt +1 -0
  27. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/entry_points.txt +2 -0
  28. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/requires.txt +7 -0
  29. sym_mcp-0.0.0.post1.dev3/src/sym_mcp.egg-info/top_level.txt +1 -0
  30. sym_mcp-0.0.0.post1.dev3/tests/test_ast_guard.py +47 -0
  31. sym_mcp-0.0.0.post1.dev3/tests/test_error_parser.py +55 -0
  32. sym_mcp-0.0.0.post1.dev3/tests/test_math_correctness.py +38 -0
  33. sym_mcp-0.0.0.post1.dev3/tests/test_perf_guardrails.py +64 -0
  34. sym_mcp-0.0.0.post1.dev3/tests/test_pool.py +66 -0
  35. sym_mcp-0.0.0.post1.dev3/tests/test_security_adversarial.py +40 -0
  36. sym_mcp-0.0.0.post1.dev3/tests/test_server_integration.py +104 -0
@@ -0,0 +1,59 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.11"
22
+
23
+ - name: Install build tools
24
+ run: |
25
+ python -m pip install --upgrade pip
26
+ python -m pip install build twine
27
+
28
+ - name: Clean dist directory
29
+ run: rm -rf dist
30
+
31
+ - name: Build distributions
32
+ run: python -m build
33
+
34
+ - name: Check distributions
35
+ run: twine check dist/*
36
+
37
+ - name: Upload artifacts
38
+ uses: actions/upload-artifact@v4
39
+ with:
40
+ name: dist
41
+ path: dist/
42
+
43
+ publish:
44
+ needs: build
45
+ runs-on: ubuntu-latest
46
+ permissions:
47
+ id-token: write
48
+ environment:
49
+ name: pypi
50
+ url: https://pypi.org/p/sym-mcp
51
+ steps:
52
+ - name: Download artifacts
53
+ uses: actions/download-artifact@v4
54
+ with:
55
+ name: dist
56
+ path: dist/
57
+
58
+ - name: Publish to PyPI (Trusted Publisher)
59
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,58 @@
1
+ # =========================
2
+ # Python cache / bytecode
3
+ # =========================
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # =========================
9
+ # Build / packaging outputs
10
+ # =========================
11
+ build/
12
+ dist/
13
+ *.egg-info/
14
+ .eggs/
15
+ *.egg
16
+ pip-wheel-metadata/
17
+
18
+ # =========================
19
+ # Test / coverage / typecheck caches
20
+ # =========================
21
+ .pytest_cache/
22
+ .coverage
23
+ .coverage.*
24
+ htmlcov/
25
+ .mypy_cache/
26
+ .pyre/
27
+ .ruff_cache/
28
+ .hypothesis/
29
+ .tox/
30
+ .nox/
31
+
32
+ # =========================
33
+ # Virtual environments
34
+ # =========================
35
+ .venv/
36
+ venv/
37
+ env/
38
+
39
+ # =========================
40
+ # Local env / secrets
41
+ # =========================
42
+ .env
43
+ .env.*
44
+ *.local
45
+
46
+ # =========================
47
+ # Editor / OS files
48
+ # =========================
49
+ .vscode/
50
+ .idea/
51
+ .DS_Store
52
+ Thumbs.db
53
+
54
+ # =========================
55
+ # Project-specific local docs (non-core)
56
+ # =========================
57
+ PRD.txt
58
+ TEST_PLAN.md
@@ -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.
@@ -0,0 +1,269 @@
1
+ Metadata-Version: 2.4
2
+ Name: sym-mcp
3
+ Version: 0.0.0.post1.dev3
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
+ English | [中文版](README.zh.md)
31
+
32
+ A production-focused MCP service that lets agents/LLMs run SymPy safely and efficiently.
33
+ It combines AST policy checks, runtime resource limits, and prewarmed workers to deliver low-noise, parse-friendly results.
34
+
35
+ ## Features
36
+
37
+ - Single tool: `sympy` (input only requires `code`)
38
+ - Prewarmed worker pool to avoid repeated `import sympy`
39
+ - Two-layer safety: AST guard + runtime resource limits
40
+ - Compact structured JSON output for low token overhead
41
+ - Standardized error codes for reliable auto-retry workflows
42
+
43
+ ## Typical Use Cases
44
+
45
+ - Symbolic algebra, differentiation, integration, equation solving
46
+ - MCP tool integration for Codex / Cursor / Claude Desktop / custom MCP clients
47
+ - Agent workflows that need controllable failures and clean error signals
48
+
49
+ ## Recommended Integration (MCP client via stdio)
50
+
51
+ Call example:
52
+
53
+ ```bash
54
+ fastmcp call \
55
+ --command 'python -m sym_mcp.server' \
56
+ --target sympy \
57
+ --input-json '{"code":"import sympy as sp\\nx=sp.Symbol(\"x\")\\nprint(sp.factor(x**2-1))"}'
58
+ ```
59
+
60
+ Client config (`python -m`, recommended):
61
+
62
+ ```json
63
+ {
64
+ "mcpServers": {
65
+ "sympy-sandbox": {
66
+ "command": "python",
67
+ "args": ["-m", "sym_mcp.server"]
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ Client config (installed as `sym-mcp`):
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "sympy-sandbox": {
79
+ "command": "sym-mcp",
80
+ "args": []
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ Client config (`uvx`):
87
+
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "sympy-sandbox": {
92
+ "command": "uvx",
93
+ "args": ["sym-mcp"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ ## Quick Start
100
+
101
+ ### 1) Requirements
102
+
103
+ - Python 3.11+
104
+ - Linux / macOS (Linux recommended for production)
105
+
106
+ ### 2) Install (Tsinghua mirror first)
107
+
108
+ ```bash
109
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e .
110
+ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -e ".[dev]"
111
+ ```
112
+
113
+ ### 3) Run server (stdio)
114
+
115
+ ```bash
116
+ python -m sym_mcp.server
117
+ ```
118
+
119
+ ### 4) Verify tool
120
+
121
+ ```bash
122
+ fastmcp list --command 'python -m sym_mcp.server'
123
+ ```
124
+
125
+ ## Tool Contract
126
+
127
+ ### Tool name
128
+
129
+ - `sympy`
130
+
131
+ ### Input
132
+
133
+ - `code: str`
134
+
135
+ Notes:
136
+ - You must `print()` final outputs.
137
+ - If nothing is printed, `out` may be empty.
138
+
139
+ ### Output (always compact JSON string)
140
+
141
+ Success:
142
+
143
+ ```json
144
+ {"out":"x**2/2"}
145
+ ```
146
+
147
+ Failure:
148
+
149
+ ```json
150
+ {"code":"E_RUNTIME","line":3,"err":"ZeroDivisionError: division by zero","hint":"Runtime error. Check variable types, division-by-zero, or undefined names near the reported line."}
151
+ ```
152
+
153
+ Field definitions:
154
+
155
+ - `out`: stdout text on success
156
+ - `code`: error code
157
+ - `line`: user code error line, or `null`
158
+ - `err`: compact error message (traceback noise removed)
159
+ - `hint`: fix hint (based on configured hint level)
160
+ - If `out` / `err` / `hint` is too long, it will be truncated with `...[truncated]`
161
+
162
+ ## Error Codes
163
+
164
+ - `E_AST_BLOCK`: blocked by AST safety policy
165
+ - `E_SYNTAX`: syntax error
166
+ - `E_TIMEOUT`: timeout
167
+ - `E_MEMORY`: memory limit triggered
168
+ - `E_RUNTIME`: general runtime error
169
+ - `E_WORKER`: worker communication/state failure
170
+ - `E_INTERNAL`: internal server error
171
+
172
+ ## Recommended Agent Prompt Rules
173
+
174
+ 1. Use math-only Python code.
175
+ 2. Only import `sympy` or `math`.
176
+ 3. Always `print()` final answers.
177
+ 4. For multiple outputs, use multiple `print()` lines.
178
+ 5. On failure, patch minimally near `line` and retry.
179
+ 6. For `E_TIMEOUT`, reduce scale first; for `E_MEMORY`, reduce object size/dimension; for `E_AST_BLOCK`, remove unsafe statements.
180
+
181
+ Example:
182
+
183
+ ```python
184
+ import sympy as sp
185
+ x = sp.Symbol("x")
186
+ expr = (x + 1)**5
187
+ print(sp.expand(expr))
188
+ ```
189
+
190
+ ## Security Model
191
+
192
+ ### Before execution (AST policy)
193
+
194
+ - Only `sympy` / `math` imports are allowed
195
+ - Dangerous capabilities are blocked (`eval`, `exec`, `open`, `__import__`, etc.)
196
+ - Dunder attribute traversal is blocked (e.g. `__class__`)
197
+
198
+ ### During execution (OS resource limits)
199
+
200
+ - Per-task CPU time limit + timeout kill
201
+ - Per-worker memory limit via `setrlimit`
202
+ - Worker auto-rebuild on failure to keep server healthy
203
+
204
+ ## Architecture
205
+
206
+ - `src/sym_mcp/server.py`: MCP entrypoint and tool registration
207
+ - `src/sym_mcp/security/ast_guard.py`: AST validation
208
+ - `src/sym_mcp/executor/worker_main.py`: worker loop
209
+ - `src/sym_mcp/executor/pool.py`: async prewarmed process pool
210
+ - `src/sym_mcp/executor/sandbox.py`: restricted execution and stdout capture
211
+ - `src/sym_mcp/errors/parser.py`: error normalization and code mapping
212
+ - `src/sym_mcp/config.py`: runtime configuration
213
+
214
+ ## Configuration (Environment Variables)
215
+
216
+ - `SYMMCP_POOL_SIZE`: worker pool size, default `10`
217
+ - `SYMMCP_EXEC_TIMEOUT_SEC`: per execution timeout (sec), default `3`
218
+ - `SYMMCP_MEMORY_LIMIT_MB`: memory cap per worker (MB), default `150`
219
+ - `SYMMCP_QUEUE_WAIT_SEC`: queue wait timeout (sec), default `2`
220
+ - `SYMMCP_LOG_LEVEL`: log level, default `INFO`
221
+ - `SYMMCP_MAX_OUTPUT_CHARS`: output truncation threshold, default `1200`
222
+ - `SYMMCP_HINT_LEVEL`: hint level (`none/short/medium`), default `medium`
223
+
224
+ ## FAQ
225
+
226
+ ### Why is `out` empty?
227
+
228
+ Most likely the code does not `print()` the final result.
229
+
230
+ ### Why return compact JSON string?
231
+
232
+ It is easier for agents to parse reliably and reduces token cost.
233
+
234
+ ### Is memory limiting always stable on macOS?
235
+
236
+ `setrlimit` behavior differs by OS. Linux is preferred for production.
237
+
238
+ ### Does it support HTTP/SSE?
239
+
240
+ Current primary delivery is `stdio`. HTTP/SSE can be added later via FastMCP transport extensions.
241
+
242
+ ## Known Limits
243
+
244
+ - This is restricted Python execution, not VM/container-grade isolation
245
+ - Memory limit behavior is OS-dependent
246
+ - Output is truncated at threshold, with `...[truncated]` suffix
247
+
248
+ ## Development
249
+
250
+ ### Run tests
251
+
252
+ ```bash
253
+ PYTHONPATH=src pytest -q
254
+ ```
255
+
256
+ ### Benchmark
257
+
258
+ ```bash
259
+ PYTHONPATH=src python scripts/benchmark.py --concurrency 100 --total 500
260
+ ```
261
+
262
+ ## Contributing
263
+
264
+ - Run `PYTHONPATH=src pytest -q` before submitting PRs
265
+ - When adding new capabilities, update:
266
+ - error code docs
267
+ - README examples
268
+ - related unit/integration tests
269
+ - Publishing process: [PUBLISHING.md](./PUBLISHING.md)
@@ -0,0 +1,87 @@
1
+ # Publishing Guide (PyPI)
2
+
3
+ 本文档描述如何将 `sym-mcp` 发布到 PyPI。
4
+
5
+ ## 0. 发布前检查
6
+
7
+ 1. 确认包名可用:
8
+ ```bash
9
+ pip index versions sym-mcp
10
+ ```
11
+
12
+ 2. 版本号由 Git Tag 自动生成(`setuptools-scm`),不再手改 `pyproject.toml`。
13
+ - 例如:`v0.1.1` -> 发布版本 `0.1.1`
14
+ - 非 tag 构建会得到开发版号(仅用于本地/CI)
15
+
16
+ 3. 执行测试:
17
+ ```bash
18
+ PYTHONPATH=src pytest -q
19
+ ```
20
+
21
+ ## 1. 构建分发包
22
+
23
+ ```bash
24
+ python -m pip install -U build
25
+ python -m build
26
+ ```
27
+
28
+ 产物在 `dist/` 目录下(`.whl` + `.tar.gz`)。
29
+
30
+ ## 2. 校验元数据
31
+
32
+ ```bash
33
+ python -m pip install -U twine
34
+ twine check dist/*
35
+ ```
36
+
37
+ ## 3. 上传到 TestPyPI(推荐先试)
38
+
39
+ ```bash
40
+ twine upload --repository testpypi dist/*
41
+ ```
42
+
43
+ ## 4. 上传到 PyPI
44
+
45
+ ```bash
46
+ twine upload dist/*
47
+ ```
48
+
49
+ ## 5. 安装与回归验证
50
+
51
+ ```bash
52
+ pip install -U sym-mcp
53
+ sym-mcp
54
+ ```
55
+
56
+ 另开终端验证工具:
57
+
58
+ ```bash
59
+ fastmcp list --command "sym-mcp"
60
+ fastmcp call --command "sym-mcp" --target sympy --input-json '{"code":"import sympy as sp\nx=sp.Symbol(\"x\")\nprint(sp.factor(x**2-1))"}'
61
+ ```
62
+
63
+ ## 使用 GitHub Trusted Publisher(推荐)
64
+
65
+ 仓库已包含工作流:
66
+
67
+ - `.github/workflows/pypi-publish.yml`
68
+
69
+ 发布方式:
70
+
71
+ 1. 在 PyPI 项目中创建 Trusted Publisher,填写:
72
+ - Owner: `Eis4TY`
73
+ - Repository: `Sym-MCP`
74
+ - Workflow: `pypi-publish.yml`
75
+ - Environment: `pypi`
76
+
77
+ 2. 推送版本标签触发发布(版本自动从 tag 推导):
78
+
79
+ ```bash
80
+ git tag v0.1.1
81
+ git push origin v0.1.1
82
+ ```
83
+
84
+ 3. GitHub Actions 会自动完成:
85
+ - 构建
86
+ - `twine check`
87
+ - OIDC 发布到 PyPI