@rupeshstha merged PR #200 into laravel/mcp, adding the resource_link content type from the MCP specification (2025-06-18). This closes issue #199 and completes support for all first-class content types defined in the spec.
An embedded resource inlines content directly into the tool response. A resource_link does not. It returns a URI pointer that the client fetches or subscribes to on its own, independent of resources/list. That makes it the right choice for large payloads, generated artifacts, and live subscriptions where embedding the full content would be impractical.
Per the spec, the URI does not need to point at a registered Resource. Clients may fetch or subscribe freely.
Response::resourceLink() is the entry point. It accepts four distinct input shapes for its first argument.
Plain URI string. The name field is required here to satisfy the MCP schema.
1Response::resourceLink( 2 uri: 'file:///data/report.json', 3 name: 'monthly-report', 4 mimeType: 'application/json', 5 title: 'Monthly Sales Report', 6 description: 'Generated sales report', 7 size: 2048, 8 annotations: [ 9 'audience' => ['user'],10 'priority' => 0.9,11 'lastModified' => '2026-05-07T12:00:00Z',12 ],13);
Resource class name. Metadata is inherited automatically from the declared Resource: uri, name, title, description, mimeType, and any existing resource annotations.
1Response::resourceLink(WeatherForecastResource::class);
Resource instance. Same inheritance behaviour as the class name form.
1Response::resourceLink(new WeatherForecastResource);
Pre-built ResourceLink object.
1$link = new ResourceLink( 2 uri: 'file:///x.pdf', 3 name: 'report.pdf', 4 mimeType: 'application/pdf', 5 annotations: [ 6 'audience' => ['user'], 7 'priority' => 0.9, 8 ], 9);10 11Response::resourceLink($link);
When passing a Resource class or instance, any named argument overrides the inherited value. This composes cleanly for cases where one resource feeds multiple tool responses with different presentation metadata.
1Response::resourceLink(2 WeatherForecastResource::class,3 title: 'Custom Title',4 annotations: [5 'priority' => 1.0,6 ],7);
The implementation covers every field defined for resource_link in the spec: uri, name, title, description, mimeType, size, annotations (audience, priority, lastModified), and _meta. Null fields are omitted from the serialized payload.
The wire output for the plain URI example above looks like this:
1{ 2 "type": "resource_link", 3 "uri": "file:///data/report.json", 4 "name": "monthly-report", 5 "title": "Monthly Sales Report", 6 "description": "Generated sales report", 7 "mimeType": "application/json", 8 "size": 2048, 9 "annotations": {10 "audience": ["user"],11 "priority": 0.9,12 "lastModified": "2026-05-07T12:00:00Z"13 }14}
Any tool that returns references to large files, generated reports, or subscribable data streams should migrate those responses to Response::resourceLink() rather than embedding content inline.
If you enjoyed this article, please consider supporting our work for as low as $5 / month.
Sponsor
Written by
Writing and maintaining @LaravelMagazine. Host of "The Laravel Magazine Podcast". Pronouns: vi/vim.