Skip to content

Conversation

@pushpak1300
Copy link
Member

@pushpak1300 pushpak1300 commented Nov 13, 2025

Resolves #107

This PR adds full support for the _meta field as specified in the MCP specification. Users can now attach metadata at three different levels: on tools/resources/prompts (in listings), on the result envelope (for execution metadata), and on individual content items.

Why This Is Needed

The _meta field is part of the official MCP specification, but Laravel MCP didn't support it. This is a problem because:

  • MCP UI and OpenAI Apps SDK require metadata to function properly
  • Developers need to pass component templates and configuration data (see OpenAI's documentation)
  • Without _meta support, Laravel MCP couldn't be used with these important tools

What This PR Adds

Three Levels of Metadata Support

  1. Tool/Resource/Prompt Level (Listing Metadata)

Metadata that describes the tool, resource, or prompt itself. This appears in tools/list, resources/list, and prompts/list responses.

  1. Result Level (Envelope Metadata)

Metadata about the execution or result. This appears at the top level of the response, alongside content and isError.

  1. Content Level (Item Metadata)

Metadata specific to individual content items. This appears in each content object's _meta field.

How to Use It

Basic Content Metadata

Add metadata to individual response content:

public function handle(Request $request): Response
{
    // Simple key-value metadata
    return Response::text('The content generated by the tool.')
        ->withMeta('x', 'y');
}

Result-Level Metadata

Add metadata about the entire result using ResponseFactory:

public function handle(Request $request): ResponseFactory
{
    // Single response with result metadata
    return Response::make(
        Response::text('The content generated by the tool.')
    )->withMeta(['x' => 'y']);
}

Multiple Responses with Result Metadata

Return multiple content items with shared result metadata:

public function handle(Request $request): ResponseFactory
{
    return Response::make([
        Response::text('The content generated by the tool.'),
        Response::text('The content generated by the tool2.')->withMeta(['x' => 'y'])
    ])->withMeta(['x' => 'y']);
}

Streaming Responses with Metadata

Use generators to stream content with metadata:

public function handle(Request $request): Generator
{
    yield Response::notification('processing/progress', [
        'current' => 400
    ])->withMeta(['x' => 'y']);

    yield Response::text('The content generated by the tool.3')
        ->withMeta('x', 'y');

    yield Response::text('The content generated by the tool.4')
        ->withMeta('x', 'y');
}

Array of Responses with Individual Metadata

Return an array where each response has its own metadata:

public function handle(Request $request): array
{
    return [
        Response::text('The content generated by the tool.'),
        Response::text('The content generated by the tool.')
            ->withMeta('x', 'y')
            ->asAssistant(),
        Response::text('The content generated by the tool.')
            ->withMeta('x', 'z'),
    ];
}

Tool/Resource/Prompt Metadata (In Listings)

Define metadata directly on the class for it to appear in list responses:

class MyTool extends Tool
{
    protected string $description = 'My tool description';

    protected ?array $meta = [
        'version' => '2.0',
        'author' => 'John Doe',
        'capabilities' => ['streaming', 'async'],
    ];

    public function handle(Request $request): Response
    {
        // Tool implementation...
    }
}

This metadata will appear when clients call tools/list.

Backward Compatibility

This change is fully backward compatible. Existing tools that return Response objects directly will continue to work. We automatically wraps them in a ResponseFactory internally.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Support for _meta

3 participants