Forward region via meta#71
Conversation
c3909e2 to
aa52f01
Compare
| event_hooks={'response': [_handle_error_response]}, | ||
| event_hooks={ | ||
| 'response': [_handle_error_response], | ||
| 'request': [partial(_inject_metadata_hook, metadata or {}, region, service)], |
There was a problem hiding this comment.
per the mcp spec, the _meta field is https://modelcontextprotocol.io/specification/2025-06-18/basic/index#meta
Should we communicate with the teams owning remote MCP that we will use their endpoint as the key in meta? The resulted meta field would look like:
{
"params": {
"_meta": {
"some-mcp-server.us-east-1.amazonaws.com/config": {
"key": "value",
"from": "cli-args"
}
}
}
}There was a problem hiding this comment.
Using their endpoint as a key could be an idea for the future, however, I don't see it adding much value right, especially since there is currently only one metadata field that we set.
There was a problem hiding this comment.
Optionally, our cli program can take an argument --config-key as the key in _meta.
There was a problem hiding this comment.
Yes, the prefix is optional. But then the config key needs to be chosen carefully.
There was a problem hiding this comment.
To my knowledge, the only thing that matters with regard to naming is that these rules are followed and that the user doesn't break them:
Prefix:
If specified, MUST be a series of labels separated by dots (.), followed by a slash (/). Labels MUST start with a letter and end with a letter or digit; interior characters can be letters, digits, or hyphens (-). Any prefix beginning with zero or more valid labels, followed by modelcontextprotocol or mcp, followed by any valid label, is reserved for MCP use. For example: modelcontextprotocol.io/, mcp.dev/, api.modelcontextprotocol.org/, and tools.mcp.com/ are all reserved.Name:
Unless empty, MUST begin and end with an alphanumeric character ([a-z0-9A-Z]). MAY contain hyphens (-), underscores (_), dots (.), and alphanumerics in between.
Perhaps we can add some sort of sanitation? Changing the spec that other people expect at this point might not be optimal
4d50207 to
8158ecf
Compare
…ta_hook to allow for proper resigning of sigv4 to work
8158ecf to
4ffb75d
Compare
| logger.debug('Using region: %s', region) | ||
|
|
||
| # Build metadata dictionary - start with AWS_REGION, then merge user metadata | ||
| metadata = {'AWS_REGION': region} |
There was a problem hiding this comment.
Is there a reason why we are always setting this metadata?
I'm just wondering if we shouldn't set nothing in the default case, and users must specify the param if they want to use this
There was a problem hiding this comment.
From my understanding of the intended workflow, there is no variation wherein an AWS_REGION is not necessary. If this is not the case, I'm happy to make it entirely optional.
There was a problem hiding this comment.
Let's maybe differentiate between "feature-request" and "how other projects will use it". The "feature-request" here is to add the ability to add metadata.
With that in mind, I think let's make it completely optional
d70f559 to
2ad1d4d
Compare
…igv4_helper.py This refactor was needed in order to avoid a circular depdency, which resulted in a mid-module import.
arangatang
left a comment
There was a problem hiding this comment.
I did like the hooks seperation, maybe we can reshuffle again later without the circular dep. For now this looks ok. Thanks for the work @kyoncal!
* feat(sigv4_helper): inject AWS_REGION in _meta * Override the sigv4 signature when adding _meta. * feat(sigv4_helper): add region and service argument to _inject_metadata_hook to allow for proper resigning of sigv4 to work * feat(server.py): add forwarding region as optional argument * feat: replace forwarding region with metadata forwarding * refactor: move the hooks from sigv4_helper.py into a new folder and add tests * refactor(siv4_helper.py): move signing logic from client creation to an event hook * test(test_hooks.py): add assertions * refactor(sigv4_helper.py): remove hooks.py module and move hooks to sigv4_helper.py This refactor was needed in order to avoid a circular depdency, which resulted in a mid-module import. --------- Co-authored-by: Kyon Caldera <kyonc@amazon.com> Co-authored-by: Leonardo Araneda Freccero <araneda@amazon.com>
* feat(sigv4_helper): inject AWS_REGION in _meta * Override the sigv4 signature when adding _meta. * feat(sigv4_helper): add region and service argument to _inject_metadata_hook to allow for proper resigning of sigv4 to work * feat(server.py): add forwarding region as optional argument * feat: replace forwarding region with metadata forwarding * refactor: move the hooks from sigv4_helper.py into a new folder and add tests * refactor(siv4_helper.py): move signing logic from client creation to an event hook * test(test_hooks.py): add assertions * refactor(sigv4_helper.py): remove hooks.py module and move hooks to sigv4_helper.py This refactor was needed in order to avoid a circular depdency, which resulted in a mid-module import. --------- Co-authored-by: Kyon Caldera <kyonc@amazon.com> Co-authored-by: Leonardo Araneda Freccero <araneda@amazon.com>
* pypi release automation through github actions * Forward region via meta (#71) * feat(sigv4_helper): inject AWS_REGION in _meta * Override the sigv4 signature when adding _meta. * feat(sigv4_helper): add region and service argument to _inject_metadata_hook to allow for proper resigning of sigv4 to work * feat(server.py): add forwarding region as optional argument * feat: replace forwarding region with metadata forwarding * refactor: move the hooks from sigv4_helper.py into a new folder and add tests * refactor(siv4_helper.py): move signing logic from client creation to an event hook * test(test_hooks.py): add assertions * refactor(sigv4_helper.py): remove hooks.py module and move hooks to sigv4_helper.py This refactor was needed in order to avoid a circular depdency, which resulted in a mid-module import. --------- Co-authored-by: Kyon Caldera <kyonc@amazon.com> Co-authored-by: Leonardo Araneda Freccero <araneda@amazon.com> * docs: mention creating issues first before sending large PR with new feature (#76) * feat: allow iam mcp client to take a botocore credentials object (#84) * pypi release automation through github actions * chore: pypi publishing added to development.md * chore: simplifying uv install * fix: adding input commit id for integ tests, and passing it in publish workflows. --------- Co-authored-by: Harvish N S <harvishn@amazon.com> Co-authored-by: Kyon <91875365+kyoncal@users.noreply.github.com> Co-authored-by: Kyon Caldera <kyonc@amazon.com> Co-authored-by: Leonardo Araneda Freccero <araneda@amazon.com> Co-authored-by: wzxxing <169175349+wzxxing@users.noreply.github.com> Co-authored-by: Leonardo Araneda Freccero <arangatang@users.noreply.github.com>
Extension of #62
Summary
Implemented automatic AWS_REGION metadata injection into MCP JSON-RPC requests using
httpxrequest hooks. Added_inject_metadata_hookfunction tohooks.pythat injects metadata into the _meta field of request params, merging with existing metadata when present (existing values take precedence). Added optional metadata argument. Includes unit tests and an end-to-end integration test with a new echo_metadata tool in the test MCP server to verify metadata transmission.User experience
AWS_REGION is now automatically injected into all MCP requests transparently - no manual configuration required. The proxy adds region information to the _meta field, making it available to MCP servers without any client-side code changes.
Checklist
If your change doesn't seem to apply, please leave them unchecked.
Is this a breaking change? (Y/N)
Please add details about how this change was tested.
Acknowledgment
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.