Skip to content

feat(aws-healthomics-mcp-server): support outputUriPrefixMode on StartAHORun and GetAHORun - #4996

Merged
markjschreiber merged 2 commits into
awslabs:mainfrom
ParulGuptaCSE:feat/healthomics-output-uri-prefix-mode
Nov 3, 2026
Merged

markjschreiber merged 2 commits into
awslabs:mainfrom
ParulGuptaCSE:feat/healthomics-output-uri-prefix-mode

Conversation

@ParulGuptaCSE

Copy link
Copy Markdown
Contributor

Summary

Changes

Adds support for the HealthOmics outputUriPrefixMode StartRun option, which lets a run write its outputs directly under the customer's outputUri instead of under a service-created <runId>/out/ prefix.

  • StartAHORun: new optional output_uri_prefix_mode parameter (SERVICE_DEFINED or NONE_WITH_OVERWRITE).
    • Validated against the allowed values; an invalid value returns an error and StartRun is not called.
    • Sent to StartRun only when provided, so the HealthOmics API default applies otherwise and existing calls are unchanged.
    • The parameter description documents both layouts and the overwrite risk: with NONE_WITH_OVERWRITE, a run into a URI that already holds outputs overwrites same-named files without warning.
    • The response includes outputUriPrefixMode (SERVICE_DEFINED when the parameter is omitted).
  • GetAHORun: returns outputUriPrefixMode when the service includes it, so an agent re-running a run can see and carry over the original layout.
  • StartAHORunBatch: description now states that run batches do not support this option and points to StartAHORun instead.
  • Dependencies: boto3 and botocore minimums raised to 1.43.123, the first release whose omics model includes outputUriPrefixMode (StartRunRequest and GetRunResponse). uv.lock updated for those two packages only.
  • Docs: README StartAHORun entry and an Unreleased CHANGELOG entry.

User experience

Before: an agent using the MCP server could only start runs with the default layout:

s3://bucket/prefix/<runId>/out/...
s3://bucket/prefix/<runId>/logs/...

It also could not tell from GetAHORun whether a run had opted into a different layout, so a re-run through the agent silently reverted to the default.

After: an agent can start a run that writes directly under the requested URI:

s3://bucket/prefix/...
s3://bucket/prefix/logs/<runId>/...

GetAHORun reports the mode, so re-runs can preserve it. Omitting the parameter keeps today's behavior.

Testing

  • New unit tests: pass-through for both values, omitted when unset (including an unresolved Field default), invalid values rejected without calling the API, the forwarded request validated against botocore's StartRun input shape, the description naming the overwrite risk, and GetAHORun returning or omitting the field.
  • New SDK smoke test (no network): installed and declared boto3/botocore minimums, StartRun input shape accepts outputUriPrefixMode with an enum matching the server constant, GetRun output shape includes it.
  • uv run --frozen pytest: 3029 passed. One unrelated pre-existing failure, test_content_resolver.py::TestErrorPropagation::test_permission_denied, fails only when the suite runs as root and fails identically on main.
  • pyright: 0 errors. ruff check and ruff format: clean. pre-commit hooks pass.
  • End to end against the HealthOmics service (one AWS account and region, WDL workflow, DYNAMIC storage), calling the tool functions with real boto3:
    • NONE_WITH_OVERWRITE: run completed, outputs directly under the URI, logs under logs/<runId>/, GetAHORun returned the mode.
    • Omitted: StartRun request contained no outputUriPrefixMode, default <runId>/out/ layout, GetAHORun returned SERVICE_DEFINED.
    • Re-run into the same URI with the mode from GetAHORun: same-named files overwritten, both runs' log folders kept.
    • Invalid value: validation error, no run created.
  • Agent prompt checks with an LLM agent connected only to this server: requests for "outputs directly in the bucket, no run ID folder" used NONE_WITH_OVERWRITE; plain requests left the mode unset; a plain "re-run" request read the mode with GetAHORun and asked before reusing the same URI; "don't overwrite" chose a new URI with the default layout; a batch request did not attempt the unsupported option.

Checklist

If your change doesn't seem to apply, please leave them unchecked.

  • I have reviewed the contributing guidelines
  • I have performed a self-review of this change
  • Changes have been tested
  • Changes are documented

Is this a breaking change? (Y/N) N

The new parameter is optional and omitted from the API call unless set. The raised boto3/botocore minimums are needed for the new field.

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.

…tAHORun and GetAHORun

Add an optional output_uri_prefix_mode to start_run, accepting
SERVICE_DEFINED or NONE_WITH_OVERWRITE. It is validated locally against
OUTPUT_URI_PREFIX_MODES and forwarded as outputUriPrefixMode only when
provided, so omitting it keeps the HealthOmics API default
(SERVICE_DEFINED) rather than having the server pick one. The effective
value is echoed in the start_run response, and GetAHORun now returns
outputUriPrefixMode when the service includes it.

The parameter description spells out the overwrite risk: with
NONE_WITH_OVERWRITE outputs land directly under output_uri with no run
ID folder, so a second run into the same URI silently replaces
same-named files. Logs still go under logs/<runId>/.

The value is normalized with isinstance like log_level and tags, so an
unresolved pydantic Field default reaching the function outside the MCP
framework is treated as omitted instead of being rejected or forwarded.

Bump boto3/botocore to >=1.43.123, the first release whose omics model
includes outputUriPrefixMode on StartRun and GetRun (1.43.122 has
neither). uv.lock updated with
`uv lock --upgrade-package boto3 --upgrade-package botocore`, which
changes only those two packages. StartRunBatch is out of scope: the
1.43.123 model has no outputUriPrefixMode on DefaultRunSetting.

The package version is left for the release bot, and the CHANGELOG entry
goes under Unreleased, matching the session-policy change.
@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.79%. Comparing base (4e591a6) to head (4db51e1).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4996      +/-   ##
==========================================
- Coverage   93.79%   93.79%   -0.01%     
==========================================
  Files        1080     1080              
  Lines       94716    94725       +9     
  Branches    15443    15445       +2     
==========================================
+ Hits        88837    88845       +8     
  Misses       3505     3505              
- Partials     2374     2375       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@markjschreiber markjschreiber left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@a-li a-li left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@markjschreiber
markjschreiber added this pull request to the merge queue Nov 3, 2026
Merged via the queue into awslabs:main with commit d12bbf3 Nov 3, 2026
138 checks passed
@github-project-automation github-project-automation Bot moved this from To triage to Done in awslabs/mcp Project Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants