Python: Updating MCP endpoint parameters to use snake case#3543
Python: Updating MCP endpoint parameters to use snake case#3543gavin-aguiar wants to merge 1 commit intomainfrom
Conversation
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
Updates the Azure Functions MCP tool trigger to use snake_case for the thread identifier parameter, aligning MCP parameter naming with other endpoints and addressing #3031.
Changes:
- Renamed MCP tool parameter from
threadIdtothread_idin the MCP tool properties schema. - Updated MCP invocation handling to read
thread_idfrom the MCP context arguments. - Updated unit tests to send
thread_idin MCP invocation contexts.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| python/packages/azurefunctions/agent_framework_azurefunctions/_app.py | Changes MCP tool schema + argument parsing to use thread_id instead of threadId. |
| python/packages/azurefunctions/tests/test_app.py | Updates MCP tool invocation tests to pass thread_id. |
| # Extract optional thread_id | ||
| thread_id = arguments.get("thread_id") |
There was a problem hiding this comment.
Switching the MCP argument name from threadId to thread_id means existing MCP clients still sending threadId will silently lose conversation continuity (a breaking API behavior change). Consider accepting both keys during a transition period (e.g., read thread_id and fall back to threadId, optionally with a deprecation warning), or explicitly mark/document this as a breaking change for consumers.
| # Extract optional thread_id | |
| thread_id = arguments.get("thread_id") | |
| # Extract optional thread_id (prefer snake_case, but support legacy camelCase 'threadId') | |
| thread_id = arguments.get("thread_id") | |
| if thread_id is None: | |
| legacy_thread_id = arguments.get("threadId") | |
| if legacy_thread_id is not None: | |
| logger.warning( | |
| "MCP argument 'threadId' is deprecated; please use 'thread_id' instead." | |
| ) | |
| thread_id = legacy_thread_id |
sphenry
left a comment
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 92%
✓ Correctness
This PR consistently renames the MCP tool property from camelCase
threadIdto snake_casethread_idacross the property definition, argument extraction, comments/docstrings, and all relevant tests. The change is complete within the affected scope — all 4 occurrences in the source file and all 4 test references are updated in lockstep. No correctness bugs are introduced.
✓ Security Reliability
This PR renames the MCP tool property from
threadId(camelCase) tothread_id(snake_case), aligning it with the HTTP endpoint convention already used elsewhere in the codebase (e.g., line 718). The change is purely a rename across the tool property schema definition, the argument extraction in_handle_mcp_tool_invocation, and all corresponding tests. No security or reliability issues are introduced: input validation logic, JSON parsing, error handling, and session ID creation remain unchanged. The rename is consistent and complete across all modified files.
✓ Test Coverage
This PR renames the MCP tool property from
threadId(camelCase) tothread_id(snake_case) in the property definition, docstring, and argument extraction, with corresponding test updates. All four existing tests that passthreadIdin the MCP context payload are correctly updated to usethread_id. However, the testtest_setup_mcp_tool_trigger_registers_decoratorsusesANYfortool_properties, so it does not actually verify the property name rename in the MCP tool definition. Additionally, there is no backward-compatibility test verifying behavior when a client sends the oldthreadIdkey (which would silently fall back to generating a new session ID).
✗ Design Approach
The diff renames the MCP tool property from
threadId(camelCase) tothread_id(snake_case) in three places: the externaltool_propertiesdefinition, the internalarguments.get()lookup, and the tests. The internal Python variable namethread_idis fine and consistent with the rest of the codebase, but the change also renames the externally-advertisedpropertyNamein the MCP tool schema from"threadId"to"thread_id". This conflates internal Python naming conventions with the external MCP interface contract. ThepropertyNamefield intool_propertiesis what gets sent to Azure Functions MCP trigger and ultimately what MCP clients must pass as argument names — it is a public API. Changing it is a breaking change for any existing MCP client already sendingthreadId, and it deviates from JSON/MCP's conventional camelCase naming. The internalarguments.get()key must match whateverpropertyNamethe schema declares, so these two must always stay in sync; changing both together without acknowledging the external breakage is the root design problem.
Automated review by sphenry's agents
| @@ -536,7 +536,7 @@ def _setup_mcp_tool_trigger(self, agent_name: str, agent_description: str | None | |||
| "isArray": False, | |||
There was a problem hiding this comment.
propertyName is the external MCP tool schema field that MCP clients must pass as an argument key. Changing it from "threadId" to "thread_id" breaks existing callers and diverges from JSON/MCP camelCase conventions. Keep this as "threadId" and update arguments.get() to match (arguments.get("threadId")). The Python local variable can remain thread_id regardless.
| "isArray": False, | |
| "propertyName": "threadId", |
Motivation and Context
Fixes: #3031
Description
Contribution Checklist