Skip to content

Implement io.modelcontextprotocol.server.Result class#17

Merged
thekid merged 11 commits intomainfrom
feature/result
Jan 6, 2026
Merged

Implement io.modelcontextprotocol.server.Result class#17
thekid merged 11 commits intomainfrom
feature/result

Conversation

@thekid
Copy link
Copy Markdown
Member

@thekid thekid commented Jan 5, 2026

This PR implements the functionality suggested in #13.

  • Text
  • Images
  • Audio
  • Resource links
  • Embedded resources
  • Structured content
  • Errors

API

public class io.modelcontextprotocol.server.Result {
  public function __construct(array $struct)

  public static function cast(var $value): self
  public static function success(var $value): self
  public static function error(var $value): self
  public static function structured(var $object, ?string|iterable $text, ?bool $isError): self

  public function add(string $type, array $struct, array $annotations): self
  public function text(string $string, [:mixed] $annotations): self
  public function image(string|util.Bytes $data, string $mime, [:mixed] $annotations): self
  public function audio(string|util.Bytes $data, string $mime, [:mixed] $annotations): self
  public function link(string $uri, string $name, string $description, string $mime, [:mixed] $annotations): self
  public function resource(string $uri, string|util.Bytes $text, string $mime, [:mixed] $annotations): self
  public function struct(): array
}

Note: The constructor is left public intentionally should users wish full control over the generated resulting struct.

Example

use io\modelcontextprotocol\server\{Implementation, Tool, Param, Result};

#[Implementation]
class Weather {
  private $backing= [
    '8FXC2C43+QF' => [
      'temperature' => 22.5,
      'conditions'  => 'Partly cloudy',
      'humidity'    => 65,
    ],
  ];

  private function lookup(string $city): ?string {
    // TBI
  }

  #[Tool]
  public function for(#[Param] string $city): Result {
    if ($code= $this->lookup($city)) {
      return Result::success($this->backing[$code]);
    } else {
      return Result::error('Cannot find city '.$city);
    }
  }
}

See also

@thekid thekid added the enhancement New feature or request label Jan 5, 2026
thekid added 9 commits January 5, 2026 22:09
Parameter for the latter order is <content>, <mime>; and was <mime>, <content>
for embedded resources as shown in the specification example. We vote for API
consistency here
The spec says: "SHOULD also return" (not: "MUST"). While the default implementation
will omit this for performance reasons, tools may chose to use the structured($object)
with either no additional parameter (which will produce the JSON) or an alternative
textual representation given either a string or an iterable of strings, which will
add text content parts
@thekid thekid merged commit 327d0d4 into main Jan 6, 2026
16 checks passed
@thekid thekid deleted the feature/result branch January 6, 2026 09:33
@thekid
Copy link
Copy Markdown
Member Author

thekid commented Jan 6, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant