WaaSuP (Website as a Server using PHP) - A production-ready, SaaS-oriented Model Context Protocol (MCP) server implementation for PHP. Built with enterprise-grade features including OAuth 2.1 authentication, real-time Server-Sent Events (SSE), and comprehensive tool management.
Want to see WaaSuP in action? Connect to our live demo MCP server with your favorite LLM or agentic tool!
Get instant help with:
- β Installation guidance - Step-by-step setup for your environment
- βοΈ Configuration assistance - Database setup, OAuth, framework integration
- π οΈ Custom tool development - Build tools specific to your use case
- π Troubleshooting - Debug issues with access to the full codebase
- π Code exploration - Understand how features work under the hood
The MCP server has access to our entire repository, documentation, and examples. Ask it anything!
https://seolinkmap.com/mcp-repo
This public MCP endpoint showcases the server's capabilities with a complete Website-as-a-Server implementation (authless).
New to MCP servers? Learn how to connect: How to Connect to MCP Servers
Once connected, you can explore our entire repository through chat and get real-time help with WaaSuP installation and configuration.
Built by SEOLinkMap - This is our production "web server for chat and agentics" powering AI access to our entire SEO intelligence platform.
- π OAuth 2.1 Authentication - Complete OAuth flow with RFC 8707 Resource Indicators support for MCP 2025-06-18
- β‘ Multi-Transport Support - Server-Sent Events (SSE) and Streamable HTTP for real-time message delivery
- π οΈ Flexible Tool System - Easy tool registration with both class-based and callable approaches
- π’ Multi-tenant Architecture - Agency/user context isolation for SaaS applications
- π Production Ready - Comprehensive logging, error handling, and session management
- π Framework Agnostic - PSR-compliant with Slim Framework and Laravel integration included
- πΎ Database & Memory Storage - Multiple storage backends for different deployment scenarios
- π CORS Support - Full cross-origin resource sharing configuration
- π΅ Audio Content Support - Handle audio content in tools and prompts (MCP 2025-03-26+)
- π Structured User Input - Elicitation support for collecting structured data (MCP 2025-06-18)
- π Progress Notifications - Real-time progress updates with version-aware messaging
- π·οΈ Tool Annotations - Rich tool metadata for better LLM understanding (MCP 2025-03-26+)
- π¦ JSON-RPC Batching - Efficient batch request processing (MCP 2025-03-26)
- PHP 8.1 or higher
- Composer
- Database (MySQL/PostgreSQL recommended for production)
WaaSuP implements the complete MCP specification across multiple protocol versions with automatic feature gating:
| Feature | 2024-11-05 | 2025-03-26 | 2025-06-18 |
|---|---|---|---|
| Tools | β | β | β |
| Prompts | β | β | β |
| Resources | β | β | β |
| Sampling | β | β | β |
| Roots | β | β | β |
| Ping | β | β | β |
| Progress Notifications | β | β | β |
| Tool Annotations | β | β | β |
| Audio Content | β | β | β |
| Completions | β | β | β |
| JSON-RPC Batching | β | β | β |
| OAuth 2.1 | β | β | β |
| Elicitation | β | β | β |
| Structured Outputs | β | β | β |
| Resource Links | β | β | β |
| Resource Indicators (RFC 8707) | β | β | β (Required) |
composer require seolinkmap/waasup
# For PSR-3 logging support
composer require monolog/monolog
# For Slim Framework integration
composer require slim/slim slim/psr7- Import the database schema:
1. Open `examples/database/database-schema.sql`
2. Use either MySQL section OR PostgreSQL section (not both)
3. Customize table names/prefixes as needed
4. Create only the tables you need (if using your own table mapping)- Create your first agency:
INSERT INTO mcp_agencies (uuid, name, active)
VALUES ('550e8400-e29b-41d4-a716-446655440000', 'My Company', 1);- Create an OAuth token:
INSERT INTO mcp_oauth_tokens (
access_token, scope, expires_at, agency_id
) VALUES (
'your-secret-token-here',
'mcp:read mcp:write',
DATE_ADD(NOW(), INTERVAL 1 YEAR),
1
);<?php
require_once __DIR__ . '/vendor/autoload.php';
use Slim\Factory\AppFactory;
use Slim\Psr7\Factory\{ResponseFactory, StreamFactory};
use Seolinkmap\Waasup\Storage\DatabaseStorage;
use Seolinkmap\Waasup\Tools\Registry\ToolRegistry;
use Seolinkmap\Waasup\Prompts\Registry\PromptRegistry;
use Seolinkmap\Waasup\Resources\Registry\ResourceRegistry;
use Seolinkmap\Waasup\Integration\Slim\SlimMCPProvider;
// Database connection
$pdo = new PDO('mysql:host=localhost;dbname=mcp_server', $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
// Initialize components
$storage = new DatabaseStorage($pdo, ['table_prefix' => 'mcp_']);
$toolRegistry = new ToolRegistry();
$promptRegistry = new PromptRegistry();
$resourceRegistry = new ResourceRegistry();
$responseFactory = new ResponseFactory();
$streamFactory = new StreamFactory();
// Configuration
$config = [
'server_info' => [
'name' => 'My MCP Server',
'version' => '0.0.7'
],
'auth' => [
'context_types' => ['agency'],
'base_url' => 'https://your-domain.com'
]
];
// Create MCP provider
$mcpProvider = new SlimMCPProvider(
$storage, $toolRegistry, $promptRegistry, $resourceRegistry,
$responseFactory, $streamFactory, $config
);
// Setup Slim app
$app = AppFactory::create();
$app->addErrorMiddleware(true, true, true);
// OAuth discovery endpoints
$app->get('/.well-known/oauth-authorization-server',
[$mcpProvider, 'handleAuthDiscovery']);
// Main MCP endpoint
$app->map(['GET', 'POST', 'OPTIONS'], '/mcp/{agencyUuid}[/{sessID}]',
[$mcpProvider, 'handleMCP'])
->add($mcpProvider->getAuthMiddleware());
$app->run();$toolRegistry->register('get_weather', function($params, $context) {
$location = $params['location'] ?? 'Unknown';
return [
'location' => $location,
'temperature' => '22Β°C',
'condition' => 'Sunny'
];
}, [
'description' => 'Get weather information for a location',
'inputSchema' => [
'type' => 'object',
'properties' => [
'location' => ['type' => 'string', 'description' => 'Location name']
],
'required' => ['location']
]
]);use Seolinkmap\Waasup\Tools\Built\{PingTool, ServerInfoTool};
$toolRegistry->registerTool(new PingTool());
$toolRegistry->registerTool(new ServerInfoTool($config));// Register a prompt
$promptRegistry->register('greeting', function($arguments, $context) {
$name = $arguments['name'] ?? 'there';
return [
'description' => 'A friendly greeting prompt',
'messages' => [[
'role' => 'user',
'content' => [['type' => 'text', 'text' => "Please greet {$name}."]]
]]
];
});
// Register a resource
$resourceRegistry->register('server://status', function($uri, $context) {
return [
'contents' => [[
'uri' => $uri,
'mimeType' => 'application/json',
'text' => json_encode(['status' => 'healthy', 'timestamp' => date('c')])
]]
];
});Add the service provider to your Laravel application:
// config/app.php
'providers' => [
Seolinkmap\Waasup\Integration\Laravel\LaravelServiceProvider::class,
],Register routes and use the provided controller pattern. See the full Laravel integration example in the /examples directory.
use Seolinkmap\Waasup\MCPSaaSServer;
$server = new MCPSaaSServer($storage, $toolRegistry, $promptRegistry, $resourceRegistry, $config, $logger);
$response = $server->handle($request, $response);$config = [
'supported_versions' => ['2025-06-18', '2025-03-26', '2024-11-05'],
'server_info' => [
'name' => 'Your MCP Server',
'version' => '0.0.7'
],
'auth' => [
'context_types' => ['agency', 'user'],
'validate_scope' => true,
'required_scopes' => ['mcp:read'],
'base_url' => 'https://your-domain.com'
],
'sse' => [
'keepalive_interval' => 1,
'max_connection_time' => 1800,
'switch_interval_after' => 60
]
];Database Storage (Production)
$storage = new DatabaseStorage($pdo, [
'table_prefix' => 'mcp_',
'cleanup_interval' => 3600
]);Memory Storage (Development/Testing)
$storage = new MemoryStorage();
// Add test data
$storage->addContext('550e8400-e29b-41d4-a716-446655440000', 'agency', [
'id' => 1, 'name' => 'Test Agency', 'active' => true
]);WaaSuP implements complete OAuth 2.1 with RFC 8707 Resource Indicators for MCP 2025-06-18:
- Authorization Code Flow with PKCE (required)
- Resource Indicators for token binding to specific MCP endpoints
- Social Authentication via Google, LinkedIn, and GitHub
- Token Validation with audience claims and scope checking
- Discovery Endpoints for client configuration
Social authentication can be configured for each provider:
$config['google'] = [
'client_id' => 'your-google-client-id',
'client_secret' => 'your-google-client-secret',
'redirect_uri' => 'https://your-domain.com/oauth/google/callback'
];use Seolinkmap\Waasup\Content\AudioContentHandler;
// In your tool
return [
'content' => [
['type' => 'text', 'text' => 'Here is the audio file:'],
AudioContentHandler::createFromFile('/path/to/audio.mp3', 'example.mp3')
]
];// Request structured input from user
$requestId = $server->requestElicitation(
$sessionId,
'Please provide your contact information',
[
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
'email' => ['type' => 'string', 'format' => 'email']
]
]
);// Send progress updates during long-running operations
$server->sendProgressNotification($sessionId, 50, 'Processing data...');| Method | Description | Supported Versions |
|---|---|---|
initialize |
Initialize MCP session | All |
ping |
Health check | All |
tools/list |
List available tools | All |
tools/call |
Execute a tool | All |
prompts/list |
List available prompts | All |
prompts/get |
Get a prompt | All |
resources/list |
List available resources | All |
resources/read |
Read a resource | All |
completion/complete |
Get completions for arguments | All |
sampling/createMessage |
Request LLM sampling | All |
roots/list |
List available root directories | All |
elicitation/create |
Request user input | 2025-06-18 |
| Code | Description |
|---|---|
-32000 |
Authentication required |
-32001 |
Session required |
-32600 |
Invalid Request |
-32601 |
Method not found |
-32602 |
Invalid params |
-32603 |
Internal error |
-32700 |
Parse error |
# Run tests
composer test
# Static analysis
composer analyse
# Code formatting
composer format- Token Validation: All requests require valid OAuth tokens with proper audience validation
- Scope Checking: Configurable scope validation for fine-grained access control
- SQL Injection Protection: All database queries use prepared statements
- Session Security: Cryptographically secure session ID generation
- CORS Configuration: Configurable CORS policies for cross-origin requests
- DNS Rebinding Protection: Origin header validation for localhost endpoints
FROM php:8.1-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
COPY . /var/www/html
WORKDIR /var/www/html
RUN composer install --no-dev --optimize-autoloader
EXPOSE 9000
CMD ["php-fpm"]server {
listen 80;
server_name your-mcp-server.com;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# SSE connection timeout
location /mcp/ {
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}We welcome contributions! This server is actively used in production at SEOLinkMap where it powers our SEO intelligence platform.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
composer test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
git clone https://github.com/seolinkmap/waasup.git
cd waasup
composer install
cp .env.example .env
# Configure your .env file
php -S localhost:8000 -t examples/slim-framework/This project is licensed under the MIT License - see the LICENSE file for details.
- Anthropic for the Model Context Protocol specification
- modelcontextprotocol.io for official MCP documentation and schema
- PHP-FIG for the PSR standards
- Slim Framework for the excellent HTTP foundation
- π Live Demo: https://seolinkmap.com/mcp-repo (use WaaSuP server to chat with WaaSuP repository... help, install, tool building)
- π Documentation: GitHub Wiki
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
Built with β€οΈ by SEOLinkMap for the MCP community.