WaaSuP (使用PHP的网站作为服务器) - 一个面向SaaS的生产就绪型Model Context Protocol (MCP) 服务器实现。内置企业级功能包括OAuth 2.1认证、实时Server-Sent Events (SSE) 和全面的工具管理。
想看看WaaSuP的实际效果吗?连接到我们的在线演示MCP服务器,使用您喜欢的LLM或代理工具!
立即获得帮助:
MCP服务器可以访问我们整个仓库、文档和示例。您可以向它提问!
https://seolinkmap.com/mcp-repo
这个公共MCP端点展示了服务器的能力,实现了完整的“网站作为服务器”(无需身份验证)。
新接触MCP服务器? 学习如何连接:如何连接到MCP服务器
一旦连接,您可以通过聊天探索我们的整个仓库,并获得WaaSuP安装和配置的实时帮助。
由SEOLinkMap构建 - 这是我们生产的“聊天和代理性Web服务器”,为AI提供了对我们整个SEO智能平台的访问。
WaaSuP实现了多个协议版本的完整MCP规范,并自动进行特性门控:
| 特性 | 2024-11-05 | 2025-03-26 | 2025-06-18 |
|---|---|---|---|
| 工具 | ✅ | ✅ | ✅ |
| 提示 | ✅ | ✅ | ✅ |
| 资源 | ✅ | ✅ | ✅ |
| 抽样 | ✅ | ✅ | ✅ |
| 根目录 | ✅ | ✅ | ✅ |
| 心跳 | ✅ | ✅ | ✅ |
| 进度通知 | ✅ | ✅ | ✅ |
| 工具注释 | ❌ | ✅ | ✅ |
| 音频内容 | ❌ | ✅ | ✅ |
| 补全 | ❌ | ✅ | ✅ |
| JSON-RPC批处理 | ❌ | ✅ | ❌ |
| OAuth 2.1 | ❌ | ❌ | ✅ |
| 引发 | ❌ | ❌ | ✅ |
| 结构化输出 | ❌ | ❌ | ✅ |
| 资源链接 | ❌ | ❌ | ✅ |
| 资源指示符(RFC 8707) | ❌ | ❌ | ✅ (必需) |
composer require seolinkmap/waasup
# 用于PSR-3日志支持
composer require monolog/monolog
# 用于Slim框架集成
composer require slim/slim slim/psr7
1. 打开 `examples/database/database-schema.sql`
2. 使用MySQL部分或PostgreSQL部分(不要同时使用两者)
3. 根据需要自定义表名/前缀
4. 只创建您需要的表(如果您有自己的表映射)
INSERT INTO mcp_agencies (uuid, name, active)
VALUES ('550e8400-e29b-41d4-a716-446655440000', '我的公司', 1);
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;
// 数据库连接
$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,
]);
// 初始化组件
$storage = new DatabaseStorage($pdo, ['table_prefix' => 'mcp_']);
$toolRegistry = new ToolRegistry();
$promptRegistry = new PromptRegistry();
$resourceRegistry = new ResourceRegistry();
$responseFactory = new ResponseFactory();
$streamFactory = new StreamFactory();
// 配置
$config = [
'server_info' => [
'name' => '我的MCP服务器',
'version' => '0.0.7'
],
'auth' => [
'context_types' => ['agency'],
'base_url' => 'https://your-domain.com'
]
];
// 创建MCP提供者
$mcpProvider = new SlimMCPProvider(
$storage, $toolRegistry, $promptRegistry, $resourceRegistry,
$responseFactory, $streamFactory, $config
);
// 设置Slim应用
$app = AppFactory::create();
$app->addErrorMiddleware(true, true, true);
// OAuth发现端点
$app->get('/.well-known/oauth-authorization-server',
[$mcpProvider, 'handleAuthDiscovery']);
// 主MCP端点
$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'] ?? '未知';
return [
'location' => $location,
'temperature' => '22°C',
'condition' => '晴朗'
];
}, [
'description' => '获取某个地点的天气信息',
'inputSchema' => [
'type' => 'object',
'properties' => [
'location' => ['type' => 'string', 'description' => '地点名称']
],
'required' => ['location']
]
]);
use Seolinkmap\Waasup\Tools\Built\{PingTool, ServerInfoTool};
$toolRegistry->registerTool(new PingTool());
$toolRegistry->registerTool(new ServerInfoTool($config));
// 注册提示
$promptRegistry->register('greeting', function($arguments, $context) {
$name = $arguments['name'] ?? '那里';
return [
'description' => '友好的问候提示',
'messages' => [[
'role' => 'user',
'content' => [['type' => 'text', 'text' => "请问候{$name}。"]]
]]
];
});
// 注册资源
$resourceRegistry->register('server://status', function($uri, $context) {
return [
'contents' => [[
'uri' => $uri,
'mimeType' => 'application/json',
'text' => json_encode(['status' => '健康', '时间戳' => date('c')])
]]
];
});
在您的Laravel应用中添加服务提供者:
// config/app.php
'providers' => [
Seolinkmap\Waasup\Integration\Laravel\LaravelServiceProvider::class,
],
注册路由并使用提供的控制器模式。请参阅/examples目录中的完整Laravel集成示例。
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' => '您的MCP服务器',
'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
]
];
数据库存储(生产环境)
$storage = new DatabaseStorage($pdo, [
'table_prefix' => 'mcp_',
'cleanup_interval' => 3600
]);
内存存储(开发/测试)
$storage = new MemoryStorage();
// 添加测试数据
$storage->addContext('550e8400-e29b-41d4-a716-446655440000', 'agency', [
'id' => 1, 'name' => '测试机构', 'active' => true
]);
WaaSuP实现了完整的OAuth 2.1,包括RFC 8707资源指示符(适用于MCP 2025-06-18):
社交认证可以针对每个提供商进行配置:
$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;
// 在您的工具中
return [
'content' => [
['type' => 'text', 'text' => '这是音频文件:'],
AudioContentHandler::createFromFile('/path/to/audio.mp3', 'example.mp3')
]
];
// 请求结构化的用户输入
$requestId = $server->requestElicitation(
$sessionId,
'请提供您的联系信息',
[
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
'email' => ['type' => 'string', 'format' => 'email']
]
]
);
// 在长时间运行的操作期间发送进度更新
$server->sendProgressNotification($sessionId, 50, '正在处理数据...');
| 方法 | 描述 | 支持的版本 |
|---|---|---|
initialize | 初始化MCP会话 | 所有 |
ping | 健康检查 | 所有 |
tools/list | 列出可用工具 | 所有 |
tools/call | 执行工具 | 所有 |
prompts/list | 列出可用提示 | 所有 |
prompts/get | 获取提示 | 所有 |
resources/list | 列出可用资源 | 所有 |
resources/read | 读取资源 | 所有 |
completion/complete | 获取参数的补全 | 所有 |
sampling/createMessage | 请求LLM抽样 | 所有 |
roots/list | 列出可用根目录 | 所有 |
elicitation/create | 请求用户输入 | 2025-06-18 |
| 代码 | 描述 |
|---|---|
-32000 | 需要认证 |
-32001 | 需要会话 |
-32600 | 请求无效 |
-32601 | 方法未找到 |
-32602 | 参数无效 |
-32603 | 内部错误 |
-32700 | 解析错误 |
# 运行测试
composer test
# 静态分析
composer analyse
# 代码格式化
composer format
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连接超时
location /mcp/ {
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}
我们欢迎贡献!此服务器在**[SEOLinkMap](https