laravel-mcp-fetch maintained by eloquage
Laravel MCP Fetch

MCP fetch server matching the official MCP fetch tool schema. Fetches public URLs with SSRF protection and optional HTML simplification.
Requirements
- PHP 8.4+
- PHP cURL extension (
ext-curl) - Laravel 12 or 13
laravel/mcp^0.9
Installation
composer require eloquage/laravel-mcp-fetch
Publish config (optional):
php artisan vendor:publish --tag=mcp-fetch-config
Run the MCP server
Laravel package discovery registers the MCP server automatically:
- The default local handle is
fetch. SetMCP_FETCH_LOCAL_HANDLEto change it.
Start the local MCP server:
php artisan mcp:start fetch
IDE config (.cursor/mcp.json)
{
"mcpServers": {
"fetch": {
"command": "php",
"args": ["artisan", "mcp:start", "fetch"]
}
}
}
Fetch a URL
The fetch tool accepts a public HTTP or HTTPS URL. For example, a client can call it with:
{
"url": "https://example.com/article",
"max_length": 5000
}
Tool reference: fetch
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string (uri) | yes | — | URL to fetch |
max_length |
integer | no | 5000 | Maximum characters to return (max 1,000,000) |
start_index |
integer | no | 0 | Start output at this character index for pagination |
raw |
boolean | no | false | Return raw HTML without simplification |
Success response
{
"success": true,
"url": "https://example.com/page",
"content": "...",
"truncated": false,
"start_index": 0,
"content_length": 1234,
"total_length": 1234
}
Error response
{
"success": false,
"error": "HTTP 404 fetching https://example.com/missing"
}
SSRF protection
Only globally routable http and https URLs are allowed. Private, shared, reserved, and documentation IP ranges are blocked before any HTTP request is made. Hostname answers are pinned to the validated public IP addresses for the request, redirects are disabled, and proxy settings are bypassed because a proxy resolves destinations outside this validation.
Use the service in Laravel
use Eloquage\LaravelMcpFetch\Services\UrlFetchService;
$result = app(UrlFetchService::class)->fetch('https://example.com', maxLength: 5000);
Configuration
| Key | Env | Default |
|---|---|---|
timeout |
MCP_FETCH_TIMEOUT |
30 |
user_agent |
MCP_FETCH_USER_AGENT |
eloquage/laravel-mcp-fetch |
default_max_length |
— | 5000 |
max_max_length |
— | 1000000 |
Docker
Published to GHCR on tag push.
{
"mcpServers": {
"fetch": {
"command": "docker",
"args": ["run", "-i", "--rm", "ghcr.io/eloquage/laravel-mcp-fetch:latest"]
}
}
}
Local build:
docker build -t mcp-fetch:local --build-arg PACKAGE_VERSION=dev .
docker run --rm -i mcp-fetch:local
Testing
composer test
composer analyse
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
License
The MIT License (MIT). Please see License File for more information.