healthcloud-cli 3.1.0__tar.gz → 3.2.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.
- healthcloud_cli-3.2.0/.gitignore +257 -0
- healthcloud_cli-3.2.0/PKG-INFO +405 -0
- healthcloud_cli-3.2.0/README.md +387 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/__init__.py +0 -1
- healthcloud_cli-3.2.0/healthcloud_cli/ams/__init__.py +1 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/auth.py +49 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/commands.py +242 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/output.py +70 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/target.py +117 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/tuning.py +247 -0
- healthcloud_cli-3.2.0/healthcloud_cli/ams/ui.py +54 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/cli.py +45 -18
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/context.py +9 -9
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/contracts/mcp-tools.manifest.json +682 -61
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/manifest.py +9 -5
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/output.py +2 -1
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/params.py +4 -8
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/pyproject.toml +9 -4
- healthcloud_cli-3.1.0/.gitignore +0 -110
- healthcloud_cli-3.1.0/PKG-INFO +0 -242
- healthcloud_cli-3.1.0/README.md +0 -227
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/hatch_build.py +0 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/contracts/__init__.py +0 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/main.py +0 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/healthcloud_cli/util.py +0 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/scripts/__init__.py +0 -0
- {healthcloud_cli-3.1.0 → healthcloud_cli-3.2.0}/scripts/bundle_manifest.py +0 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
tests/integration/artifacts/
|
|
2
|
+
test-artifacts/
|
|
3
|
+
|
|
4
|
+
# ── Python ────────────────────────────────────────────────────────────────────
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
*.pyo
|
|
9
|
+
*.pyd
|
|
10
|
+
*.pyc
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
dist/
|
|
14
|
+
build/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
*.egg
|
|
17
|
+
.eggs/
|
|
18
|
+
wheels/
|
|
19
|
+
MANIFEST
|
|
20
|
+
|
|
21
|
+
# Virtual environments
|
|
22
|
+
.venv/
|
|
23
|
+
venv/
|
|
24
|
+
env/
|
|
25
|
+
.env/
|
|
26
|
+
ENV/
|
|
27
|
+
env.bak/
|
|
28
|
+
venv.bak/
|
|
29
|
+
|
|
30
|
+
# Installer logs
|
|
31
|
+
pip-log.txt
|
|
32
|
+
pip-delete-this-directory.txt
|
|
33
|
+
|
|
34
|
+
# ── Testing ───────────────────────────────────────────────────────────────────
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
.coverage
|
|
37
|
+
.coverage.*
|
|
38
|
+
coverage.xml
|
|
39
|
+
htmlcov/
|
|
40
|
+
*.cover
|
|
41
|
+
*.tox/
|
|
42
|
+
nosetests.xml
|
|
43
|
+
test-results/
|
|
44
|
+
junit.xml
|
|
45
|
+
|
|
46
|
+
# ── Type checking ─────────────────────────────────────────────────────────────
|
|
47
|
+
.mypy_cache/
|
|
48
|
+
.dmypy.json
|
|
49
|
+
dmypy.json
|
|
50
|
+
.pytype/
|
|
51
|
+
.pyre/
|
|
52
|
+
|
|
53
|
+
# ── Secrets (never commit) ────────────────────────────────────────────────────
|
|
54
|
+
gcp-key.json
|
|
55
|
+
*.key.json
|
|
56
|
+
|
|
57
|
+
# ── IDEs ──────────────────────────────────────────────────────────────────────
|
|
58
|
+
.vscode/
|
|
59
|
+
.idea/
|
|
60
|
+
*.iml
|
|
61
|
+
*.iws
|
|
62
|
+
*.ipr
|
|
63
|
+
.project
|
|
64
|
+
.classpath
|
|
65
|
+
.settings/
|
|
66
|
+
*.swp
|
|
67
|
+
*.swo
|
|
68
|
+
*~
|
|
69
|
+
|
|
70
|
+
# ── macOS ─────────────────────────────────────────────────────────────────────
|
|
71
|
+
.DS_Store
|
|
72
|
+
.AppleDouble
|
|
73
|
+
.LSOverride
|
|
74
|
+
._*
|
|
75
|
+
.Spotlight-V100
|
|
76
|
+
.Trashes
|
|
77
|
+
Icon
|
|
78
|
+
|
|
79
|
+
# ── Environment / secrets ─────────────────────────────────────────────────────
|
|
80
|
+
.env
|
|
81
|
+
.env.*
|
|
82
|
+
!.env.example
|
|
83
|
+
!.env.template
|
|
84
|
+
*.pem
|
|
85
|
+
*.key
|
|
86
|
+
*.p12
|
|
87
|
+
*.pfx
|
|
88
|
+
secrets/
|
|
89
|
+
!docs/secrets/expected-schema.json
|
|
90
|
+
credentials/
|
|
91
|
+
service-account*.json
|
|
92
|
+
*-service-account.json
|
|
93
|
+
gcp-key.json
|
|
94
|
+
sa-key.json
|
|
95
|
+
|
|
96
|
+
# ── AWS ───────────────────────────────────────────────────────────────────────
|
|
97
|
+
.aws/
|
|
98
|
+
samconfig.toml
|
|
99
|
+
packaged*.yaml
|
|
100
|
+
packaged*.json
|
|
101
|
+
.aws-sam/
|
|
102
|
+
|
|
103
|
+
# Contract baked into the Lambda package at deploy time (see the "Bundle hc
|
|
104
|
+
# shared library" step in .github/workflows/_deploy-api.yml). Build output —
|
|
105
|
+
# the source of truth stays contracts/generated/<service>/openapi.json.
|
|
106
|
+
hc/contracts/_generated/
|
|
107
|
+
|
|
108
|
+
# ── Terraform / CDK ───────────────────────────────────────────────────────────
|
|
109
|
+
.terraform/
|
|
110
|
+
*.tfstate
|
|
111
|
+
*.tfstate.*
|
|
112
|
+
*.tfplan
|
|
113
|
+
cdk.out/
|
|
114
|
+
cdk.context.json
|
|
115
|
+
|
|
116
|
+
# ── Docker ────────────────────────────────────────────────────────────────────
|
|
117
|
+
*.dockerignore
|
|
118
|
+
|
|
119
|
+
# ── Node (if any tooling) ─────────────────────────────────────────────────────
|
|
120
|
+
node_modules/
|
|
121
|
+
npm-debug.log*
|
|
122
|
+
yarn-debug.log*
|
|
123
|
+
yarn-error.log*
|
|
124
|
+
.npm/
|
|
125
|
+
.yarn/
|
|
126
|
+
|
|
127
|
+
# ── Logs ──────────────────────────────────────────────────────────────────────
|
|
128
|
+
*.log
|
|
129
|
+
logs/
|
|
130
|
+
*.out
|
|
131
|
+
|
|
132
|
+
# ── Reports ───────────────────────────────────────────────────────────────────
|
|
133
|
+
reports/
|
|
134
|
+
*.report.json
|
|
135
|
+
*.report.html
|
|
136
|
+
|
|
137
|
+
# ── Temporary files ───────────────────────────────────────────────────────────
|
|
138
|
+
*.tmp
|
|
139
|
+
*.temp
|
|
140
|
+
*.bak
|
|
141
|
+
*.orig
|
|
142
|
+
*.rej
|
|
143
|
+
tmp/
|
|
144
|
+
temp/
|
|
145
|
+
|
|
146
|
+
# Imported SDK build and documentation outputs
|
|
147
|
+
# Logs
|
|
148
|
+
logs/
|
|
149
|
+
*.log
|
|
150
|
+
npm-debug.log*
|
|
151
|
+
yarn-debug.log*
|
|
152
|
+
yarn-error.log*
|
|
153
|
+
pnpm-debug.log*
|
|
154
|
+
|
|
155
|
+
# Environment files
|
|
156
|
+
**/live-state.json
|
|
157
|
+
|
|
158
|
+
# Node / npm
|
|
159
|
+
node_modules/
|
|
160
|
+
.npm/
|
|
161
|
+
.pnpm-store/
|
|
162
|
+
dist/
|
|
163
|
+
build/
|
|
164
|
+
|
|
165
|
+
# packages/cli/npm bundles the manifest from packages/cli/contracts at build/
|
|
166
|
+
# test time (scripts/copy-manifest.cjs) — that copy is generated, not source.
|
|
167
|
+
packages/cli/npm/contracts/
|
|
168
|
+
coverage/
|
|
169
|
+
report/
|
|
170
|
+
*.tsbuildinfo
|
|
171
|
+
|
|
172
|
+
# Python / pip
|
|
173
|
+
__pycache__/
|
|
174
|
+
*.py[cod]
|
|
175
|
+
*.pyo
|
|
176
|
+
.Python
|
|
177
|
+
.venv/
|
|
178
|
+
venv/
|
|
179
|
+
env/
|
|
180
|
+
pip-wheel-metadata/
|
|
181
|
+
*.egg-info/
|
|
182
|
+
.pytest_cache/
|
|
183
|
+
.mypy_cache/
|
|
184
|
+
.ruff_cache/
|
|
185
|
+
htmlcov/
|
|
186
|
+
|
|
187
|
+
# Java / Maven
|
|
188
|
+
target/
|
|
189
|
+
.mvn/timing.properties
|
|
190
|
+
.mvn/wrapper/maven-wrapper.jar
|
|
191
|
+
*.class
|
|
192
|
+
*.jar
|
|
193
|
+
*.war
|
|
194
|
+
*.ear
|
|
195
|
+
|
|
196
|
+
# .NET / NuGet
|
|
197
|
+
# Scoped to packages/nuget/ specifically — an unscoped `bin/`/`obj/` matches
|
|
198
|
+
# a directory of that name at ANY depth (gitignore has no implicit anchor),
|
|
199
|
+
# which silently swallowed the real source file packages/cli/npm/src/bin/hc.ts
|
|
200
|
+
# and broke that package's CI build (the file was never committed).
|
|
201
|
+
packages/nuget/**/bin/
|
|
202
|
+
packages/nuget/**/obj/
|
|
203
|
+
TestResults/
|
|
204
|
+
*.nupkg
|
|
205
|
+
*.snupkg
|
|
206
|
+
*.user
|
|
207
|
+
*.suo
|
|
208
|
+
|
|
209
|
+
# IDEs and editors
|
|
210
|
+
.idea/
|
|
211
|
+
.vscode/
|
|
212
|
+
*.swp
|
|
213
|
+
*.swo
|
|
214
|
+
.DS_Store
|
|
215
|
+
Thumbs.db
|
|
216
|
+
|
|
217
|
+
# Build outputs and caches
|
|
218
|
+
out/
|
|
219
|
+
tmp/
|
|
220
|
+
temp/
|
|
221
|
+
.cache/
|
|
222
|
+
.codegraph/
|
|
223
|
+
.parcel-cache/
|
|
224
|
+
.turbo/
|
|
225
|
+
|
|
226
|
+
# Disposable OpenAPI Generator staging and C#/Java sanity outputs
|
|
227
|
+
.generated/
|
|
228
|
+
|
|
229
|
+
# Rendered documentation, immutable S3 release snapshots, and the latest
|
|
230
|
+
# pointer are build/publish artifacts generated on demand. Versioned inputs
|
|
231
|
+
# remain the source of truth in this repository.
|
|
232
|
+
docs-data/v1/
|
|
233
|
+
docs-data/releases/
|
|
234
|
+
docs-data/latest.json
|
|
235
|
+
|
|
236
|
+
# ── Generated documentation ──────────────────────────────────────────────
|
|
237
|
+
# The pip packages force-include docs/ (hatchling errors outright if it is
|
|
238
|
+
# absent), so those two keep a .gitkeep and are populated by docs:build.
|
|
239
|
+
#
|
|
240
|
+
# Built by `npm run docs:build` from contracts/pinned + the SDK source, and
|
|
241
|
+
# published to S3 by .github/workflows/docs-publish.yml. The package publish
|
|
242
|
+
# workflows regenerate packages/*/docs before packaging, because the package
|
|
243
|
+
# manifests ship it. None of it is source -- do not commit it.
|
|
244
|
+
packages/npm/docs/
|
|
245
|
+
packages/pip/docs/*
|
|
246
|
+
!packages/pip/docs/.gitkeep
|
|
247
|
+
packages/npm-tenantadmin/docs/
|
|
248
|
+
packages/npm-ams/docs/
|
|
249
|
+
packages/pip-tenantadmin/docs/*
|
|
250
|
+
!packages/pip-tenantadmin/docs/.gitkeep
|
|
251
|
+
packages/npm/README.md
|
|
252
|
+
packages/pip/README.md
|
|
253
|
+
packages/npm-tenantadmin/README.md
|
|
254
|
+
packages/pip-tenantadmin/README.md
|
|
255
|
+
|
|
256
|
+
# Live SDK test assets stay in the archived SDK history, outside this source import.
|
|
257
|
+
integration-tests/shared/test-assets/
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: healthcloud-cli
|
|
3
|
+
Version: 3.2.0
|
|
4
|
+
Summary: Command-line interface for the HealthCloud MCP gateway, generated from the shared MCP tool manifest.
|
|
5
|
+
Project-URL: Issues, https://github.com/healthcloudservices/healthcloud-services/issues
|
|
6
|
+
Project-URL: Repository, https://github.com/healthcloudservices/healthcloud-services
|
|
7
|
+
Author: Healthcheck Systems Inc
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: cli,health-cloud,healthcare,healthcloud,mcp
|
|
10
|
+
Requires-Python: >=3.14
|
|
11
|
+
Requires-Dist: click>=8.1
|
|
12
|
+
Requires-Dist: healthcloud-sdk>=0.9.0
|
|
13
|
+
Requires-Dist: healthcloud-tenantadmin>=1.1.1
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: pytest>=9.0.3; extra == 'dev'
|
|
16
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# healthcloud-cli
|
|
20
|
+
|
|
21
|
+
Requires **Python 3.14 or newer**.
|
|
22
|
+
|
|
23
|
+
`hc` provides the HealthCloud MCP gateway and bounded deployed AMS administration.
|
|
24
|
+
The `hc mcp` subtree has exactly one subcommand per
|
|
25
|
+
MCP tool -- generated dynamically at startup from a shared manifest across
|
|
26
|
+
audiences such as `patient`, `fieldagent`, `ehr`, `vitals`, `diagnostics`,
|
|
27
|
+
`appointments`, `graph`, `person`, `provider`, `tenantadmin`, `connectors`,
|
|
28
|
+
and `telehealth`. Run `hc mcp tools list` to see the exact, current set for
|
|
29
|
+
your installed version. Nothing here is hand-written per tool: the same
|
|
30
|
+
manifest also drives the sibling NPM CLI (`@healthcloud CLI` in
|
|
31
|
+
`packages/cli/npm`), so command names match exactly between the two.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install healthcloud-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This installs the `hc` console script plus its dependency, the
|
|
40
|
+
[`healthcloud-sdk`](../../pip) package, which does the actual HTTP/JSON-RPC
|
|
41
|
+
work against the MCP gateway.
|
|
42
|
+
|
|
43
|
+
## Local development
|
|
44
|
+
|
|
45
|
+
Use uv 0.12.5 and Python 3.14. The package's uv source override installs the
|
|
46
|
+
SDK checkout in editable mode; its committed lock includes the test and build
|
|
47
|
+
tools. Released package consumers can still use pip.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd packages/cli/pip
|
|
51
|
+
uv lock --check
|
|
52
|
+
uv sync --frozen --extra dev
|
|
53
|
+
uv run --frozen --extra dev python -m pytest
|
|
54
|
+
uv run --frozen hc --help
|
|
55
|
+
uv run --frozen hc mcp tools list --audience patient
|
|
56
|
+
uv run --frozen hc mcp patient get-patient --help
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The bundled tool manifest (`healthcloud_cli/contracts/mcp-tools.manifest.json`)
|
|
60
|
+
is a copy of `packages/cli/contracts/mcp-tools.manifest.json`. Re-sync it
|
|
61
|
+
after pulling manifest changes with:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
python scripts/bundle_manifest.py
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This also runs automatically as a hatchling build hook whenever you `python
|
|
68
|
+
-m build`, so a built wheel/sdist is always self-contained and never depends
|
|
69
|
+
on a relative path outside the installed package.
|
|
70
|
+
|
|
71
|
+
## Authentication & configuration
|
|
72
|
+
|
|
73
|
+
Every command accepts these global options (place them before the `mcp`
|
|
74
|
+
subcommand):
|
|
75
|
+
|
|
76
|
+
| Flag | Env var | Meaning |
|
|
77
|
+
|-------------------|--------------------|-----------------------------------------------|
|
|
78
|
+
| `--access-token` | `HC_ACCESS_TOKEN` | Bearer token sent to the MCP gateway |
|
|
79
|
+
| `--base-url` | `HC_MCP_BASE_URL` | Override the MCP gateway base URL |
|
|
80
|
+
| `--profile` | `HC_PROFILE` | Named profile (see below) |
|
|
81
|
+
| `--output` | -- | `pretty` (default) \| `json` \| `raw` |
|
|
82
|
+
| `--raw` | -- | Shortcut for `--output raw` |
|
|
83
|
+
| `--verbose` | -- | Print request diagnostics to stderr |
|
|
84
|
+
|
|
85
|
+
Precedence, highest wins: **explicit CLI flag > environment variable >
|
|
86
|
+
profile file value > built-in default** (`environment` defaults to `"dev"`;
|
|
87
|
+
`accessToken`/`baseUrl` default to unset). The resolved access token is never
|
|
88
|
+
written to logs, generated files, or test snapshots.
|
|
89
|
+
|
|
90
|
+
### Optional profile file
|
|
91
|
+
|
|
92
|
+
`~/.healthcloud/cli/profiles.json`:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"dev-mia": {
|
|
97
|
+
"baseUrl": "https://dev-api-mcp.health.cloud",
|
|
98
|
+
"accessToken": "eyJ...",
|
|
99
|
+
"environment": "dev"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
A missing profiles file is not an error -- profiles are entirely optional. If
|
|
105
|
+
`--profile`/`HC_PROFILE` names a profile and the file (or that entry) is
|
|
106
|
+
missing, `hc` exits with a clear usage error rather than silently ignoring
|
|
107
|
+
it.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# get-patient is self-service — the patient is resolved from the access
|
|
111
|
+
# token, so no --patient-id flag exists.
|
|
112
|
+
hc --profile dev-mia mcp patient get-patient
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Listing and inspecting tools
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Local (bundled manifest, no network call)
|
|
119
|
+
hc mcp tools list
|
|
120
|
+
hc mcp tools list --audience patient
|
|
121
|
+
|
|
122
|
+
# Live gateway (requires --audience)
|
|
123
|
+
hc mcp tools list --audience patient --remote
|
|
124
|
+
|
|
125
|
+
# Full manifest entry for one tool (description, inputSchema, method/path)
|
|
126
|
+
hc mcp tools show patient add_insurance --output json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Calling a tool
|
|
130
|
+
|
|
131
|
+
Every manifest tool is its own subcommand, grouped by audience:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
hc mcp patient get-patient
|
|
135
|
+
hc mcp appointments book-appointment --patient-id patient-123 --slot-id slot-456
|
|
136
|
+
|
|
137
|
+
# Every Diagnostics tool takes an explicit --patient-id — providers and
|
|
138
|
+
# field agents legitimately look up or record diagnostics for a patient
|
|
139
|
+
# other than themselves. When the caller holds a patient token, the backend
|
|
140
|
+
# enforces server-side that --patient-id must be their own (403 otherwise).
|
|
141
|
+
hc mcp diagnostics create-rapid-test --patient-id patient-123 --test-type covid-19 --result negative
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Run `--help` on any generated command to see its real manifest description
|
|
145
|
+
and arguments:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
hc mcp patient get-patient --help
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Argument flags
|
|
152
|
+
|
|
153
|
+
- **Primitive properties** (`string`/`number`/`integer`/`boolean`) become a
|
|
154
|
+
normal flag in kebab-case, e.g. `patient_id` -> `--patient-id`.
|
|
155
|
+
- `enum` values are validated; invalid values are rejected before any
|
|
156
|
+
network call.
|
|
157
|
+
- `minimum`/`maximum`/`exclusiveMinimum`/`exclusiveMaximum` are enforced
|
|
158
|
+
the same way.
|
|
159
|
+
- Boolean properties are a tri-state flag pair: `--flag/--no-flag`.
|
|
160
|
+
Passing neither leaves the value unset (falls back to the manifest
|
|
161
|
+
default or an `--input`/`--stdin` value, if any); passing one sets it
|
|
162
|
+
explicitly to `true`/`false`.
|
|
163
|
+
- **Object/array properties are never flattened.** They get a single
|
|
164
|
+
`--<prop>-json` flag that takes a raw JSON string, e.g.:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# create-medication is self-service — no --patient-id flag; the patient is
|
|
168
|
+
# resolved server-side from the access token.
|
|
169
|
+
hc mcp patient create-medication \
|
|
170
|
+
--name "Metformin" \
|
|
171
|
+
--dosage-json '{"value":10,"unit":"mg","frequency":"once_daily"}'
|
|
172
|
+
```
|
|
173
|
+
- Path parameters (from `{placeholders}` in the tool's HTTP path) are always
|
|
174
|
+
required, in addition to whatever `inputSchema.required` lists.
|
|
175
|
+
|
|
176
|
+
### Bulk input: `--input` / `--stdin`
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
hc mcp appointments book-appointment --input request.json
|
|
180
|
+
cat request.json | hc mcp appointments book-appointment --stdin
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`--input <file>` and `--stdin` both supply a *base* JSON object of
|
|
184
|
+
arguments. `--input` and `--stdin` cannot be combined. Merge precedence
|
|
185
|
+
(highest wins): **manifest defaults < `--input`/`--stdin` object < explicit
|
|
186
|
+
flags** -- i.e. an explicit flag you actually pass always overrides the same
|
|
187
|
+
key coming from a file or stdin, which in turn overrides the schema default.
|
|
188
|
+
|
|
189
|
+
After merging, the final object is validated against the tool's
|
|
190
|
+
`inputSchema` (required fields present, correct types, enum membership,
|
|
191
|
+
numeric bounds). Any validation failure prints a clear message to stderr and
|
|
192
|
+
exits **2**, without making a network call.
|
|
193
|
+
|
|
194
|
+
### `hc mcp call` -- generic escape hatch
|
|
195
|
+
|
|
196
|
+
`hc mcp call` dispatches to any MCP tool by its exact snake_case tool name --
|
|
197
|
+
including one not yet present in the bundled manifest (the tool name itself
|
|
198
|
+
is never validated against the manifest, it's just forwarded):
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# get_patient is self-service and takes no arguments — {} is a complete,
|
|
202
|
+
# valid call.
|
|
203
|
+
hc mcp call patient get_patient --input '{}'
|
|
204
|
+
hc mcp call patient get_patient --input-file request.json
|
|
205
|
+
cat request.json | hc mcp call patient get_patient --stdin
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Note the deliberate inconsistency versus named commands: here `--input` takes
|
|
209
|
+
an inline JSON **value**, not a file path -- use `--input-file` for a file.
|
|
210
|
+
Exactly one of `--input` / `--input-file` / `--stdin` may be given (or none,
|
|
211
|
+
meaning `{}`).
|
|
212
|
+
|
|
213
|
+
## Output modes
|
|
214
|
+
|
|
215
|
+
The MCP tool-call result is `{ content: [{type:"text", text: "..."}],
|
|
216
|
+
is_error: bool }` from the JSON-RPC response's `.result`, or the JSON-RPC
|
|
217
|
+
`.error` object if the gateway returned one.
|
|
218
|
+
|
|
219
|
+
- **`pretty`** (default): if `content[0].text` parses as JSON, pretty-prints
|
|
220
|
+
the parsed value; otherwise prints the raw text. On a JSON-RPC error,
|
|
221
|
+
prints `error.message` (and `error.code` with `--verbose`) to stderr.
|
|
222
|
+
- **`json`**: prints the tool result's parsed JSON (or raw text if
|
|
223
|
+
unparseable) to stdout, with no envelope.
|
|
224
|
+
- **`raw`**: prints the complete JSON-RPC envelope (`id`, `jsonrpc`,
|
|
225
|
+
`result`, `error`) as returned by the gateway.
|
|
226
|
+
|
|
227
|
+
Diagnostics and `--verbose` logs always go to stderr -- stdout stays
|
|
228
|
+
pipeable in every mode.
|
|
229
|
+
|
|
230
|
+
## Exit codes
|
|
231
|
+
|
|
232
|
+
| Code | Meaning |
|
|
233
|
+
|------|-----------------------------------------------------------------------|
|
|
234
|
+
| `0` | Success |
|
|
235
|
+
| `2` | Local input validation failure (bad JSON, missing required field, invalid enum/number, `--input`+`--stdin` both given, unknown option) -- no network call made |
|
|
236
|
+
| `3` | HTTP/network failure talking to the MCP gateway |
|
|
237
|
+
| `4` | JSON-RPC error response (`.error` is not `None`) |
|
|
238
|
+
| `5` | MCP tool result reported `is_error: true` |
|
|
239
|
+
|
|
240
|
+
## Building
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
uv lock --check
|
|
244
|
+
uv run --frozen python -m build --no-isolation
|
|
245
|
+
uv run --frozen python -m zipfile -l dist/*.whl # confirm the bundled manifest is included
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Deployed AMS administration (source checkout)
|
|
249
|
+
|
|
250
|
+
The reviewed AMS administration SDK is not published yet. Use this checkout's
|
|
251
|
+
editable SDK and tenant-admin sources; no released SDK version is claimed to
|
|
252
|
+
contain `ams_admin`. An installed SDK missing that capability is refused before
|
|
253
|
+
login. Ordinary MCP commands keep their existing behavior.
|
|
254
|
+
|
|
255
|
+
Prepare ignored SDK build READMEs from tracked inputs, then install the locked
|
|
256
|
+
editable packages (the CLI README itself is tracked):
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
node tooling/docs-compiler/prepare-package-readmes.mjs
|
|
260
|
+
cd packages/cli/pip
|
|
261
|
+
uv sync --frozen --extra dev
|
|
262
|
+
uv run --frozen hc ams --help
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Bootstrap candidate IDs with the public SDK discovery endpoint. Both flags are
|
|
266
|
+
required; no MCP defaults, admin login, or automatic candidate selection are used:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
uv run --frozen hc ams discover --environment dev --tenant-id TENANT_ID
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Every other command requires an explicit local, non-secret target JSON file.
|
|
273
|
+
Only the canonical HTTPS AMS origin for that environment is accepted; custom
|
|
274
|
+
origins require separately verified support. Target and nested qualification keys
|
|
275
|
+
are strict. Unknown/unavailable qualification may be represented by omitted
|
|
276
|
+
records or empty qualification `{}` for inspection/UI, but blocks planning.
|
|
277
|
+
|
|
278
|
+
The following is a **schema example**, not evidence of deployed CareCo eligibility.
|
|
279
|
+
Replace its assertions only after an operator has established the corresponding
|
|
280
|
+
proof. `deployed_build` and `proof_ref` are references, never credentials:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"schema_version": 1,
|
|
285
|
+
"environment": "dev",
|
|
286
|
+
"tenant_id": "TENANT_ID",
|
|
287
|
+
"agent_id": "EXPLICIT_SELECTED_AGENT_ID",
|
|
288
|
+
"api_origin": "https://dev-amsservices.health.cloud",
|
|
289
|
+
"qualification": {
|
|
290
|
+
"runtime": {"source": "OPERATOR_VERIFIED_RUNTIME", "proof_ref": "RUNTIME_PROOF"},
|
|
291
|
+
"instructions": {"source": "agent.instructions", "proof_ref": "INSTRUCTION_SOURCE_PROOF"},
|
|
292
|
+
"greetings": {"source": "agent.greetings", "proof_ref": "GREETING_SOURCE_PROOF"},
|
|
293
|
+
"backend_model_context": {
|
|
294
|
+
"deployed_build": "OPERATOR_VERIFIED_DEPLOYED_REVISION",
|
|
295
|
+
"config_version": 7,
|
|
296
|
+
"proof_ref": "FULL_INPUT_AND_WRITER_COVERAGE_REVIEW_PROOF",
|
|
297
|
+
"current_build_confirmed": true,
|
|
298
|
+
"fresh_session": true,
|
|
299
|
+
"no_attachments_or_history": true,
|
|
300
|
+
"full_inputs_approved": true,
|
|
301
|
+
"change_path_without_logs": true
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Qualification is an operator assertion with evidence, never authorization.
|
|
308
|
+
Server-side tenant-admin authorization remains mandatory. No current-build API is
|
|
309
|
+
established: the CLI cannot automatically detect an unreported deployment, verify
|
|
310
|
+
actual runtime consumption, attest deployed all-writer coverage, or audit model
|
|
311
|
+
inputs. A changed/unavailable build or agent configuration invalidates the review;
|
|
312
|
+
the operator must refresh the record. The recorded config version must equal the
|
|
313
|
+
inspected version before planning/apply/restore.
|
|
314
|
+
`full_inputs_approved` means an operator approved non-sensitive **full planner and
|
|
315
|
+
reviewer inputs**, including custom_tools, catalogs, all agent fields, and all other
|
|
316
|
+
server context. Output projection does not sanitize server-side model context.
|
|
317
|
+
`change_path_without_logs` requires evidence that the exact deterministic modify
|
|
318
|
+
request uses the change path, avoiding the direct-answer branch's recent logs.
|
|
319
|
+
Unknown effective sources and file-backed/ignored instructions block tuning.
|
|
320
|
+
|
|
321
|
+
Before `plan`, `apply` or selected-field `restore`, the operator must review evidence
|
|
322
|
+
that the actual serving build includes **all writer version coverage**: ordinary
|
|
323
|
+
agent updates and startup/migration repair writers advance `config_version`
|
|
324
|
+
atomically with their changes, and tuning apply uses transactional compare-and-set
|
|
325
|
+
against the expected version. Bind this coverage evidence and the full-input
|
|
326
|
+
review together in the existing `qualification.backend_model_context.proof_ref`
|
|
327
|
+
review bundle for its `deployed_build`, inspected `config_version` and
|
|
328
|
+
`current_build_confirmed` assertion. AMS source prerequisites
|
|
329
|
+
[#488](https://github.com/healthcloudservices/healthcloud-ams-services/pull/488) and
|
|
330
|
+
[#497](https://github.com/healthcloudservices/healthcloud-ams-services/pull/497)
|
|
331
|
+
are evidence leads; source tests, PR merges, or a numeric `config_version` alone
|
|
332
|
+
cannot prove coverage in the serving build. If deployed identity or any writer's
|
|
333
|
+
coverage is unknown, or a writer still bypasses version advancement, stop
|
|
334
|
+
`plan`/`apply`/`restore`; bounded read-only inspection/UI may continue under their
|
|
335
|
+
existing limits. Refresh this evidence after a changed/unknown build or agent
|
|
336
|
+
configuration and recheck it before apply and selected-field restore. This is an
|
|
337
|
+
operator prerequisite: the current CLI does not automatically attest deployment
|
|
338
|
+
or all-writer coverage, and the record adds no server authorization boundary.
|
|
339
|
+
|
|
340
|
+
Credentials enter only through `HC_AMS_ADMIN_EMAIL` and `HC_AMS_ADMIN_PASSWORD`
|
|
341
|
+
in the current process, intended for composition with the existing
|
|
342
|
+
`onepassword-env` wrapper. Each invocation logs in through `HCTenantAdminSDK`;
|
|
343
|
+
tokens remain private in memory. There is no token cache, fallback identity,
|
|
344
|
+
secret argument, resolved env file, or browser credential bridge. Root MCP
|
|
345
|
+
`--access-token`, `--base-url`, their environment equivalents, and token/base-URL
|
|
346
|
+
profiles are refused for AMS. Root profile environment values do not select AMS.
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
uv run --frozen hc ams --target-file TARGET.json inspect
|
|
350
|
+
uv run --frozen hc ams --target-file TARGET.json inspect --out PRIVATE_INSPECTION.json
|
|
351
|
+
uv run --frozen hc ams --target-file TARGET.json plan --changes-file PRIVATE_CHANGES.json --out PRIVATE_RECEIPT.json
|
|
352
|
+
uv run --frozen hc ams --target-file TARGET.json show --receipt PRIVATE_RECEIPT.json --out PRIVATE_DIFF.json
|
|
353
|
+
uv run --frozen hc ams --target-file TARGET.json apply --receipt PRIVATE_RECEIPT.json --confirm-plan-hash DISPLAYED_HASH
|
|
354
|
+
uv run --frozen hc ams --target-file TARGET.json restore --receipt PRIVATE_RECEIPT.json --out PRIVATE_RESTORE_RECEIPT.json
|
|
355
|
+
uv run --frozen hc ams --target-file TARGET.json ui --repo EXISTING_AMS_WORKTREE
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Changes JSON accepts only nonempty subsets of `instructions` (string) and
|
|
359
|
+
`greetings` (language-key to string map). Input changes/receipts must be regular,
|
|
360
|
+
owner-only files (for example create under `umask 077`). Outputs use exclusive
|
|
361
|
+
0600 creation and refuse overwrite/symlinks; failed operations remove unfinished
|
|
362
|
+
outputs. No whole-agent snapshot is saved. Free text appears only in explicitly
|
|
363
|
+
requested private files for human review before any AI use. Default output in
|
|
364
|
+
pretty/json/verbose modes contains bounded metadata and hashes; AMS refuses raw.
|
|
365
|
+
|
|
366
|
+
The planner receives `Update the agent configuration to exactly these field
|
|
367
|
+
values: ` followed by sorted, compact requested JSON. Extra fields, files,
|
|
368
|
+
validation errors, warnings/skipped references, blocking or unknown review
|
|
369
|
+
findings, and approximate wording are refused. Each immutable field change must
|
|
370
|
+
include `before` and exact `after` values so a modified receipt cannot redefine a
|
|
371
|
+
restore. A server plan omitting `before` cannot safely support this workflow;
|
|
372
|
+
review/replan rather than synthesizing server provenance. `show`/`apply` reload the
|
|
373
|
+
immutable backend plan/hash. Before apply, recheck the deployed coverage and
|
|
374
|
+
full-input qualification above. Apply requires the displayed hash, matching
|
|
375
|
+
version and selected before-values, and sends `confirm=True` once. HTTP 401/403
|
|
376
|
+
and 409 never trigger identity fallback or mutation replay.
|
|
377
|
+
|
|
378
|
+
On transport failure, apply records an unknown outcome and reconciles through GET
|
|
379
|
+
plan/agent without retrying the mutation. Confirmed saves require applied status,
|
|
380
|
+
selected-field readback and exactly the next config version. The current public
|
|
381
|
+
response omits publication_status: **saved/readback confirmed is reported separately
|
|
382
|
+
from publication unknown and runtime unverified**, with nonzero exit status for
|
|
383
|
+
complete success. `publish_failed` is reported separately. Do not replay a saved
|
|
384
|
+
apply to resolve publication. A fresh invocation refuses an already consumed plan.
|
|
385
|
+
|
|
386
|
+
Restore creates a new reviewed plan from only the selected fields' authoritative
|
|
387
|
+
before-values against the latest config version. Unrelated edits are preserved;
|
|
388
|
+
a current same-field mismatch blocks restore. There is no force restore. Refresh
|
|
389
|
+
operator qualification, including deployed all-writer coverage and full-input
|
|
390
|
+
evidence, for the latest build/version first, then review the new
|
|
391
|
+
restore receipt with `show` and confirm its new hash with `apply`.
|
|
392
|
+
|
|
393
|
+
UI launch validates the existing `test-client-ui/package.json` Vite script,
|
|
394
|
+
refuses lifecycle hooks, and invokes `npm run dev -- --host 127.0.0.1` by argv
|
|
395
|
+
with `shell=False`. It installs nothing and launches no backend. The allowlisted
|
|
396
|
+
child environment includes toolchain essentials plus only these public target
|
|
397
|
+
variables: `VITE_API_URL`, `VITE_HEALTHCLOUD_ENVIRONMENT`, `VITE_TUNING_TENANT_ID`,
|
|
398
|
+
`VITE_TUNING_AGENT_ID`. Injected HC/OP credentials and other VITE/NODE/NPM options
|
|
399
|
+
are excluded. It prints `/app/agents/{agent_id}`; browser login remains separate.
|
|
400
|
+
The supplied existing worktree and its local frontend configuration remain
|
|
401
|
+
operator-controlled.
|
|
402
|
+
|
|
403
|
+
AMS failures exit nonzero with safe categories, never backend exception bodies.
|
|
404
|
+
In particular, apply may exit nonzero after a confirmed save because publication
|
|
405
|
+
is unknown: inspect the emitted outcome before any next action.
|