Skip to content

Conversation

ineersa
Copy link
Contributor

@ineersa ineersa commented Oct 5, 2025

  1. Inside \Mcp\Capability\Tool\ToolCaller::call added ability to return CallToolResult from tool as response.
  2. In \Mcp\Capability\Tool\ToolCaller::call we passing formatted result with array of content items to utilize previously unused \Mcp\Schema\Result\CallToolResult::fromArray
  3. Added \Mcp\Schema\Content\StructuredContent to represent structuredContent response node.
  4. \Mcp\Schema\Result\CallToolResult was modified to work correctly with new content type
  5. Added \Mcp\Schema\Content\TextContent::__construct(isError) to propagate error in case of content item use instead of call result.

Motivation and Context

While testing my MCP server I've noticed inconsistencies between output with Python MCP server.

  1. There was no possibility and no implementation for structuredContent
  2. There was no possibility to return isError=true

Also while outputSchema being added in #88 , with outputSchema MCP server MUST provide structured content alongside text representation.

How Has This Been Tested?

Tested on my MCP server to ensure same response between PHP and Python versions.
Scenarios tested:

$content = new TextContent($result);
$structured = new StructuredContent(
    [
        'result' => $result,
    ]
);

return new CallToolResult([$content], $structured, false);
return new CallToolResult([$content], $structured, true);

return [$content, $structured];

$content = new TextContent(text: $result, isError: true);
return [$content, $structured];

I will add unit tests after structure of changes will be approved

Breaking Changes

Tests passing, as far as I tested and understand there will be no breaking changes as \Mcp\Capability\Registry\ToolReference::formatResult left intact

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

As an additional notes I have few suggestions and explanations.

5. Added `\Mcp\Schema\Content\TextContent::__construct(isError)` to propagate error in case of content item use instead of call result.

Is terrible solution and it shouldn't be there, I just didn't found any possibility to add error without usage of \Mcp\Schema\Result\CallToolResult and I will happily remove it.
I think it will interfere and conflict with #73

As a suggestion, we could just remove \Mcp\Capability\Registry\ToolReference::formatResult.
This method does some heavy processing and can produce unexpected results for user.
It would be more convenient to enforce Tools to return \Mcp\Schema\Result\CallToolResult which has enforcements to use proper Content items.

One more suggestion about JSON serialization, I know that SDK tries to be agnostic and not use packages, but consider using serializer library.
Manual serialization via jsonSerialize works, but you always need to keep in mind to call child serialization and handle nulls to remove them from results. This makes code more prone to errors.

@ineersa ineersa force-pushed the structured-content-return branch from f340e0d to cfbfff8 Compare October 5, 2025 01:26
@chr-hertel chr-hertel added the Server Issues & PRs related to the Server component label Oct 6, 2025
@ineersa ineersa force-pushed the structured-content-return branch from cfbfff8 to 1f4ccdf Compare October 8, 2025 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants