Skip to content

Conversation

@pushpak1300
Copy link
Member

@pushpak1300 pushpak1300 commented Nov 19, 2025

This PR adds support for resource annotations as defined in the MCP Specs.

Usage

Three annotation types are now available for use with Resource classes.

1. Audience.

use Laravel\Mcp\Enums\Role;
use Laravel\Mcp\Server\Annotations\Audience;
use Laravel\Mcp\Server\Resource;

#[Audience(Role::ASSISTANT)]
class SystemLogsResource extends Resource
{
    protected string $description = 'System logs for debugging';

    public function handle(): Response
    {
        return Response::text($this->getSystemLogs());
    }
}

Accepted values: Role::USER, Role::ASSISTANT, or an array of both.

#[Audience([Role::USER, Role::ASSISTANT])]
class DocumentationResource extends Resource { }

2. Priority.

A numerical score between 0.0 and 1.0 indicating resource importance.

use Laravel\Mcp\Server\Annotations\Priority;

#[Priority(1.0)]
class CriticalConfigResource extends Resource
{
    protected string $description = 'Critical application configuration';

    public function handle(): Response
    {
        return Response::text(config('app'));
    }
}

Validation. Throws InvalidArgumentException if value is outside the 0.0 to 1.0 range.

3. LastModified

An ISO 8601 timestamp showing when the resource was last updated.

use Laravel\Mcp\Server\Annotations\LastModified;

#[LastModified('2025-01-12T15:00:58Z')]
class CachedDataResource extends Resource
{
    protected string $description = 'Cached analytics data';

    public function handle(): Response
    {
        return Response::text($this->getCachedData());
    }
}

Accepted formats:

  • 2025-01-12T15:00:58Z
  • 2025-01-12T15:00:58+00:00
  • Any other ISO 8601 compliant format

Validation. Throws InvalidArgumentException if the timestamp format is invalid.

Combining Multiple Annotations

All three annotations can be combined on a single resource.

use Laravel\Mcp\Enums\Role;
use Laravel\Mcp\Server\Annotations\Audience;
use Laravel\Mcp\Server\Annotations\LastModified;
use Laravel\Mcp\Server\Annotations\Priority;

#[Audience(Role::USER)]
#[Priority(0.9)]
#[LastModified('2025-01-12T15:00:58Z')]
class UserDashboardResource extends Resource
{
    protected string $description = 'User-facing dashboard data';

    public function handle(): Response
    {
        return Response::text($this->getDashboardData());
    }
}

How It Works

Annotations are automatically included in resource listings via the resources/list method.

{
  "uri": "file://resources/user-dashboard",
  "name": "UserDashboard",
  "description": "User-facing dashboard data",
  "mimeType": "text/plain",
  "annotations": {
    "audience": ["user"],
    "priority": 0.9,
    "lastModified": "2025-01-12T15:00:58Z"
  }
}

If no annotations are present, the annotations field is omitted entirely from the response.

Important

This implementation throw error if Invalid Annotations are added on the Tool::class or Resource::class

@pushpak1300 pushpak1300 marked this pull request as ready for review November 19, 2025 15:58
@taylorotwell
Copy link
Member

taylorotwell commented Nov 21, 2025

Should this just be an annotations method on the resource that returns an array?

@taylorotwell taylorotwell marked this pull request as draft November 21, 2025 21:14
@pushpak1300
Copy link
Member Author

pushpak1300 commented Nov 22, 2025

@taylorotwell It could be, and it already works since the user can override the annotations method and return an array. But for defining tool annotations we already use attributes, so it would be better if the codebase supported this in a consistent way instead of having two completely different approaches.

@pushpak1300 pushpak1300 marked this pull request as ready for review November 24, 2025 11:28
@taylorotwell taylorotwell merged commit e1acc1f into main Nov 25, 2025
18 checks passed
@taylorotwell taylorotwell deleted the add_annotations_support branch November 25, 2025 22:24
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.

3 participants