hms-commander-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.
- hms_commander_mcp-0.1.0/.github/workflows/candidate-content-api.yml +39 -0
- hms_commander_mcp-0.1.0/.github/workflows/dependency-review.yml +55 -0
- hms_commander_mcp-0.1.0/.github/workflows/package-compatibility.yml +81 -0
- hms_commander_mcp-0.1.0/.gitignore +5 -0
- hms_commander_mcp-0.1.0/AGENTS.md +24 -0
- hms_commander_mcp-0.1.0/CLAUDE.md +3 -0
- hms_commander_mcp-0.1.0/COMPATIBILITY.md +46 -0
- hms_commander_mcp-0.1.0/LICENSE +21 -0
- hms_commander_mcp-0.1.0/PKG-INFO +192 -0
- hms_commander_mcp-0.1.0/README.md +175 -0
- hms_commander_mcp-0.1.0/VALIDATION.md +103 -0
- hms_commander_mcp-0.1.0/build.err +7 -0
- hms_commander_mcp-0.1.0/pyproject.toml +22 -0
- hms_commander_mcp-0.1.0/scripts/propose_dependency_update.py +55 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/__init__.py +2 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/__main__.py +3 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/adapter.py +160 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/contracts.py +59 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/policy.py +131 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/server.py +88 -0
- hms_commander_mcp-0.1.0/src/hms_commander_mcp/worker.py +115 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/1__24HR.met +436 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/A1000000.gage +285 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/A1000000.hms +98 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/A1000000.run +166 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/A100_1PCT.basin +8812 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/Control_5.control +10 -0
- hms_commander_mcp-0.1.0/tests/fixtures/real-hms/PROVENANCE.json +13 -0
- hms_commander_mcp-0.1.0/tests/test_candidate_text_corpus.py +88 -0
- hms_commander_mcp-0.1.0/tests/test_contracts.py +312 -0
- hms_commander_mcp-0.1.0/tests/test_native_policy.py +59 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Candidate content API qualification
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
jobs:
|
|
8
|
+
candidate:
|
|
9
|
+
name: content-api (${{ matrix.os }})
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
11
|
+
timeout-minutes: 15
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, windows-latest]
|
|
16
|
+
env:
|
|
17
|
+
CI: '1'
|
|
18
|
+
PYTHONUNBUFFERED: '1'
|
|
19
|
+
PYTHONFAULTHANDLER: '1'
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.11'
|
|
25
|
+
- name: Install MCP candidate and declared test dependencies
|
|
26
|
+
run: python -m pip install ".[test]"
|
|
27
|
+
- name: Install exact merged upstream content API candidate
|
|
28
|
+
# Separate from the released PyPI minimum/current compatibility matrix.
|
|
29
|
+
# A source commit is qualification evidence, not a published-support claim.
|
|
30
|
+
run: python -m pip install --force-reinstall --no-deps "hms-commander @ git+https://github.com/gpt-cmdr/hms-commander.git@4b71b4f137331a5f391873edfd87c281be24767e"
|
|
31
|
+
- name: Require candidate public API before qualification
|
|
32
|
+
run: python -c "from hms_commander import HmsText; assert HmsText is not None"
|
|
33
|
+
- name: Qualify public synthetic and maintained SDK contracts
|
|
34
|
+
timeout-minutes: 10
|
|
35
|
+
run: python -m pytest tests -q
|
|
36
|
+
- name: Record exact dependency and source identities
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip check
|
|
39
|
+
python -m pip freeze
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Propose dependency refresh
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: '23 8 * * 1'
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
jobs:
|
|
9
|
+
propose:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write
|
|
13
|
+
pull-requests: write
|
|
14
|
+
actions: write
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
ref: ${{ github.event.repository.default_branch }}
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: '3.11'
|
|
22
|
+
- run: python -m pip install 'packaging>=24'
|
|
23
|
+
- name: Compare stable PyPI metadata and prepare candidate
|
|
24
|
+
run: python scripts/propose_dependency_update.py --apply
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: dependency-review
|
|
28
|
+
path: dependency-review.json
|
|
29
|
+
- name: Open update PR if compatible lower bounds changed
|
|
30
|
+
env:
|
|
31
|
+
GH_TOKEN: ${{ github.token }}
|
|
32
|
+
shell: bash
|
|
33
|
+
run: |
|
|
34
|
+
if git diff --quiet -- pyproject.toml; then exit 0; fi
|
|
35
|
+
branch='maintenance/dependency-refresh'
|
|
36
|
+
# Refresh this owned branch's tracking ref so --force-with-lease works
|
|
37
|
+
# on repeated runs from a shallow default-branch checkout.
|
|
38
|
+
if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then
|
|
39
|
+
git fetch origin "$branch:refs/remotes/origin/$branch"
|
|
40
|
+
fi
|
|
41
|
+
git checkout -B "$branch"
|
|
42
|
+
git config user.name 'github-actions[bot]'
|
|
43
|
+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
|
|
44
|
+
git add pyproject.toml
|
|
45
|
+
git commit -m 'Propose compatible dependency refresh'
|
|
46
|
+
git push --force-with-lease origin "$branch"
|
|
47
|
+
python - <<'PY'
|
|
48
|
+
from pathlib import Path
|
|
49
|
+
Path('pr-body.md').write_text('Proposes current stable versions within existing dependency ranges. Review the metadata artifact, exact compatibility evidence and wheel/sdist metadata before merge. No runtime upgrades, range widening, merge or publication are performed.\n')
|
|
50
|
+
PY
|
|
51
|
+
if ! gh pr view "$branch" --json number >/dev/null 2>&1; then
|
|
52
|
+
gh pr create --head "$branch" --title 'Propose compatible dependency refresh' --body-file pr-body.md --draft
|
|
53
|
+
fi
|
|
54
|
+
# GITHUB_TOKEN-created PRs do not trigger ordinary pull_request CI.
|
|
55
|
+
gh workflow run package-compatibility.yml --ref "$branch"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: Package compatibility candidates
|
|
2
|
+
on:
|
|
3
|
+
workflow_dispatch:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
jobs:
|
|
10
|
+
package:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 10
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python: ['3.10', '3.11', '3.12']
|
|
17
|
+
dependencies: [minimum, latest-compatible]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
- uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python }}
|
|
23
|
+
- name: Install minimum dependency candidates
|
|
24
|
+
if: matrix.dependencies == 'minimum'
|
|
25
|
+
run: |
|
|
26
|
+
python - <<'PY' > minimum-constraints.txt
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
import re
|
|
29
|
+
text = Path('pyproject.toml').read_text()
|
|
30
|
+
for package in ('mcp', 'hms-commander'):
|
|
31
|
+
match = re.search(r'"' + re.escape(package) + r'>=([^,"]+)', text)
|
|
32
|
+
print(package + '==' + match.group(1))
|
|
33
|
+
PY
|
|
34
|
+
python -m pip install -c minimum-constraints.txt ".[test]"
|
|
35
|
+
- name: Install latest compatible dependency candidates
|
|
36
|
+
if: matrix.dependencies == 'latest-compatible'
|
|
37
|
+
run: python -m pip install --upgrade ".[test]"
|
|
38
|
+
- name: Public API, bounded-read and official SDK stdio contracts
|
|
39
|
+
run: python -m pytest tests -q
|
|
40
|
+
- name: Record resolved versions and resolver consistency
|
|
41
|
+
run: |
|
|
42
|
+
python -m pip check
|
|
43
|
+
python -m pip freeze > resolved-versions.txt
|
|
44
|
+
- name: Build wheel and source distribution
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install build
|
|
47
|
+
python -m build
|
|
48
|
+
- name: Inspect wheel dependency and entrypoint metadata
|
|
49
|
+
run: |
|
|
50
|
+
python - <<'PY'
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
import zipfile
|
|
53
|
+
wheel = next(Path('dist').glob('*.whl'))
|
|
54
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
55
|
+
for name in archive.namelist():
|
|
56
|
+
if name.endswith(('METADATA', 'entry_points.txt')):
|
|
57
|
+
print(archive.read(name).decode())
|
|
58
|
+
PY
|
|
59
|
+
- uses: actions/upload-artifact@v4
|
|
60
|
+
with:
|
|
61
|
+
name: package-${{ matrix.python }}-${{ matrix.dependencies }}
|
|
62
|
+
path: |
|
|
63
|
+
dist/
|
|
64
|
+
resolved-versions.txt
|
|
65
|
+
|
|
66
|
+
windows-policy:
|
|
67
|
+
runs-on: windows-latest
|
|
68
|
+
timeout-minutes: 10
|
|
69
|
+
env:
|
|
70
|
+
PYTHONUNBUFFERED: '1'
|
|
71
|
+
PYTHONFAULTHANDLER: '1'
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@v4
|
|
74
|
+
- uses: actions/setup-python@v5
|
|
75
|
+
with:
|
|
76
|
+
python-version: '3.11'
|
|
77
|
+
- run: python -m pip install ".[test]"
|
|
78
|
+
- name: Native Windows handle containment and approved text reads
|
|
79
|
+
timeout-minutes: 3
|
|
80
|
+
run: >-
|
|
81
|
+
python -X faulthandler -c "import faulthandler,pytest; faulthandler.dump_traceback_later(30, repeat=True); raise SystemExit(pytest.main(['tests/test_native_policy.py', '-vv', '-s', '-o', 'faulthandler_timeout=30']))"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# HMS Commander MCP agent contract
|
|
2
|
+
|
|
3
|
+
This repository owns a constrained informational server. Preserve read-only,
|
|
4
|
+
low-dependency, non-spatial/non-gridded output and subagent-only client routing.
|
|
5
|
+
Only explicit typed tools are registered. Do not reflect the domain library into
|
|
6
|
+
MCP. Do not add model execution, setters, cloning, exports, downloads, generic
|
|
7
|
+
file/SQL/code readers, geometry, DSS/HDF/SQLite or gridded data. Use public HMS
|
|
8
|
+
library APIs; domain parsers remain upstream. No global project state.
|
|
9
|
+
|
|
10
|
+
Read README.md and COMPATIBILITY.md before changes. Keep stdout for MCP wire
|
|
11
|
+
traffic, logs on stderr, configured roots enforced, and byte/row/character/time
|
|
12
|
+
limits enforced with explicit counts/truncation. Per-request objects and workers
|
|
13
|
+
must not retain a prior project's state. Do not accept terms or infer suitability
|
|
14
|
+
from successful parsing. Annotations and client roots are not access controls.
|
|
15
|
+
|
|
16
|
+
HEC is primary for documented HEC-HMS methods and terminology. State supported
|
|
17
|
+
project capabilities and reproducible observations directly, with their scope.
|
|
18
|
+
Maintain an objective independent third-party voice and passive official HEC
|
|
19
|
+
references. Repository editorial standards do not apply to users' external work.
|
|
20
|
+
|
|
21
|
+
Dependency update PRs need minimum/latest contract and wheel/sdist evidence.
|
|
22
|
+
Preserve user pins; no runtime pip install, unattended merge/publish, or dependency
|
|
23
|
+
range widening without qualification. Do not run tests, model engines or user
|
|
24
|
+
project processing unless the task authorizes that work.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Compatibility evidence and release prerequisites
|
|
2
|
+
|
|
3
|
+
Qualification date: October 4, 2026. Package identities and MCP protocol revision
|
|
4
|
+
are separate. Minimum and latest-compatible stable releases were identical on
|
|
5
|
+
this date: official MCP SDK **2.3.0**, HMS Commander **0.3.1**.
|
|
6
|
+
|
|
7
|
+
| Dependency/environment | Evidence |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Official MCP SDK 2.3.0 | Typed schemas, actionable errors and stdio auto/legacy modes passed locally |
|
|
10
|
+
| Published HMS Commander 0.3.1 | Linux public standalone getter contracts passed on real repository text fixtures |
|
|
11
|
+
| Companion HmsText source, unreleased | Content API and upstream fixture contracts passed locally; not published evidence |
|
|
12
|
+
| Linux CPython 3.11.2 | Read-only/path/encoding/bounds/timeout/concurrency/status and package checks passed |
|
|
13
|
+
| Linux Python 3.10.21/3.11.16/3.12.14 | Six minimum/latest-compatible jobs passed: 31 tests and1 optional-network skip each; pipcheck and builds passed |
|
|
14
|
+
| Windows CPython 3.11.9 | Native file-policy subset passed 12 tests with no skips; full domain adapter not qualified |
|
|
15
|
+
|
|
16
|
+
See [VALIDATION.md](VALIDATION.md) for exact checks, source provenance and limits.
|
|
17
|
+
A resolver range is not proof that every version has passed qualification.
|
|
18
|
+
|
|
19
|
+
Current-release transition permits approved basin/met/control/gage reads on
|
|
20
|
+
Linux using existing public getters and sealed memfd snapshots. This is a
|
|
21
|
+
compatibility bridge, not a second domain parser. HmsText replaces it through
|
|
22
|
+
capability detection. The transition omits gage type because the current public
|
|
23
|
+
getter can default a missing source `Type` to `Precipitation`; MCP does not present
|
|
24
|
+
that default as an observation. Empty met/control getter records are also omitted; this does not establish
|
|
25
|
+
that the source lacks a named section header. HmsPrj.initialize is excluded because even with DSS loading
|
|
26
|
+
disabled it invokes SQLite/CRS discovery. No heavy extras are requested, but base
|
|
27
|
+
HMS dependencies remain installed.
|
|
28
|
+
|
|
29
|
+
Project/run reads and all Windows domain reads require the upstream HmsText
|
|
30
|
+
release. Publish it before claiming those capabilities against PyPI or raising
|
|
31
|
+
the wrapper minimum. Windows CI currently qualifies secure text I/O and path
|
|
32
|
+
policy separately, not the unreleased full domain adapter. Native link denial
|
|
33
|
+
can be skipped if the host lacks link privileges; inspect CI skips before release.
|
|
34
|
+
No binary, GIS, Java or engine case is included in MCP qualification.
|
|
35
|
+
|
|
36
|
+
CI exercises declared minimum and latest-compatible public dependencies,
|
|
37
|
+
functional contracts and wheel/sdist builds. Latest/minimum behavior and updated
|
|
38
|
+
metadata must be reviewed before changing ranges or publishing. Preserve user
|
|
39
|
+
pins; no runtime auto-upgrade, unattended merge or publication.
|
|
40
|
+
|
|
41
|
+
Remote evidence: [run 37165170753](https://github.com/gpt-cmdr/hms-commander-mcp/actions/runs/37165170753),
|
|
42
|
+
source head 8e04b3c, all 7 jobs successful. Windows policy coverage includes traversal,
|
|
43
|
+
extensions/streams, unconfigured roots, NUL/oversize inputs, real text reads and
|
|
44
|
+
leaf link denial. It does not establish Windows HmsText domain/stdio behavior.
|
|
45
|
+
The earlier cancelled Windows run had no retrievable diagnostic log; its stall
|
|
46
|
+
cause remains unconfirmed.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CLB Engineering Corporation
|
|
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 copies
|
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
10
|
+
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,192 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: hms-commander-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Bounded read-only HEC-HMS text information through MCP
|
|
5
|
+
Author: CLB Engineering Corporation
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: hms-commander<0.5,>=0.3.1
|
|
10
|
+
Requires-Dist: mcp<3,>=2.3.0
|
|
11
|
+
Requires-Dist: packaging>=24
|
|
12
|
+
Requires-Dist: pydantic<3,>=2.12
|
|
13
|
+
Provides-Extra: test
|
|
14
|
+
Requires-Dist: jsonschema>=4.20; extra == 'test'
|
|
15
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# HMS Commander MCP
|
|
19
|
+
|
|
20
|
+
HMS Commander MCP supplies bounded information from HEC-HMS text files. It is
|
|
21
|
+
an independent CLB Engineering project that complements HEC's work; it is not
|
|
22
|
+
associated with or endorsed by HEC. Technical terminology follows HEC's
|
|
23
|
+
[HEC-HMS documentation](https://www.hec.usace.army.mil/confluence/hmsdocs).
|
|
24
|
+
Those links are passive references; the server does not retrieve HEC pages.
|
|
25
|
+
|
|
26
|
+
## Purpose and boundary
|
|
27
|
+
|
|
28
|
+
Use this server through a **bounded informational subagent**. The parent supplies
|
|
29
|
+
one question, a configured project root, named file/entities, selected fields,
|
|
30
|
+
and row/character/time budgets. The child returns a compact answer with source
|
|
31
|
+
identity, versions, units/time basis, counts, truncation, and blockers. The host
|
|
32
|
+
must expose project MCP tools only to that child. A server cannot attest whether
|
|
33
|
+
a caller is a subagent. A host without isolation should use a scoped Python read
|
|
34
|
+
instead of exposing these tools to its main coordinator.
|
|
35
|
+
|
|
36
|
+
The server reads approved project/component text, scalar parameters, gage
|
|
37
|
+
configuration, and control/run relationships. It does not modify projects,
|
|
38
|
+
compute models, download data, export files, or read DSS/HDF/SQLite, coordinates,
|
|
39
|
+
geometry, rasters, grids, or spatial results. Filenames and DSS pathnames are
|
|
40
|
+
references only and are never followed. Text-series/report extraction is deferred
|
|
41
|
+
until a dedicated upstream public reader can provide a qualified contract;
|
|
42
|
+
there is no generic file reader. Larger investigations use public
|
|
43
|
+
[hms-commander Python APIs](https://rascommander.info/hms/) and their required
|
|
44
|
+
extras outside MCP.
|
|
45
|
+
|
|
46
|
+
## Install and configure
|
|
47
|
+
|
|
48
|
+
This candidate is developed in public and has not been published to PyPI. From
|
|
49
|
+
its checkout:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
python -m pip install .
|
|
53
|
+
hms-commander-mcp --root /absolute/path/to/project
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Repeat `--root` for additional allowed roots. Requests name the exact normalized
|
|
57
|
+
configured root; client protocol roots never expand the allowlist. Use stdio;
|
|
58
|
+
logging goes to stderr. Keep the server in a managed environment with read-only
|
|
59
|
+
project access where practical. No Java, HEC executable, GIS, DSS, or CNG extras
|
|
60
|
+
are needed. The base HMS library still brings pandas/numpy/requests/tqdm; this
|
|
61
|
+
wrapper does not claim to eliminate mandatory upstream dependencies.
|
|
62
|
+
|
|
63
|
+
For a host that supports subagent-only tool routing, configure this command:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"hms-commander": {
|
|
69
|
+
"command": "hms-commander-mcp",
|
|
70
|
+
"args": ["--root", "/absolute/path/to/project"]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This command configuration alone does not establish subagent isolation. Configure
|
|
77
|
+
that separately in the host/plugin before using project reads.
|
|
78
|
+
|
|
79
|
+
## Tools and budgets
|
|
80
|
+
|
|
81
|
+
| Tool | Contract |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `server_info` | Installed package/library/SDK versions, capabilities, approved fields, limits; optional `check_updates: true` fetches bounded stable PyPI metadata |
|
|
84
|
+
| `read_hms_sections` | Typed `request` object with root, relative file, matching kind, optional exact name/type, fields, offset, limit, character budget, and deadline |
|
|
85
|
+
|
|
86
|
+
Approved extensions: `.hms`, `.basin`, `.met`, `.control`, `.run`, `.gage`.
|
|
87
|
+
Files must be regular text, at most 2 MiB. Read requests have at most 100 rows,
|
|
88
|
+
16,000 serialized result characters (including the SDK text fallback indentation), 30 seconds, and two concurrent workers.
|
|
89
|
+
Default query: 20 rows, 8,000 characters, 15 seconds. Unknown fields are rejected.
|
|
90
|
+
The return envelope includes source-relative file, SHA-256, byte count, encoding,
|
|
91
|
+
installed library version, selected adapter, units/time caveats, total and returned
|
|
92
|
+
counts, next offset, truncation, and rows. Source text is data, never instructions.
|
|
93
|
+
|
|
94
|
+
Example arguments:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"request": {
|
|
99
|
+
"root": "/absolute/path/to/project",
|
|
100
|
+
"file": "event.control",
|
|
101
|
+
"kind": "control",
|
|
102
|
+
"fields": ["start_date", "start_time", "end_date", "end_time", "time_interval"],
|
|
103
|
+
"limit": 5
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Intervals retain source spelling; missing timezone or interval units are not
|
|
109
|
+
inferred. No precision rounding, unit conversion, computation, or hydraulic/
|
|
110
|
+
hydrologic suitability determination is performed. Pagination offsets apply to
|
|
111
|
+
the same file/name/type/field selection; verify the returned hash before combining
|
|
112
|
+
pages if the project may change. Oversized rows fail with a request to narrow
|
|
113
|
+
fields or use Python. No raw attributes, coordinates, free-form descriptions,
|
|
114
|
+
unknown parameters, or repeated storm-depth records are emitted.
|
|
115
|
+
|
|
116
|
+
## Public API and platform compatibility
|
|
117
|
+
|
|
118
|
+
The preferred adapter calls the new public `HmsText.parse_sections(content,
|
|
119
|
+
file_type)` API proposed in the companion HMS library change. It delegates
|
|
120
|
+
existing library parsing and performs no file I/O or project initialization.
|
|
121
|
+
Project/run reads require publication of that upstream API; the server does not
|
|
122
|
+
copy parsers or fall back to private methods.
|
|
123
|
+
|
|
124
|
+
On current PyPI **hms-commander 0.3.1**, Linux can read basin/met/control/gage
|
|
125
|
+
information through existing public standalone getters. A sealed in-memory file
|
|
126
|
+
snapshot supplies a stable path without writing any project or temporary file.
|
|
127
|
+
The transition contract is narrower: basin inventory contains primary scalar
|
|
128
|
+
fields, and met/control identities use filename stems rather than parsed section
|
|
129
|
+
names. Text `.hms` and `.run` reads fail clearly until HmsText is installed.
|
|
130
|
+
Gage type is omitted in the transition adapter because the public getter supplies
|
|
131
|
+
`Precipitation` when the source omits `Type`; that default is not reported as an
|
|
132
|
+
observed source value. HmsText reports `Type` only when present. Empty met/control getter records are also omitted; this does not establish
|
|
133
|
+
that the source lacks a named section header.
|
|
134
|
+
Windows has no transition adapter: it requires the upstream HmsText release.
|
|
135
|
+
|
|
136
|
+
POSIX input handling opens each path component with no-follow directory
|
|
137
|
+
handles. Windows input handling verifies the opened handle's final target lies
|
|
138
|
+
inside the configured root before reading and rejects leaf reparse points.
|
|
139
|
+
The native Windows file-policy subset passed 12 tests on Python 3.11.9. Full
|
|
140
|
+
Windows domain reads still need the upstream HmsText release and separate domain/
|
|
141
|
+
stdio qualification; do not infer those from file-policy results. Other platforms fail closed.
|
|
142
|
+
Each read runs in a separate killable process. No HmsPrj initialization, global
|
|
143
|
+
project selection, CRS detection, result loading, sidecar creation, or engine
|
|
144
|
+
lookup is invoked. The audited default logging setup uses stderr and no log file.
|
|
145
|
+
|
|
146
|
+
## Version and release policy
|
|
147
|
+
|
|
148
|
+
Dependency candidates: `mcp>=2.3.0,<3` (official SDK, no CLI extra) and
|
|
149
|
+
`hms-commander>=0.3.1,<0.5` (base only). Pydantic is explicitly declared
|
|
150
|
+
for the typed contracts (already required by the SDK); packaging supplies standard
|
|
151
|
+
version comparison. This range is an implementation target,
|
|
152
|
+
not a claim that every version has passed qualification. See
|
|
153
|
+
[COMPATIBILITY.md](COMPATIBILITY.md) for exact evidence and release prerequisites.
|
|
154
|
+
|
|
155
|
+
Runtime reports installed versions without installing or upgrading packages.
|
|
156
|
+
`server_info(check_updates=true)` explicitly opts into fixed official PyPI metadata
|
|
157
|
+
endpoints, capped at 512 KiB per package and a five-second worker deadline. Offline
|
|
158
|
+
or unavailable metadata is reported; the default makes no network request.
|
|
159
|
+
Users retain their pins/locks. New managed installs should resolve current
|
|
160
|
+
compatible releases; refresh a managed environment explicitly after inspecting
|
|
161
|
+
an update. The scheduled/manual dependency workflow compares stable PyPI metadata
|
|
162
|
+
and proposes a PR for compatible drift. Versions outside declared ranges are
|
|
163
|
+
reported as requiring maintainer review, never silently admitted. CI checks
|
|
164
|
+
minimum/current-stable installs and packaging; merge and publication remain human
|
|
165
|
+
steps. Publication of HmsText precedes claiming cross-platform project/run reads.
|
|
166
|
+
|
|
167
|
+
## Specification and sources
|
|
168
|
+
|
|
169
|
+
Implemented against the official [Python SDK v2](https://py.sdk.modelcontextprotocol.io/),
|
|
170
|
+
its [tool contracts](https://py.sdk.modelcontextprotocol.io/servers/tools/),
|
|
171
|
+
[structured output](https://py.sdk.modelcontextprotocol.io/servers/structured-output/),
|
|
172
|
+
and [stdio specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio).
|
|
173
|
+
The SDK owns negotiation and wire serialization; this package does not recreate
|
|
174
|
+
initialization/discovery. Official SDK auto and legacy client modes passed local
|
|
175
|
+
stdio contracts; this does not establish compatibility with every host.
|
|
176
|
+
Annotations describe behavior; roots, field selection, file validation, isolation,
|
|
177
|
+
and result bounds enforce it. No sampling, elicitation, remote transport, task,
|
|
178
|
+
resource, audio, image, or UI feature is enabled merely because MCP supports it.
|
|
179
|
+
|
|
180
|
+
Published API baseline inspected: [hms-commander 0.3.1](https://pypi.org/project/hms-commander/0.3.1/).
|
|
181
|
+
HEC methods/terminology are primary HEC sources. This project's capabilities and
|
|
182
|
+
observations use its own package evidence. Repository writing instructions apply
|
|
183
|
+
to repository-maintained text, not users' external scripts/reports/deliverables.
|
|
184
|
+
|
|
185
|
+
## Qualification
|
|
186
|
+
|
|
187
|
+
On Linux CPython 3.11.2, 31 current-release/wheel contracts and 39 companion-source
|
|
188
|
+
contracts passed, including SDK stdio auto/legacy modes and bounded read-only
|
|
189
|
+
behavior. One explicitly enabled live PyPI metadata check passed. Linux minimum/latest CI passed on Python 3.10.21/3.11.16/3.12.14;
|
|
190
|
+
the native Windows Python 3.11.9 file-policy subset passed 12 tests without skips.
|
|
191
|
+
Full Windows domain/stdio qualification remains separate. [Validation details](VALIDATION.md) distinguish published
|
|
192
|
+
0.3.1 compatibility from unreleased HmsText source evidence.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# HMS Commander MCP
|
|
2
|
+
|
|
3
|
+
HMS Commander MCP supplies bounded information from HEC-HMS text files. It is
|
|
4
|
+
an independent CLB Engineering project that complements HEC's work; it is not
|
|
5
|
+
associated with or endorsed by HEC. Technical terminology follows HEC's
|
|
6
|
+
[HEC-HMS documentation](https://www.hec.usace.army.mil/confluence/hmsdocs).
|
|
7
|
+
Those links are passive references; the server does not retrieve HEC pages.
|
|
8
|
+
|
|
9
|
+
## Purpose and boundary
|
|
10
|
+
|
|
11
|
+
Use this server through a **bounded informational subagent**. The parent supplies
|
|
12
|
+
one question, a configured project root, named file/entities, selected fields,
|
|
13
|
+
and row/character/time budgets. The child returns a compact answer with source
|
|
14
|
+
identity, versions, units/time basis, counts, truncation, and blockers. The host
|
|
15
|
+
must expose project MCP tools only to that child. A server cannot attest whether
|
|
16
|
+
a caller is a subagent. A host without isolation should use a scoped Python read
|
|
17
|
+
instead of exposing these tools to its main coordinator.
|
|
18
|
+
|
|
19
|
+
The server reads approved project/component text, scalar parameters, gage
|
|
20
|
+
configuration, and control/run relationships. It does not modify projects,
|
|
21
|
+
compute models, download data, export files, or read DSS/HDF/SQLite, coordinates,
|
|
22
|
+
geometry, rasters, grids, or spatial results. Filenames and DSS pathnames are
|
|
23
|
+
references only and are never followed. Text-series/report extraction is deferred
|
|
24
|
+
until a dedicated upstream public reader can provide a qualified contract;
|
|
25
|
+
there is no generic file reader. Larger investigations use public
|
|
26
|
+
[hms-commander Python APIs](https://rascommander.info/hms/) and their required
|
|
27
|
+
extras outside MCP.
|
|
28
|
+
|
|
29
|
+
## Install and configure
|
|
30
|
+
|
|
31
|
+
This candidate is developed in public and has not been published to PyPI. From
|
|
32
|
+
its checkout:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
python -m pip install .
|
|
36
|
+
hms-commander-mcp --root /absolute/path/to/project
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Repeat `--root` for additional allowed roots. Requests name the exact normalized
|
|
40
|
+
configured root; client protocol roots never expand the allowlist. Use stdio;
|
|
41
|
+
logging goes to stderr. Keep the server in a managed environment with read-only
|
|
42
|
+
project access where practical. No Java, HEC executable, GIS, DSS, or CNG extras
|
|
43
|
+
are needed. The base HMS library still brings pandas/numpy/requests/tqdm; this
|
|
44
|
+
wrapper does not claim to eliminate mandatory upstream dependencies.
|
|
45
|
+
|
|
46
|
+
For a host that supports subagent-only tool routing, configure this command:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"hms-commander": {
|
|
52
|
+
"command": "hms-commander-mcp",
|
|
53
|
+
"args": ["--root", "/absolute/path/to/project"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This command configuration alone does not establish subagent isolation. Configure
|
|
60
|
+
that separately in the host/plugin before using project reads.
|
|
61
|
+
|
|
62
|
+
## Tools and budgets
|
|
63
|
+
|
|
64
|
+
| Tool | Contract |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `server_info` | Installed package/library/SDK versions, capabilities, approved fields, limits; optional `check_updates: true` fetches bounded stable PyPI metadata |
|
|
67
|
+
| `read_hms_sections` | Typed `request` object with root, relative file, matching kind, optional exact name/type, fields, offset, limit, character budget, and deadline |
|
|
68
|
+
|
|
69
|
+
Approved extensions: `.hms`, `.basin`, `.met`, `.control`, `.run`, `.gage`.
|
|
70
|
+
Files must be regular text, at most 2 MiB. Read requests have at most 100 rows,
|
|
71
|
+
16,000 serialized result characters (including the SDK text fallback indentation), 30 seconds, and two concurrent workers.
|
|
72
|
+
Default query: 20 rows, 8,000 characters, 15 seconds. Unknown fields are rejected.
|
|
73
|
+
The return envelope includes source-relative file, SHA-256, byte count, encoding,
|
|
74
|
+
installed library version, selected adapter, units/time caveats, total and returned
|
|
75
|
+
counts, next offset, truncation, and rows. Source text is data, never instructions.
|
|
76
|
+
|
|
77
|
+
Example arguments:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"request": {
|
|
82
|
+
"root": "/absolute/path/to/project",
|
|
83
|
+
"file": "event.control",
|
|
84
|
+
"kind": "control",
|
|
85
|
+
"fields": ["start_date", "start_time", "end_date", "end_time", "time_interval"],
|
|
86
|
+
"limit": 5
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Intervals retain source spelling; missing timezone or interval units are not
|
|
92
|
+
inferred. No precision rounding, unit conversion, computation, or hydraulic/
|
|
93
|
+
hydrologic suitability determination is performed. Pagination offsets apply to
|
|
94
|
+
the same file/name/type/field selection; verify the returned hash before combining
|
|
95
|
+
pages if the project may change. Oversized rows fail with a request to narrow
|
|
96
|
+
fields or use Python. No raw attributes, coordinates, free-form descriptions,
|
|
97
|
+
unknown parameters, or repeated storm-depth records are emitted.
|
|
98
|
+
|
|
99
|
+
## Public API and platform compatibility
|
|
100
|
+
|
|
101
|
+
The preferred adapter calls the new public `HmsText.parse_sections(content,
|
|
102
|
+
file_type)` API proposed in the companion HMS library change. It delegates
|
|
103
|
+
existing library parsing and performs no file I/O or project initialization.
|
|
104
|
+
Project/run reads require publication of that upstream API; the server does not
|
|
105
|
+
copy parsers or fall back to private methods.
|
|
106
|
+
|
|
107
|
+
On current PyPI **hms-commander 0.3.1**, Linux can read basin/met/control/gage
|
|
108
|
+
information through existing public standalone getters. A sealed in-memory file
|
|
109
|
+
snapshot supplies a stable path without writing any project or temporary file.
|
|
110
|
+
The transition contract is narrower: basin inventory contains primary scalar
|
|
111
|
+
fields, and met/control identities use filename stems rather than parsed section
|
|
112
|
+
names. Text `.hms` and `.run` reads fail clearly until HmsText is installed.
|
|
113
|
+
Gage type is omitted in the transition adapter because the public getter supplies
|
|
114
|
+
`Precipitation` when the source omits `Type`; that default is not reported as an
|
|
115
|
+
observed source value. HmsText reports `Type` only when present. Empty met/control getter records are also omitted; this does not establish
|
|
116
|
+
that the source lacks a named section header.
|
|
117
|
+
Windows has no transition adapter: it requires the upstream HmsText release.
|
|
118
|
+
|
|
119
|
+
POSIX input handling opens each path component with no-follow directory
|
|
120
|
+
handles. Windows input handling verifies the opened handle's final target lies
|
|
121
|
+
inside the configured root before reading and rejects leaf reparse points.
|
|
122
|
+
The native Windows file-policy subset passed 12 tests on Python 3.11.9. Full
|
|
123
|
+
Windows domain reads still need the upstream HmsText release and separate domain/
|
|
124
|
+
stdio qualification; do not infer those from file-policy results. Other platforms fail closed.
|
|
125
|
+
Each read runs in a separate killable process. No HmsPrj initialization, global
|
|
126
|
+
project selection, CRS detection, result loading, sidecar creation, or engine
|
|
127
|
+
lookup is invoked. The audited default logging setup uses stderr and no log file.
|
|
128
|
+
|
|
129
|
+
## Version and release policy
|
|
130
|
+
|
|
131
|
+
Dependency candidates: `mcp>=2.3.0,<3` (official SDK, no CLI extra) and
|
|
132
|
+
`hms-commander>=0.3.1,<0.5` (base only). Pydantic is explicitly declared
|
|
133
|
+
for the typed contracts (already required by the SDK); packaging supplies standard
|
|
134
|
+
version comparison. This range is an implementation target,
|
|
135
|
+
not a claim that every version has passed qualification. See
|
|
136
|
+
[COMPATIBILITY.md](COMPATIBILITY.md) for exact evidence and release prerequisites.
|
|
137
|
+
|
|
138
|
+
Runtime reports installed versions without installing or upgrading packages.
|
|
139
|
+
`server_info(check_updates=true)` explicitly opts into fixed official PyPI metadata
|
|
140
|
+
endpoints, capped at 512 KiB per package and a five-second worker deadline. Offline
|
|
141
|
+
or unavailable metadata is reported; the default makes no network request.
|
|
142
|
+
Users retain their pins/locks. New managed installs should resolve current
|
|
143
|
+
compatible releases; refresh a managed environment explicitly after inspecting
|
|
144
|
+
an update. The scheduled/manual dependency workflow compares stable PyPI metadata
|
|
145
|
+
and proposes a PR for compatible drift. Versions outside declared ranges are
|
|
146
|
+
reported as requiring maintainer review, never silently admitted. CI checks
|
|
147
|
+
minimum/current-stable installs and packaging; merge and publication remain human
|
|
148
|
+
steps. Publication of HmsText precedes claiming cross-platform project/run reads.
|
|
149
|
+
|
|
150
|
+
## Specification and sources
|
|
151
|
+
|
|
152
|
+
Implemented against the official [Python SDK v2](https://py.sdk.modelcontextprotocol.io/),
|
|
153
|
+
its [tool contracts](https://py.sdk.modelcontextprotocol.io/servers/tools/),
|
|
154
|
+
[structured output](https://py.sdk.modelcontextprotocol.io/servers/structured-output/),
|
|
155
|
+
and [stdio specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio).
|
|
156
|
+
The SDK owns negotiation and wire serialization; this package does not recreate
|
|
157
|
+
initialization/discovery. Official SDK auto and legacy client modes passed local
|
|
158
|
+
stdio contracts; this does not establish compatibility with every host.
|
|
159
|
+
Annotations describe behavior; roots, field selection, file validation, isolation,
|
|
160
|
+
and result bounds enforce it. No sampling, elicitation, remote transport, task,
|
|
161
|
+
resource, audio, image, or UI feature is enabled merely because MCP supports it.
|
|
162
|
+
|
|
163
|
+
Published API baseline inspected: [hms-commander 0.3.1](https://pypi.org/project/hms-commander/0.3.1/).
|
|
164
|
+
HEC methods/terminology are primary HEC sources. This project's capabilities and
|
|
165
|
+
observations use its own package evidence. Repository writing instructions apply
|
|
166
|
+
to repository-maintained text, not users' external scripts/reports/deliverables.
|
|
167
|
+
|
|
168
|
+
## Qualification
|
|
169
|
+
|
|
170
|
+
On Linux CPython 3.11.2, 31 current-release/wheel contracts and 39 companion-source
|
|
171
|
+
contracts passed, including SDK stdio auto/legacy modes and bounded read-only
|
|
172
|
+
behavior. One explicitly enabled live PyPI metadata check passed. Linux minimum/latest CI passed on Python 3.10.21/3.11.16/3.12.14;
|
|
173
|
+
the native Windows Python 3.11.9 file-policy subset passed 12 tests without skips.
|
|
174
|
+
Full Windows domain/stdio qualification remains separate. [Validation details](VALIDATION.md) distinguish published
|
|
175
|
+
0.3.1 compatibility from unreleased HmsText source evidence.
|