Tinkerwell - The PHP Scratchpad

Building MCP Servers in PHP

Last updated on by

Building MCP Servers in PHP image

The Model Context Protocol (MCP) is an open protocol that standardises how LLM clients and tools exchange structured context and capabilities. The PHP MCP Server SDK is a package that makes it incredibly easy to build your MCP-compliant servers. Created by Kyrian Obikwelu, its core goal is to allow you to expose specific methods of your existing PHP application as MCP Tools, Resources, or Prompts with minimal effort.

Key Features

  • Modern Architecture: Built with PHP 8.1+ features, PSR standards, and modular design principles. The library follows established PHP conventions while incorporating cutting-edge language features.
  • Multiple Transport Options: Supports stdio (perfect for command-line tools), HTTP with Server-Sent Events, and enhanced streamable HTTP with resumability - giving you deployment flexibility from simple scripts to high-scale production environments.
  • Attribute-Based Definition: Use PHP 8 attributes like #[McpTool], #[McpResource], and #[McpPrompt] for zero-configuration element registration. Annotate your methods and let the library handle the rest.
  • Intelligent Schema Generation: Automatic JSON schema generation from method signatures, docblocks, and optional #[Schema] attribute enhancements. Your existing type hints become rich validation schemas.
  • Advanced Session Management: Multiple storage backends, including in-memory, cache-based, and custom implementations, with persistent sessions across reconnections.
  • Dependency Injection Support: Full PSR-11 container support with automatic dependency injection for your handlers, making it easy to integrate with existing applications.
  • Production-Ready Features: Comprehensive error handling, batch request processing, event sourcing, resumable connections, and extensive logging capabilities.

Hands-On Example: Building a simple File System MCP Server

Let's explore how easy it is to create a simple MCP server. We'll develop a file system browser that enables AI assistants to interact with your local files securely and efficiently.

<?php
// src/FileSystemElements.php
 
declare(strict_types=1);
 
namespace App;
 
use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\McpResource;
use PhpMcp\Server\Attributes\Schema;
 
/**
* File System MCP Elements
*
* Simple file operations for educational purposes
*/
class FileSystemElements
{
private string $basePath;
 
public function __construct()
{
// Set base path to current directory for safety
$this->basePath = getcwd();
}
 
/**
* List files in a directory
*/
#[McpTool(name: 'ln_list_files')]
public function listFiles(
#[Schema(description: 'Directory path relative to base', default: '.')]
string $path = '.'
): array {
$fullPath = $this->basePath . DIRECTORY_SEPARATOR . ltrim($path, '/\\');
 
if (!is_dir($fullPath)) {
throw new \InvalidArgumentException("'$path' is not a directory");
}
 
$files = [];
foreach (scandir($fullPath) as $item) {
if ($item === '.' || $item === '..') continue;
 
$itemPath = $fullPath . DIRECTORY_SEPARATOR . $item;
$files[] = [
'name' => $item,
'type' => is_dir($itemPath) ? 'directory' : 'file',
'size' => is_file($itemPath) ? filesize($itemPath) : null
];
}
 
return ['path' => $path, 'items' => $files];
}
 
/**
* Read file contents
*/
#[McpTool(name: 'ln_read_file')]
public function readFile(
#[Schema(description: 'File path to read')]
string $filePath
): string {
$fullPath = $this->basePath . DIRECTORY_SEPARATOR . ltrim($filePath, '/\\');
 
if (!file_exists($fullPath)) {
throw new \InvalidArgumentException("File '$filePath' does not exist");
}
 
if (!is_file($fullPath)) {
throw new \InvalidArgumentException("'$filePath' is not a file");
}
 
$content = file_get_contents($fullPath);
if ($content === false) {
throw new \RuntimeException("Failed to read file '$filePath'");
}
 
return $content;
}
 
/**
* Search for files by name
*/
#[McpTool(name: 'ln_search_files')]
public function searchFiles(
#[Schema(description: 'Search pattern (supports wildcards)')]
string $pattern
): array {
$results = [];
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($this->basePath)
);
 
foreach ($iterator as $file) {
if ($file->isFile() && fnmatch($pattern, $file->getFilename())) {
$relativePath = str_replace($this->basePath . DIRECTORY_SEPARATOR, '', $file->getPathname());
$results[] = [
'path' => $relativePath,
'name' => $file->getFilename(),
'size' => $file->getSize()
];
}
}
 
return [
'pattern' => $pattern,
'results' => $results,
'count' => count($results)
];
}
 
/**
* Get current working directory info
*/
#[McpResource(
uri: 'filesystem://info',
mimeType: 'application/json'
)]
public function getFilesystemInfo(): array {
return [
'base_path' => $this->basePath,
'working_directory' => getcwd(),
'php_version' => PHP_VERSION,
'os' => PHP_OS
];
}
}

The server setup is equally straightforward:

<?php
// server.php
declare(strict_types=1);
 
require_once __DIR__ . '/vendor/autoload.php';
 
use PhpMcp\Server\Server;
use PhpMcp\Server\Transports\StdioServerTransport;
 
try {
// Build the server with attribute discovery
$server = Server::make()
->withServerInfo('Simple File System Server', '1.0.0')
->build();
 
// Discover MCP elements via attributes
$server->discover(
basePath: __DIR__,
scanDirs: ['src']
);
 
// Start listening via stdio transport
$transport = new StdioServerTransport();
$server->listen($transport);
 
} catch (\Throwable $e) {
fwrite(STDERR, "[ERROR] " . $e->getMessage() . "\n");
exit(1);
}

Now with this in place, you can add our MCP Server to your AI Assistant of choice. Let's say we want to add this to the AI Assistant in PHPStorm.

  1. We could go to Settings > Tools > AI Assistant > Model Context Protocol (MCP).
  2. Click "Add" and configure your server:
    • Name: PHP File System Server
    • Command: php
    • Arguments: /absolute/path/to/your/server.php
    • Working directory: Your project root

Now, if we open the AI Chat within PHP Storm, we can begin using our MCP Tools.

For example, we can run /ln_list_files ./data, and our Assistant will now use our MCP tool to list the files in our data directory.

The Model Context Protocol represents a fundamental shift in how we build AI-integrated applications. Instead of creating custom integrations for each AI assistant, we can build once and connect anywhere using the MCP standard.

The PHP-MCP library makes this vision accessible to PHP developers with its modern architecture, comprehensive feature set, and developer-friendly approach. Whether you're building simple file tools or complex business logic integrations, the library provides the foundation you need.

Ready to start building? Install this package via Composer:

composer require php-mcp/server

Visit the PHP-MCP GitHub repository to explore comprehensive documentation, additional examples, and community resources.

In a follow-up article, we will use the Laravel-specific version of the SDK for seamless integration with the framework, configuration management, and Artisan commands.

Yannick Lyn Fatt photo

Staff Writer at Laravel News and Full stack web developer.

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and more

Visit CodeRabbit
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $3200/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Cut PHP Code Review Time & Bugs into Half with CodeRabbit logo

Cut PHP Code Review Time & Bugs into Half with CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and custom review features while remaining free for open-source projects.

Cut PHP Code Review Time & Bugs into Half with CodeRabbit
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
A new beta of Laravel Wayfinder just dropped image

A new beta of Laravel Wayfinder just dropped

Read article
Ben Bjurstrom: Laravel is the best Vibecoding stack for 2026 image

Ben Bjurstrom: Laravel is the best Vibecoding stack for 2026

Read article
Laravel Altitude - Opinionated Claude Code agents and commands for TALL stack development image

Laravel Altitude - Opinionated Claude Code agents and commands for TALL stack development

Read article
JSON:API Resource in Laravel 12.45 image

JSON:API Resource in Laravel 12.45

Read article
Caching With MongoDB for Faster Laravel Apps image

Caching With MongoDB for Faster Laravel Apps

Read article
Laravel 12.44 Adds HTTP Client afterResponse() Callbacks image

Laravel 12.44 Adds HTTP Client afterResponse() Callbacks

Read article