Getting Started with PHP MCP SDK โ
Welcome to the PHP MCP SDK! This guide will help you understand what MCP is, why it's useful, and how to get started building with it.
What is MCP? โ
The Model Context Protocol (MCP) is an open protocol that enables seamless integration between Large Language Models (LLMs) and external data sources, tools, and services. Think of it as a standardized way for AI models to interact with the world beyond their training data.
Why Use MCP? โ
๐ Universal Integration โ
- Connect any LLM to any data source or tool
- Standardized protocol means write once, use everywhere
- Growing ecosystem of compatible tools and services
๐ก๏ธ Secure & Controlled โ
- Fine-grained access control
- OAuth 2.0 authentication support
- Input validation and sanitization
โก High Performance โ
- Async-first architecture
- Multiple transport options (STDIO, HTTP, WebSocket)
- Built-in caching and connection pooling
๐๏ธ Production Ready โ
- Comprehensive error handling
- Monitoring and observability
- Docker and cloud deployment support
Key Concepts โ
Before diving into code, let's understand the core MCP concepts:
Architecture Overview โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ LLM โโโโโบโ MCP Client โโโโโบโ MCP Server โ
โ (ChatGPT, โ โ โ โ โ
โ Claude, etc) โ โ โ โ Your PHP App โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ- MCP Server (what you'll build): Provides tools, resources, and capabilities
- MCP Client: Connects servers to LLMs (like Claude Desktop)
- LLM: The AI model that uses your server's capabilities
Core Capabilities โ
MCP servers can provide four types of capabilities:
1. ๐ง Tools โ
Callable functions that perform actions:
- Database queries
- API calls
- File operations
- Calculations
2. ๐ฆ Resources โ
Data sources that can be read:
- Configuration files
- Documentation
- Database records
- API responses
3. ๐ญ Prompts โ
Templates that guide LLM behavior:
- Instructions and context
- Response formatting
- Domain-specific guidelines
4. ๐ฏ Sampling โ
Request LLM completions from within your server:
- Content generation
- Analysis and summarization
- Translation
Your First MCP Server โ
Let's create a simple "Hello World" server to see MCP in action:
Installation โ
composer require dalehurley/php-mcp-sdkCreate the Server โ
Create hello-server.php:
#!/usr/bin/env php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MCP\Server\McpServer;
use MCP\Server\Transport\StdioServerTransport;
use MCP\Types\Implementation;
use function Amp\async;
// Create server with basic info
$server = new McpServer(
new Implementation(
'hello-world-server',
'1.0.0',
'A simple greeting server'
)
);
// Add a tool that says hello
$server->tool(
'say_hello',
'Says hello to someone',
[
'type' => 'object',
'properties' => [
'name' => [
'type' => 'string',
'description' => 'Name of the person to greet'
]
],
'required' => ['name']
],
function (array $args): array {
$name = $args['name'] ?? 'World';
return [
'content' => [
[
'type' => 'text',
'text' => "Hello, {$name}! ๐ Welcome to MCP!"
]
]
];
}
);
// Start the server
async(function () use ($server) {
echo "๐ Hello World MCP Server starting...\n";
$transport = new StdioServerTransport();
$server->connect($transport)->await();
})->await();Make it Executable โ
chmod +x hello-server.phpTest with MCP Inspector โ
The MCP Inspector is a great tool for testing servers:
# Install MCP Inspector (requires Node.js)
npm install -g @modelcontextprotocol/inspector
# Test your server
mcp-inspector ./hello-server.phpThis opens a web interface where you can:
- View available tools and resources
- Test tool calls with different parameters
- Inspect JSON-RPC messages
- Debug issues
Test with Claude Desktop โ
Add your server to Claude Desktop's configuration:
{
"mcpServers": {
"hello-world": {
"command": "php",
"args": ["/path/to/your/hello-server.php"]
}
}
}Now you can ask Claude to use your greeting tool!
Understanding the Code โ
Let's break down what's happening:
1. Server Creation โ
$server = new McpServer(
new Implementation('hello-world-server', '1.0.0', 'Description')
);Creates a new MCP server with identifying information.
2. Tool Registration โ
$server->tool($name, $description, $schema, $handler);- Name: Unique identifier for the tool
- Description: Human-readable description
- Schema: JSON Schema defining expected parameters
- Handler: Function that processes tool calls
3. Transport Setup โ
$transport = new StdioServerTransport();
$server->connect($transport)->await();Sets up communication via STDIO (standard input/output).
4. Async Execution โ
async(function () use ($server) {
// Server logic here
})->await();Uses ReactPHP's async system for non-blocking operations.
Real-World Example โ
Let's build something more practical - a weather server:
#!/usr/bin/env php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MCP\Server\McpServer;
use MCP\Server\Transport\StdioServerTransport;
use MCP\Types\Implementation;
use function Amp\async;
$server = new McpServer(
new Implementation('weather-server', '1.0.0')
);
// Weather tool with input validation
$server->tool(
'get_weather',
'Get current weather for a location',
[
'type' => 'object',
'properties' => [
'location' => [
'type' => 'string',
'description' => 'City name or coordinates'
],
'units' => [
'type' => 'string',
'enum' => ['celsius', 'fahrenheit'],
'default' => 'celsius'
]
],
'required' => ['location']
],
function (array $args): array {
$location = $args['location'];
$units = $args['units'] ?? 'celsius';
// Simulate API call (replace with real weather API)
$weather = [
'location' => $location,
'temperature' => rand(15, 30),
'condition' => ['sunny', 'cloudy', 'rainy'][rand(0, 2)],
'humidity' => rand(40, 80) . '%',
'units' => $units
];
if ($units === 'fahrenheit') {
$weather['temperature'] = round($weather['temperature'] * 9/5 + 32);
}
return [
'content' => [
[
'type' => 'text',
'text' => "Weather in {$location}:\n" .
"Temperature: {$weather['temperature']}ยฐ" .
($units === 'celsius' ? 'C' : 'F') . "\n" .
"Condition: {$weather['condition']}\n" .
"Humidity: {$weather['humidity']}"
]
]
];
}
);
// Weather resource for current conditions
$server->resource(
'weather://current/{location}',
'Current weather conditions',
'application/json',
function (string $uri): array {
preg_match('/weather:\/\/current\/(.+)/', $uri, $matches);
$location = urldecode($matches[1] ?? 'Unknown');
$weather = [
'location' => $location,
'temperature' => rand(15, 30),
'condition' => ['sunny', 'cloudy', 'rainy'][rand(0, 2)],
'timestamp' => date('c')
];
return [
'contents' => [
[
'uri' => $uri,
'mimeType' => 'application/json',
'text' => json_encode($weather, JSON_PRETTY_PRINT)
]
]
];
}
);
async(function () use ($server) {
echo "๐ค๏ธ Weather MCP Server starting...\n";
$transport = new StdioServerTransport();
$server->connect($transport)->await();
})->await();This server provides:
- A tool for getting weather data with parameters
- A resource for accessing weather data via URI
- Input validation and error handling
- Realistic data structure
What's Next? โ
Now that you've created your first MCP server, here are the next steps:
๐ Learn More โ
- Installation Guide - Detailed setup instructions
- Quick Start - Build a complete client-server example
- Core Concepts - Deep dive into MCP architecture
๐ ๏ธ Build Advanced Features โ
- Creating Servers - Production-ready servers
- Authentication - Secure your servers
- Transport Options - HTTP, WebSocket, and more
๐๏ธ Framework Integration โ
- Laravel Integration - Use MCP in Laravel apps
- Symfony Integration - Symfony-specific patterns
๐ค Agentic AI โ
- Building AI Agents - Create intelligent AI systems
- Multi-Agent Systems - Coordinate multiple agents
๐ฏ Examples โ
- Hello World Examples - Simple starting points
- Real-World Applications - Complete applications
- Enterprise Examples - Production deployments
Getting Help โ
- ๐ Full Documentation
- ๐ Report Issues
- ๐ฌ Community Discussions
- ๐ง Contact Support
Welcome to the world of MCP! Let's build something amazing together. ๐