Skip to content

fix: Make context logging functions spec-compliant - Fixes #397#1907

Open
akshaykumarbedre wants to merge 7 commits intomodelcontextprotocol:mainfrom
akshaykumarbedre:fix/issue-397-context-logging-spec-compliance
Open

fix: Make context logging functions spec-compliant - Fixes #397#1907
akshaykumarbedre wants to merge 7 commits intomodelcontextprotocol:mainfrom
akshaykumarbedre:fix/issue-397-context-logging-spec-compliance

Conversation

@akshaykumarbedre
Copy link

Fixes #397 - FastMCP Context logging methods now accept Any type instead of restricting to str, aligning with MCP specification requirements.

Motivation and Context

The MCP specification requires logging functions to accept any JSON-serializable data (Any type), but FastMCP's Context.log() only accepted strings. This prevented users from logging structured data like dictionaries, lists, numbers, and booleans.

How Has This Been Tested?

  • Added comprehensive test test_context_logging_with_structured_data covering all JSON types (dict, list, number, boolean, string)
  • All existing 84 tests pass
  • Verified backward compatibility with string messages
  • Tested with mock assertions to confirm correct data types passed to underlying session

Breaking Changes

Yes - Removed the extra parameter from all logging methods:

  • Before: ctx.info("message", extra={"key": "value"})
  • After: ctx.info({"message": "message", "key": "value"})

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

Changed Context.log() signature from message: str, extra: dict to data: Any. The extra parameter was not part of the MCP spec and created confusion. Updated all convenience methods (debug(), info(), warning(), error()) for consistency.

@maxisbey maxisbey added bug Something isn't working improves spec compliance When a change improves ability of SDK users to comply with spec definition breaking change Will break existing deployments when updated without changes labels Feb 10, 2026
Copilot AI review requested due to automatic review settings March 22, 2026 05:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make context logging spec-compliant by allowing structured (JSON-serializable) log payloads (issue #397) and updates tests to validate logging of non-string values.

Changes:

  • Adds a new test covering structured log data types (dict, list, number, boolean, string).
  • Updates the client logging-callback test to pass structured fields via data= instead of extra=.
  • Adds a new Context.log(..., data: Any) + convenience logging methods in mcpserver/server.py.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
tests/server/mcpserver/test_server.py Adds a structured-data logging test intended to validate spec compliance.
tests/client/test_logging_callback.py Updates one logging call to use the new data= shape rather than extra=.
src/mcp/server/mcpserver/server.py Introduces new Context/logging implementation and a StreamableHTTPASGIApp class definition.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@akshaykumarbedre
Copy link
Author

@copilot open a new pull request to apply changes based on the comments in this thread

@akshaykumarbedre akshaykumarbedre force-pushed the fix/issue-397-context-logging-spec-compliance branch from 36b4521 to ff86c75 Compare March 22, 2026 06:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 189 to 193
level: Literal["debug", "info", "warning", "error"],
message: str,
message: Any,
*,
logger_name: str | None = None,
extra: dict[str, Any] | None = None,
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

PR description says the extra parameter was removed from all logging methods (and marks this as a breaking change), but Context.log() and the convenience methods still accept extra. Either remove extra to match the stated API change or update the PR description/breaking-change note to reflect the actual behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +1077 to +1085
async def structured_logging_tool(msg: str, ctx: Context) -> str:
# Test with dictionary
await ctx.info({"status": "success", "message": msg, "count": 42})
# Test with list
await ctx.debug([1, 2, 3, "item"])
# Test with number
await ctx.warning(404)
# Test with boolean
await ctx.error(True)
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

This test covers object/array/number/bool/string, but not JSON null (None). Since the PR description claims coverage of “all JSON types” and the spec allows any JSON-serializable type, add a None case and assert it is passed through to send_log_message unchanged.

Copilot uses AI. Check for mistakes.
Comment on lines +1072 to +1073
@pytest.mark.anyio
async def test_context_logging_with_structured_data(self):
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

This module is already marked with pytestmark = pytest.mark.anyio, so this decorator is redundant here. Consider removing it for consistency with the surrounding async tests in this file.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Will break existing deployments when updated without changes bug Something isn't working improves spec compliance When a change improves ability of SDK users to comply with spec definition

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context logging function types are not spec compliant

3 participants