Skip to content

Conversation

@aledsage
Copy link
Contributor

This change is required when running this MCP Server container in Amazon Bedrock AgentCore agent runtime. The change adds support for stateless_http=True, including with the environment variable PURPLEMCP_STATELESS_HTTP.

--
Tested by following the instructions at https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-mcp.html

Prior to this change, step 4 on the page above failed (Test with MCP client (remote)): the client hung, not getting back the response from the MCP Server.

After this change, the client correctly received the MCP information such as list of tools etc.

You can see in the AWS example (step 1) that they set this value for their FastMCP server.

--
Note an alternative one-line change that also worked for AgentCore testing was to change server.py as shown below. However, that may risk breaking other modes such as stdio (untested).

-app: fastmcp.FastMCP[None] = fastmcp.FastMCP("PurpleAIMCP")
+app: fastmcp.FastMCP[None] = fastmcp.FastMCP("PurpleAIMCP", host="0.0.0.0", stateless_http=True)

--
The changes here seem more in line with how other configuration options are being handled.

@aledsage aledsage requested a review from tjkuson-s1 as a code owner November 21, 2025 17:03
Copy link
Contributor

@michaelmoore-s1 michaelmoore-s1 left a comment

Choose a reason for hiding this comment

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

Thanks for putting this together! The AWS Bedrock deployment guide is excellent — the IAM policies are thorough, the setup instructions are clear, and the security considerations are well thought out.

I ran through the code and tests and found a few issues to address:

  • There’s a type error in tests/unit/test_cli_helpers.py:83 where the test passes None, but the function signature expects a bool. You’ll need to either update the signature to stateless_http: bool | None or pass False in that test.
  • The docstring for _apply_environment_overrides is missing the new parameter, which Ruff flags as a D417 error.
  • server.py:138 defines a module-level http_app with hardcoded parameters, while the CLI creates its own instance dynamically. If someone runs uvicorn purple_mcp.server:http_app directly, that instance won’t reflect the configured settings.
  • Both JSON policy files are missing trailing newlines (per POSIX standards), and the main README should document the new environment variable alongside the existing ones.
  • All current test assertions check for stateless_http=False — consider adding at least one test that verifies behavior when it’s set to True.

A larger architectural concern is configuration management. This PR introduces PURPLEMCP_STATELESS_HTTP as an environment variable, but there’s no corresponding field in the Settings class in config.py. Per the project’s conventions, configuration values should flow through that Pydantic model to ensure validation and consistency. As it stands, this setting bypasses that mechanism entirely. I recommend adding a stateless_http field to Settings with appropriate defaults and documentation.

Thanks again for the PR — looking forward to reviewing the next iteration once these items are addressed.

Copy link
Contributor

@michaelmoore-s1 michaelmoore-s1 left a comment

Choose a reason for hiding this comment

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

Thanks for the updates. You addressed several points from the previous review. The new stateless_http field in Settings is exactly what we needed, and the docstring updates look good.

Configuration management is now correctly centralized in Settings with validation and sensible defaults. The _apply_environment_overrides function documents the new parameter clearly, and the test_streamable_http_mode_options_and_stateless test confirms the flag is parsed and propagated.

There are a few remaining items to address before merge:

  1. The module-level http_app in server.py:138-142 hardcodes transport="sse". Since the CLI supports both sse and streamable-http, the module-level instance should read the transport from Settings so consumers of the module get the configured transport by default.

  2. The JSON policy files are missing trailing newlines. Please add a newline to the end of bedrock-agentcore-iam-policy.json and bedrock-agentcore-trust-policy.json to comply with POSIX conventions.

  3. The current tests verify parsing and CLI propagation, but there is no test for behavioral differences when stateless_http is True vs False. Add a test that asserts FastMCP is invoked with the expected stateless_http value in each case.

Once these are addressed, this should be ready to merge.

@michaelmoore-s1 michaelmoore-s1 merged commit 8b29d03 into Sentinel-One:main Nov 25, 2025
13 of 14 checks passed
michaelmoore-s1 added a commit that referenced this pull request Nov 25, 2025
## Summary

Fixes issues introduced in PR #12 (stateless_http configuration) and
bumps version to 0.6.0.

### Bug Fixes
- **CI failure fix**: Added `stdio` to `transport_mode` Literal type -
the CLI was setting `PURPLEMCP_TRANSPORT_MODE=stdio` but Settings only
accepted `http`, `streamable-http`, or `sse`
- **Exception handling**: Changed `contextlib.suppress(BaseException)`
to `suppress(Exception)` in `server.py` to avoid catching
`KeyboardInterrupt`, `SystemExit`, etc.
- **Type cleanup**: Removed unnecessary `| None` from `stateless_http`
field type
- **Description fix**: Corrected `transport_mode` field description (was
copy-paste error from `stateless_http`)

### Documentation
- Added `PURPLEMCP_TRANSPORT_MODE` to README environment variables
section
- Updated CHANGELOG for 0.6.0 release

### Version Bump
- 0.5.1 → 0.6.0 (new feature: stateless HTTP mode for AWS Bedrock
AgentCore)

## Test plan

- [x] `uv run ruff format` passes
- [x] `uv run ruff check --fix` passes  
- [x] `uv run mypy` passes
- [x] Unit tests pass locally
- [x] CI server-startup-tests should pass (previously failed due to
`stdio` not in Literal type)
- [x] CI docker-startup-tests should pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants