netlogo-mcp 1.0.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.
- netlogo_mcp-1.0.0/.env.example +13 -0
- netlogo_mcp-1.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +64 -0
- netlogo_mcp-1.0.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- netlogo_mcp-1.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +25 -0
- netlogo_mcp-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +11 -0
- netlogo_mcp-1.0.0/.github/dependabot.yml +17 -0
- netlogo_mcp-1.0.0/.github/workflows/ci.yml +56 -0
- netlogo_mcp-1.0.0/.github/workflows/release.yml +97 -0
- netlogo_mcp-1.0.0/.gitignore +53 -0
- netlogo_mcp-1.0.0/.mcp.json +12 -0
- netlogo_mcp-1.0.0/.pre-commit-config.yaml +16 -0
- netlogo_mcp-1.0.0/CHANGELOG.md +220 -0
- netlogo_mcp-1.0.0/CITATION.cff +24 -0
- netlogo_mcp-1.0.0/CONTRIBUTING.md +64 -0
- netlogo_mcp-1.0.0/LICENSE +21 -0
- netlogo_mcp-1.0.0/PKG-INFO +249 -0
- netlogo_mcp-1.0.0/README.md +205 -0
- netlogo_mcp-1.0.0/docs/CLIENTS.md +260 -0
- netlogo_mcp-1.0.0/docs/COMSES_PLAN.md +791 -0
- netlogo_mcp-1.0.0/docs/CONFIGURATION.md +54 -0
- netlogo_mcp-1.0.0/docs/DEVELOPMENT.md +132 -0
- netlogo_mcp-1.0.0/docs/SECURITY.md +44 -0
- netlogo_mcp-1.0.0/docs/TOOLS.md +136 -0
- netlogo_mcp-1.0.0/exports/views/.gitkeep +0 -0
- netlogo_mcp-1.0.0/exports/worlds/.gitkeep +0 -0
- netlogo_mcp-1.0.0/logo.svg +19 -0
- netlogo_mcp-1.0.0/models/.gitkeep +0 -0
- netlogo_mcp-1.0.0/pyproject.toml +129 -0
- netlogo_mcp-1.0.0/smithery.yaml +31 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/__init__.py +3 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/bspace.py +762 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/comses.py +831 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/config.py +137 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/data/netlogo7_transition.md +168 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/data/primitives.md +801 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/data/programming_guide.md +1155 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/prompts.py +257 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/py.typed +0 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/resources.py +65 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/server.py +280 -0
- netlogo_mcp-1.0.0/src/netlogo_mcp/tools.py +2522 -0
- netlogo_mcp-1.0.0/tests/conftest.py +78 -0
- netlogo_mcp-1.0.0/tests/fixtures/comses/codebase_detail.json +43 -0
- netlogo_mcp-1.0.0/tests/fixtures/comses/release_detail.json +19 -0
- netlogo_mcp-1.0.0/tests/fixtures/comses/search_result.json +70 -0
- netlogo_mcp-1.0.0/tests/manual_smoke.py +128 -0
- netlogo_mcp-1.0.0/tests/test_bspace.py +544 -0
- netlogo_mcp-1.0.0/tests/test_bspace_tools.py +345 -0
- netlogo_mcp-1.0.0/tests/test_comses.py +1107 -0
- netlogo_mcp-1.0.0/tests/test_config.py +28 -0
- netlogo_mcp-1.0.0/tests/test_resources.py +87 -0
- netlogo_mcp-1.0.0/tests/test_server.py +159 -0
- netlogo_mcp-1.0.0/tests/test_tools.py +1044 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Path to your NetLogo installation
|
|
2
|
+
NETLOGO_HOME=C:/Program Files/NetLogo 7.0.3
|
|
3
|
+
|
|
4
|
+
# Path to your Java JDK installation
|
|
5
|
+
JAVA_HOME=C:/Program Files/Eclipse Adoptium/jdk-25.0.2.10-hotspot
|
|
6
|
+
|
|
7
|
+
# (Optional) Directory where .nlogo model files are stored
|
|
8
|
+
# Defaults to the current working directory's models/ folder
|
|
9
|
+
# NETLOGO_MODELS_DIR=C:/Users/you/your-project/models
|
|
10
|
+
|
|
11
|
+
# (Optional) NETLOGO_GUI controls whether a live NetLogo window opens.
|
|
12
|
+
# Default is "true" (live GUI). Set to "false" for headless mode — faster, no window.
|
|
13
|
+
# NETLOGO_GUI=false
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something isn't working
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: what-happened
|
|
7
|
+
attributes:
|
|
8
|
+
label: What happened?
|
|
9
|
+
description: What did you do, what did you expect, and what happened instead?
|
|
10
|
+
placeholder: |
|
|
11
|
+
I asked Claude to "create a predator-prey model" and got...
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: repro
|
|
17
|
+
attributes:
|
|
18
|
+
label: How to reproduce
|
|
19
|
+
description: The prompt you gave your AI assistant, or the tool call that failed.
|
|
20
|
+
placeholder: |
|
|
21
|
+
1. Connect the server in Claude Code
|
|
22
|
+
2. Ask: "..."
|
|
23
|
+
3. Error: ...
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
|
|
27
|
+
- type: input
|
|
28
|
+
id: mcp-client
|
|
29
|
+
attributes:
|
|
30
|
+
label: MCP client
|
|
31
|
+
placeholder: e.g. Claude Code, Claude Desktop, Cursor, Cline
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
|
|
35
|
+
- type: input
|
|
36
|
+
id: netlogo-version
|
|
37
|
+
attributes:
|
|
38
|
+
label: NetLogo version
|
|
39
|
+
placeholder: e.g. 7.0.3
|
|
40
|
+
validations:
|
|
41
|
+
required: true
|
|
42
|
+
|
|
43
|
+
- type: input
|
|
44
|
+
id: os
|
|
45
|
+
attributes:
|
|
46
|
+
label: Operating system
|
|
47
|
+
placeholder: e.g. Windows 11, macOS 15, Ubuntu 24.04
|
|
48
|
+
validations:
|
|
49
|
+
required: true
|
|
50
|
+
|
|
51
|
+
- type: input
|
|
52
|
+
id: versions
|
|
53
|
+
attributes:
|
|
54
|
+
label: Python and Java versions
|
|
55
|
+
placeholder: e.g. Python 3.12, Temurin JDK 21
|
|
56
|
+
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: logs
|
|
59
|
+
attributes:
|
|
60
|
+
label: Server output / logs
|
|
61
|
+
description: |
|
|
62
|
+
Run `netlogo-mcp` manually in a terminal to capture error output, or check
|
|
63
|
+
your MCP client's logs. Paste anything relevant here.
|
|
64
|
+
render: shell
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a new tool, resource, or improvement
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: What are you trying to do?
|
|
9
|
+
description: Describe the modeling/analysis task you want your AI assistant to handle.
|
|
10
|
+
placeholder: |
|
|
11
|
+
I want to ask Claude to "..." but there's no tool for...
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: solution
|
|
17
|
+
attributes:
|
|
18
|
+
label: Proposed solution
|
|
19
|
+
description: What should the server do? A new tool, a new parameter, a new resource?
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: alternatives
|
|
23
|
+
attributes:
|
|
24
|
+
label: Workarounds you've tried
|
|
25
|
+
description: e.g. raw `command`/`report` calls, manual NetLogo steps
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# What does this PR do?
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences. Link the issue if there is one: Fixes #123 -->
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] Tests pass locally (`pytest tests/`)
|
|
8
|
+
- [ ] Lint passes (`pre-commit run --all-files` and `mypy src/netlogo_mcp/`)
|
|
9
|
+
- [ ] Added/updated tests for the change
|
|
10
|
+
- [ ] Updated `CHANGELOG.md` under `[Unreleased]`
|
|
11
|
+
- [ ] Updated docs (`docs/TOOLS.md`, `docs/CONFIGURATION.md`, README) if behavior changed
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: github-actions
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: monthly
|
|
7
|
+
groups:
|
|
8
|
+
actions:
|
|
9
|
+
patterns: ["*"]
|
|
10
|
+
|
|
11
|
+
- package-ecosystem: pip
|
|
12
|
+
directory: /
|
|
13
|
+
schedule:
|
|
14
|
+
interval: monthly
|
|
15
|
+
groups:
|
|
16
|
+
python-deps:
|
|
17
|
+
patterns: ["*"]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, gui]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint & Type Check
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Pre-commit hooks (Ruff lint + format)
|
|
27
|
+
run: pre-commit run --all-files --show-diff-on-failure
|
|
28
|
+
|
|
29
|
+
- name: Mypy type check
|
|
30
|
+
run: mypy src/netlogo_mcp/
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
strategy:
|
|
36
|
+
matrix:
|
|
37
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- uses: actions/setup-python@v5
|
|
42
|
+
with:
|
|
43
|
+
python-version: ${{ matrix.python-version }}
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: pip install -e ".[dev]"
|
|
47
|
+
|
|
48
|
+
- name: Run tests with coverage
|
|
49
|
+
run: pytest tests/ -v --cov=netlogo_mcp --cov-report=xml --cov-report=term-missing
|
|
50
|
+
|
|
51
|
+
- name: Upload coverage
|
|
52
|
+
if: matrix.python-version == '3.12'
|
|
53
|
+
uses: codecov/codecov-action@v4
|
|
54
|
+
with:
|
|
55
|
+
file: coverage.xml
|
|
56
|
+
fail_ci_if_error: false
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build distribution
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
|
|
22
|
+
- name: Verify tag matches package version
|
|
23
|
+
run: |
|
|
24
|
+
PKG_VERSION=$(python -c "import re; print(re.search(r'__version__ = \"(.+?)\"', open('src/netlogo_mcp/__init__.py').read()).group(1))")
|
|
25
|
+
TAG_VERSION="${GITHUB_REF_NAME#v}"
|
|
26
|
+
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
|
|
27
|
+
echo "::error::Tag $GITHUB_REF_NAME does not match __version__ $PKG_VERSION"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
- name: Build sdist and wheel
|
|
32
|
+
run: |
|
|
33
|
+
pip install build
|
|
34
|
+
python -m build
|
|
35
|
+
|
|
36
|
+
- name: Check distribution metadata
|
|
37
|
+
run: |
|
|
38
|
+
pip install twine
|
|
39
|
+
twine check dist/*
|
|
40
|
+
|
|
41
|
+
- uses: actions/upload-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
|
|
46
|
+
publish-pypi:
|
|
47
|
+
name: Publish to PyPI
|
|
48
|
+
needs: build
|
|
49
|
+
runs-on: ubuntu-latest
|
|
50
|
+
environment:
|
|
51
|
+
name: pypi
|
|
52
|
+
url: https://pypi.org/p/netlogo-mcp
|
|
53
|
+
permissions:
|
|
54
|
+
id-token: write # OIDC trusted publishing — no API token needed
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/download-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: dist
|
|
59
|
+
path: dist/
|
|
60
|
+
|
|
61
|
+
- name: Publish to PyPI
|
|
62
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
63
|
+
|
|
64
|
+
github-release:
|
|
65
|
+
name: Create GitHub Release
|
|
66
|
+
needs: publish-pypi
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
permissions:
|
|
69
|
+
contents: write
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
|
|
73
|
+
- uses: actions/download-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: dist
|
|
76
|
+
path: dist/
|
|
77
|
+
|
|
78
|
+
- name: Extract changelog for this version
|
|
79
|
+
run: |
|
|
80
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
81
|
+
# Pull the section for this version out of CHANGELOG.md
|
|
82
|
+
awk -v ver="$VERSION" '
|
|
83
|
+
$0 ~ "^## \\[" ver "\\]" { found=1; next }
|
|
84
|
+
found && /^## \[/ { exit }
|
|
85
|
+
found { print }
|
|
86
|
+
' CHANGELOG.md > release-notes.md
|
|
87
|
+
if [ ! -s release-notes.md ]; then
|
|
88
|
+
echo "No CHANGELOG section found for $VERSION — using auto-generated notes." > release-notes.md
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
- name: Create release
|
|
92
|
+
env:
|
|
93
|
+
GH_TOKEN: ${{ github.token }}
|
|
94
|
+
run: |
|
|
95
|
+
gh release create "$GITHUB_REF_NAME" dist/* \
|
|
96
|
+
--title "$GITHUB_REF_NAME" \
|
|
97
|
+
--notes-file release-notes.md
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.eggs/
|
|
9
|
+
*.egg
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.env
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
env/
|
|
17
|
+
ENV/
|
|
18
|
+
|
|
19
|
+
# IDE
|
|
20
|
+
.vscode/
|
|
21
|
+
.idea/
|
|
22
|
+
*.swp
|
|
23
|
+
*.swo
|
|
24
|
+
*~
|
|
25
|
+
|
|
26
|
+
# NetLogo temp files
|
|
27
|
+
*.nlogo~
|
|
28
|
+
|
|
29
|
+
# OS files
|
|
30
|
+
.DS_Store
|
|
31
|
+
Thumbs.db
|
|
32
|
+
desktop.ini
|
|
33
|
+
|
|
34
|
+
# Testing
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.coverage
|
|
38
|
+
htmlcov/
|
|
39
|
+
|
|
40
|
+
# Exports (keep folder structure, ignore actual exports)
|
|
41
|
+
exports/views/*.png
|
|
42
|
+
exports/worlds/*.csv
|
|
43
|
+
exports/experiments/*.csv
|
|
44
|
+
exports/experiments/*.xml
|
|
45
|
+
|
|
46
|
+
# Auto-created models (from create_model tool)
|
|
47
|
+
models/_created_*.nlogox
|
|
48
|
+
|
|
49
|
+
# Claude Code session scratch (worktrees, session state)
|
|
50
|
+
.claude/
|
|
51
|
+
|
|
52
|
+
# COMSES download cache — live data, not source
|
|
53
|
+
models/comses/
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.8.6
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
10
|
+
rev: v1.14.1
|
|
11
|
+
hooks:
|
|
12
|
+
- id: mypy
|
|
13
|
+
additional_dependencies:
|
|
14
|
+
- types-setuptools
|
|
15
|
+
args: [--config-file=pyproject.toml, src/netlogo_mcp/]
|
|
16
|
+
pass_filenames: false
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-06-06
|
|
11
|
+
|
|
12
|
+
First stable release. The server is feature-complete for conversational
|
|
13
|
+
agent-based modeling: 25 tools covering model creation with declarative
|
|
14
|
+
widgets, simulation and data collection, BehaviorSpace parameter sweeps,
|
|
15
|
+
CoMSES Net library access, and view/world export — now published on PyPI
|
|
16
|
+
as [`netlogo-mcp`](https://pypi.org/project/netlogo-mcp/).
|
|
17
|
+
|
|
18
|
+
### Packaging
|
|
19
|
+
|
|
20
|
+
- Published to PyPI: `pip install netlogo-mcp`.
|
|
21
|
+
- Package renamed `NetLogo_MCP` → `netlogo-mcp` (PyPI-normalized name);
|
|
22
|
+
version is now single-sourced from `netlogo_mcp.__version__`.
|
|
23
|
+
- Added release automation: pushing a `v*` tag builds, publishes to PyPI
|
|
24
|
+
via trusted publishing, and creates a GitHub Release with these notes.
|
|
25
|
+
- Added `CITATION.cff`, issue/PR templates, and Dependabot config.
|
|
26
|
+
|
|
27
|
+
### Changed — lazy JVM startup
|
|
28
|
+
|
|
29
|
+
- The JVM (and the NetLogo GUI window) now starts **lazily** on the first
|
|
30
|
+
tool call that needs the workspace, instead of the moment an MCP client
|
|
31
|
+
connects. Connecting Claude/Cursor/etc. no longer pops a NetLogo window
|
|
32
|
+
you didn't ask for. Startup runs on a worker thread under the workspace
|
|
33
|
+
lock, so the event loop and MCP heartbeats stay responsive during the
|
|
34
|
+
30-60s boot. Set `NETLOGO_EAGER_START=true` to restore the old
|
|
35
|
+
boot-at-launch behavior.
|
|
36
|
+
- `server_info` now reports `jvm_started` so clients can check workspace
|
|
37
|
+
state without triggering a boot.
|
|
38
|
+
|
|
39
|
+
### Fixed — JVM startup deadlock on Windows
|
|
40
|
+
|
|
41
|
+
- The stdio transport keeps a pending blocking read on the stdin pipe from
|
|
42
|
+
a worker thread; Windows serializes operations on a synchronous pipe's
|
|
43
|
+
file object, so the JVM's std-handle probes during `CreateJavaVM` blocked
|
|
44
|
+
behind that read — JVM startup hung until the client happened to send
|
|
45
|
+
another byte. The server now hands the transport a private duplicate of
|
|
46
|
+
stdin and points fd 0 (and the Win32 `STD_INPUT_HANDLE`) at devnull, so
|
|
47
|
+
the JVM never touches the protocol pipe. This was the real reason an
|
|
48
|
+
earlier lazy-startup attempt was abandoned for eager startup.
|
|
49
|
+
|
|
50
|
+
### Fixed — protocol corruption on NetLogo errors
|
|
51
|
+
|
|
52
|
+
- pynetlogo `print()`s Java stack traces to stdout whenever a NetLogo
|
|
53
|
+
command/reporter/load fails — and stdout is the MCP JSON-RPC channel.
|
|
54
|
+
One compile error in generated model code could corrupt the protocol
|
|
55
|
+
stream and leave the session flaky. The server now duplicates fd 1 for
|
|
56
|
+
the transport's private use, points fd 1 at stderr (covering the JVM's
|
|
57
|
+
direct `System.out` writes, which bypass Python entirely), and parks
|
|
58
|
+
Python's `sys.stdout` on stderr for the whole serving phase.
|
|
59
|
+
|
|
60
|
+
### Fixed — widget generation
|
|
61
|
+
|
|
62
|
+
- `create_model` / `save_model` no longer emit Setup/Go buttons for
|
|
63
|
+
procedures that don't exist in the code — a button pointing at a missing
|
|
64
|
+
procedure made the whole model fail to load.
|
|
65
|
+
- `to setup-patches` no longer falsely counts as defining `setup`.
|
|
66
|
+
|
|
67
|
+
### Changed — multi-column widget layout
|
|
68
|
+
|
|
69
|
+
- Declarative widgets now wrap into additional columns when they'd
|
|
70
|
+
overflow the column height, and the world view shifts right to sit
|
|
71
|
+
beside the last column — widget-heavy models no longer pile into one
|
|
72
|
+
endless strip that runs off the bottom of the window.
|
|
73
|
+
|
|
74
|
+
### Added — GUI polish
|
|
75
|
+
|
|
76
|
+
- The NetLogo window is retitled to the model name and brought to the
|
|
77
|
+
front whenever a model is loaded (`create_model` / `open_model` /
|
|
78
|
+
`update_model` / `open_comses_model`). Best-effort via the Swing event
|
|
79
|
+
thread; silent no-op in headless mode.
|
|
80
|
+
- New `watch_simulation(ticks, delay_ms)` tool — runs `go` step-by-step
|
|
81
|
+
with a pause between steps so a human can actually watch the dynamics
|
|
82
|
+
unfold in the GUI. Capped at 120s per call; `run_simulation` remains the
|
|
83
|
+
full-speed data-collection path.
|
|
84
|
+
|
|
85
|
+
### Added — plot widgets
|
|
86
|
+
|
|
87
|
+
- The `widgets` schema now supports `{"type": "plot", "pens": [...]}` —
|
|
88
|
+
live population-dynamics plots in the NetLogo window, the main reason to
|
|
89
|
+
watch a GUI run. Pens take NetLogo plot code, palette color names (or raw
|
|
90
|
+
AWT ints), line/bar/point modes, and intervals; axes auto-scale.
|
|
91
|
+
Verified live: NetLogo 7.0.3 loads the generated XML and pens plot every
|
|
92
|
+
tick.
|
|
93
|
+
|
|
94
|
+
### Added — update_model
|
|
95
|
+
|
|
96
|
+
- New `update_model(code, widgets?)` tool: rewrites the currently loaded
|
|
97
|
+
`.nlogox` in place and reloads it. Existing widgets are preserved when
|
|
98
|
+
`widgets` is omitted, so iterating on procedures keeps the interface the
|
|
99
|
+
user already has. Ends the one-`_created_*.nlogox`-file-per-iteration
|
|
100
|
+
clutter in the models directory.
|
|
101
|
+
|
|
102
|
+
### Added — declarative interface widgets
|
|
103
|
+
|
|
104
|
+
- `create_model` and `save_model` accept an optional `widgets` list:
|
|
105
|
+
sliders, switches, buttons, and monitors with validated names, escaped
|
|
106
|
+
code, and automatic column layout (NetLogo 7 `.nlogox` widget schema).
|
|
107
|
+
Slider/switch widgets define their variable, so generated models can use
|
|
108
|
+
interface globals exactly like hand-built ones — and `set_parameter`
|
|
109
|
+
works against them out of the box.
|
|
110
|
+
|
|
111
|
+
### Docs
|
|
112
|
+
|
|
113
|
+
- README slimmed to the essentials; full tool reference moved to
|
|
114
|
+
`docs/TOOLS.md`, environment variables and GUI/headless guidance to
|
|
115
|
+
`docs/CONFIGURATION.md`, and the security model to `docs/SECURITY.md`.
|
|
116
|
+
- `docs/DEVELOPMENT.md` architecture notes rewritten to match the lazy
|
|
117
|
+
startup and fd-level stdout discipline (the old notes contradicted the
|
|
118
|
+
code on threading).
|
|
119
|
+
|
|
120
|
+
### Security & validation
|
|
121
|
+
|
|
122
|
+
- `set_parameter` now validates the `name` argument against a NetLogo
|
|
123
|
+
identifier regex before interpolating it into a `set <name> <value>`
|
|
124
|
+
command. Closes a command-injection vector where a name like
|
|
125
|
+
`"x setup -- "` would have appended an arbitrary NetLogo command past
|
|
126
|
+
the `set`. Legitimate kebab-case + predicate names (`show-energy?`,
|
|
127
|
+
`initial-number-sheep`) are unaffected.
|
|
128
|
+
- `run_simulation` rejects empty / non-string entries in `reporters`,
|
|
129
|
+
and `get_patch_data` rejects blank `attribute`s — these formerly
|
|
130
|
+
produced confusing NetLogo compile errors deep in the call.
|
|
131
|
+
- 25 new tests cover the validation surface (injection-shape names,
|
|
132
|
+
blank reporters, blank attributes).
|
|
133
|
+
|
|
134
|
+
### Added — workspace control & introspection
|
|
135
|
+
|
|
136
|
+
- New `close_model` tool — issues `clear-all` and forgets the current
|
|
137
|
+
model path so AI clients can drop pending state without bouncing the
|
|
138
|
+
JVM (which costs 30-60s on the next startup).
|
|
139
|
+
- New `server_info` tool — pure config / filesystem inspection that
|
|
140
|
+
returns server version, GUI mode, configured paths, and whether the
|
|
141
|
+
BehaviorSpace headless launcher is reachable. Useful as a pre-flight
|
|
142
|
+
check before launching long sweeps; does not require the JVM to be
|
|
143
|
+
warm.
|
|
144
|
+
|
|
145
|
+
### Removed
|
|
146
|
+
|
|
147
|
+
- Dead `get_or_create_netlogo` lazy-init helper in `server.py` — the
|
|
148
|
+
eager `lifespan()` startup is the only path now, and the duplicated
|
|
149
|
+
init was an attractive nuisance for future contributors.
|
|
150
|
+
|
|
151
|
+
### Added — BehaviorSpace integration & NetLogo 7 transition guide
|
|
152
|
+
|
|
153
|
+
- 3 new tools for running NetLogo BehaviorSpace experiments:
|
|
154
|
+
`list_experiments` (read saved experiments from `.nlogox`),
|
|
155
|
+
`preview_experiment` (show run plan without executing),
|
|
156
|
+
`run_experiment` (drive the headless launcher in a separate JVM and
|
|
157
|
+
return parsed table-CSV results).
|
|
158
|
+
- Drives BehaviorSpace via the canonical `NetLogo_Console` /
|
|
159
|
+
`netlogo-headless` launcher — no dependency on the unbundled `bspace`
|
|
160
|
+
extension, works with NetLogo 6.x and 7.x.
|
|
161
|
+
- Hard run cap (`max_total_runs`, default 200) and wall-clock timeout
|
|
162
|
+
(`timeout_seconds`, default 600). Partial table CSV is preserved on
|
|
163
|
+
timeout; the runner reports `timed_out` separately from `failed`.
|
|
164
|
+
- New prompt: `behaviorspace_experiment` — enforces preview-before-run.
|
|
165
|
+
- New resource: `netlogo://docs/transition` — focused 6→7 porting guide
|
|
166
|
+
for AI clients hitting old CoMSES models. Covers `.nlogo` →
|
|
167
|
+
`.nlogox` auto-conversion, `ifelse-value` precedence shift, `task` →
|
|
168
|
+
anonymous procedures, movie-prim → `vid` extension, bundled vs
|
|
169
|
+
non-bundled extensions in 7.0.3.
|
|
170
|
+
- Tracks `current_model_path` in the lifespan context so BehaviorSpace
|
|
171
|
+
can target the model the AI most recently loaded without an extra arg.
|
|
172
|
+
|
|
173
|
+
### Changed — token efficiency
|
|
174
|
+
|
|
175
|
+
- `run_simulation` accepts `summary_only=True` (returns
|
|
176
|
+
min/mean/max/std/final per reporter as one row each) and `max_rows=N`
|
|
177
|
+
(evenly-spaced decimation that always keeps the final tick).
|
|
178
|
+
- `get_patch_data` accepts `summary_only=True` (returns shape + numeric
|
|
179
|
+
stats + unique-count instead of the full 2D grid).
|
|
180
|
+
- Defaults are unchanged; existing prompts keep working.
|
|
181
|
+
|
|
182
|
+
### Added — CoMSES Net integration
|
|
183
|
+
|
|
184
|
+
- 5 new tools for exploring the CoMSES Net computational model library:
|
|
185
|
+
`search_comses`, `get_comses_model`, `download_comses_model`,
|
|
186
|
+
`open_comses_model`, `read_comses_files`.
|
|
187
|
+
- 1 new prompt: `explore_comses` — NetLogo-first, source-introspection,
|
|
188
|
+
never fabricates commands, stops-and-asks on runtime errors.
|
|
189
|
+
- Safe download pipeline: HEAD screen + mid-stream byte cap
|
|
190
|
+
(`COMSES_MAX_DOWNLOAD_MB`, default 50), zip-member path-traversal
|
|
191
|
+
validation, zip-bomb guard, atomic temp-to-final extract with
|
|
192
|
+
`.comses_complete` marker, race reconciliation.
|
|
193
|
+
- `"latest"` version resolution with snapshot semantics — resolved to
|
|
194
|
+
a concrete version before any cache path is computed; the resolved
|
|
195
|
+
version is returned so follow-up reads stay pinned.
|
|
196
|
+
- `read_comses_files` returns a precise contract with per-file
|
|
197
|
+
`{content, full_size, returned_size, truncated}`, priority ordering
|
|
198
|
+
(ODD → NetLogo → other code → md/txt), byte cap with line-boundary
|
|
199
|
+
truncation, UTF-8 decoding with `errors="replace"`, zero-match case
|
|
200
|
+
handled explicitly.
|
|
201
|
+
- `httpx>=0.27` dependency.
|
|
202
|
+
- 44 new tests covering retry matrix, zip-slip, zip-bomb, marker,
|
|
203
|
+
race-orphan, NetLogo-file selection rule, ODD discovery, cache
|
|
204
|
+
reuse, latest resolution, truncation, extension filters, prompt rules.
|
|
205
|
+
|
|
206
|
+
## [0.1.0] - 2025-02-23
|
|
207
|
+
|
|
208
|
+
### Added
|
|
209
|
+
|
|
210
|
+
- Initial release of NetLogo MCP Server
|
|
211
|
+
- 12 tools: `open_model`, `command`, `report`, `run_simulation`, `set_parameter`, `get_world_state`, `get_patch_data`, `export_view`, `create_model`, `list_models`, `save_model`, `export_world`
|
|
212
|
+
- 3 resources: `netlogo://docs/primitives`, `netlogo://docs/programming`, `netlogo://models/{name}`
|
|
213
|
+
- 3 prompts: `analyze_model`, `create_abm`, `parameter_sweep`
|
|
214
|
+
- Headless and GUI mode support
|
|
215
|
+
- Built-in NetLogo primitives reference and programming guide
|
|
216
|
+
- Path traversal protection on all file operations
|
|
217
|
+
- XML escaping for `.nlogox` model creation
|
|
218
|
+
- Stdout protection to prevent JVM corruption of MCP stdio transport
|
|
219
|
+
- Mock-based test suite (no Java/NetLogo needed to run tests)
|
|
220
|
+
- Cross-platform JVM detection (Windows, Linux, macOS)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use NetLogo MCP in your research, please cite it as below."
|
|
3
|
+
type: software
|
|
4
|
+
title: "NetLogo MCP: A Model Context Protocol server for NetLogo agent-based modeling"
|
|
5
|
+
abstract: >-
|
|
6
|
+
The first MCP (Model Context Protocol) server for NetLogo, enabling AI
|
|
7
|
+
assistants to create, run, and analyze agent-based models through natural
|
|
8
|
+
conversation — including declarative interface widgets, BehaviorSpace
|
|
9
|
+
parameter sweeps, and safe access to the CoMSES Net model library.
|
|
10
|
+
authors:
|
|
11
|
+
- family-names: Abbas
|
|
12
|
+
given-names: Saqlain
|
|
13
|
+
email: saqlainrazee@gmail.com
|
|
14
|
+
repository-code: "https://github.com/Razee4315/NetLogo-MCP"
|
|
15
|
+
license: MIT
|
|
16
|
+
version: 1.0.0
|
|
17
|
+
date-released: 2026-06-06
|
|
18
|
+
keywords:
|
|
19
|
+
- NetLogo
|
|
20
|
+
- agent-based modeling
|
|
21
|
+
- Model Context Protocol
|
|
22
|
+
- MCP
|
|
23
|
+
- simulation
|
|
24
|
+
- AI assistants
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Contributing to NetLogo MCP
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing! Here's how to get started.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/Razee4315/NetLogo-MCP.git
|
|
9
|
+
cd NetLogo-MCP
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
pre-commit install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
You'll need Java JDK 11+ and NetLogo 7.0+ installed for integration testing. Unit tests use mocks and don't require either.
|
|
15
|
+
|
|
16
|
+
## Running Tests
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Run tests
|
|
20
|
+
pytest tests/ -v
|
|
21
|
+
|
|
22
|
+
# Run tests with coverage report
|
|
23
|
+
pytest tests/ -v --cov=netlogo_mcp --cov-report=term-missing
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Code Quality
|
|
27
|
+
|
|
28
|
+
This project uses [Ruff](https://github.com/astral-sh/ruff) for linting/formatting and [mypy](https://mypy-lang.org/) for type checking. Pre-commit hooks run these automatically, or run them manually:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Lint
|
|
32
|
+
ruff check src/ tests/
|
|
33
|
+
|
|
34
|
+
# Format
|
|
35
|
+
ruff format src/ tests/
|
|
36
|
+
|
|
37
|
+
# Type check
|
|
38
|
+
mypy src/netlogo_mcp/
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Submitting Changes
|
|
42
|
+
|
|
43
|
+
1. Fork the repository
|
|
44
|
+
2. Create a feature branch (`git checkout -b feature/my-feature`)
|
|
45
|
+
3. Make your changes
|
|
46
|
+
4. Run tests and linting to make sure nothing breaks
|
|
47
|
+
5. Commit with a clear message
|
|
48
|
+
6. Push to your fork and open a Pull Request
|
|
49
|
+
|
|
50
|
+
## Reporting Issues
|
|
51
|
+
|
|
52
|
+
Open an issue on GitHub with:
|
|
53
|
+
- What you expected to happen
|
|
54
|
+
- What actually happened
|
|
55
|
+
- Your Python, Java, and NetLogo versions
|
|
56
|
+
- Any error messages or logs
|
|
57
|
+
|
|
58
|
+
## Code Style
|
|
59
|
+
|
|
60
|
+
- Follow existing patterns in the codebase
|
|
61
|
+
- Keep functions focused and well-named
|
|
62
|
+
- Add type hints to new functions
|
|
63
|
+
- Add tests for new tools or resources
|
|
64
|
+
- Run `ruff format` before committing
|