MCP Server for Rhymix
๐ฐ๐ท ํ๊ตญ์ด | ๐บ๐ธ English
English
Overview
MCP Server is a Model Context Protocol (MCP) server module that can be applied to the Rhymix CMS. This module provides a standardized interface for AI clients to access Rhymix's data and functionality.
This module is a program that ports php-mcp/server for use in Rhymix. For MCP tool, prompt, and plugin development, you should refer to the above repository.
[!IMPORTANT]This module requires advanced knowledge of servers and Rhymix during the installation process. When changing server settings, you must be aware of what you are doing and proceed accordingly.
What is Model Context Protocol (MCP)?
MCP is an open standard protocol designed to allow AI assistants to securely connect to external tools and data sources. This allows AI clients to leverage the capabilities of various applications and services.
Key Features
- โจ Standardized MCP Protocol support
- ๐ง Extensible Tool System - Users can develop their own MCP tools
- ๐ Automatic Directory Scanning - Automatically scans for MCP plugins from separate modules
Installation Requirements
- PHP 8.2 or higher
- Rhymix 2.1 or higher
- Linux Shell access required
Installation Method
- Copy the module to the
modules/mcpserver
directory of Rhymix. - Configure settings in Advanced > Installed Modules > MCP Server.
Configuration Options
Server Settings
- Server Name: MCP server identifier
- Server Version: Version information
- Host: IP address the server will bind to (default: 127.0.0.1)
- Port: Port the server will use (default: 8080)
- MCP Path: MCP endpoint path (default: /mcp)
Communication Settings
- Enable SSE: Whether to use Server-Sent Events
- Stateless Mode: Whether to enable stateless mode
Logging Settings
- Log Output: Enable console log output
- Log Level: Select log level to output (DEBUG, INFO, WARNING, ERROR, etc.)
Running MCP Server
This module requires running a server separate from Rhymix. Refer to Module > Configuration Manual to run the script and make necessary reverse proxy configuration changes in server programs like nginx.
Developing Custom MCP Tools
Basic Structure
Custom MCP tools are created in the modules/(any module)/mcp/
directory. All MCP tool classes must inherit from \Rhymix\Modules\Mcpserver\Models\MCPServerInterface
.
Example: Calculator Tool (ExampleCalculatorElements.php)
<?php
namespace Rhymix\Modules\Mcpserver\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\Schema;
/**
* Example MCP tool providing calculator functionality
*/
class ExampleCalculatorElements extends MCPServerInterface
{
/**
* Adds two numbers.
*
* @param int $a First number
* @param int $b Second number
* @return int Sum of two numbers
*/
#[McpTool(name: 'add_numbers')]
public function add(int $a, int $b): int
{
return $a + $b;
}
/**
* Calculates power with validation.
*/
#[McpTool(name: 'calculate_power')]
public function power(
#[Schema(type: 'number', minimum: 0, maximum: 1000)]
float $base,
#[Schema(type: 'integer', minimum: 0, maximum: 10)]
int $exponent
): float {
return pow($base, $exponent);
}
}
Creating New MCP Tool Classes
Create File: Create a new PHP file (YourCustomTool.php) in the
modules/example/mcp/
directory.Basic Class Structure:
<?php
namespace Rhymix\Modules\Example\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\Schema;
/**
* Custom MCP Tool
*/
class YourCustomTool extends MCPServerInterface
{
/**
* Example tool method
*/
#[McpTool(name: 'your_tool_name')]
public function yourMethod($param1, $param2)
{
// Implement business logic here
return "Result";
}
}
Rhymix Database Access Example
<?php
namespace Rhymix\Modules\Example\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
class RhymixDatabaseTool extends MCPServerInterface
{
/**
* Retrieves member information.
*/
#[McpTool(name: 'get_member_info')]
public function getMemberInfo(int $member_srl): array
{
// Execute Rhymix database query
$output = executeQuery('member.getMemberInfoByMemberSrl', ['member_srl' => $member_srl]);
if (!$output->toBool()) {
throw new \Exception('Cannot get member info: ' . $output->getMessage());
}
$member = $output->data;
return [
'member_srl' => $member->member_srl,
'user_id' => $member->user_id,
'nick_name' => $member->nick_name,
'email_address' => $member->email_address
];
}
/**
* Retrieves document list.
*/
#[McpTool(name: 'get_document_list')]
public function getDocumentList(int $module_srl, int $page = 1): array
{
$args = new \stdClass();
$args->module_srl = $module_srl;
$args->page = $page;
$args->list_count = 10;
$output = executeQueryArray('document.getDocumentList', $args);
if (!$output->toBool()) {
throw new \Exception('Cannot get document list: ' . $output->getMessage());
}
return [
'total_count' => $output->total_count,
'documents' => $output->data
];
}
}
Schema Validation
In MCP tools, you can set validation for input parameters using the Schema
attribute:
#[McpTool(name: 'validated_tool')]
public function validatedMethod(
#[Schema(type: 'string', minLength: 1, maxLength: 100)]
string $text,
#[Schema(type: 'integer', minimum: 1, maximum: 999)]
int $number,
#[Schema(type: 'number', minimum: 0.0, maximum: 100.0)]
float $percentage
): array {
return [
'text' => $text,
'number' => $number,
'percentage' => $percentage
];
}
For more information, please refer to php-mcp/server.
Debugging
Log Checking
The MCP server outputs detailed logs according to configuration. Through logs, you can check:
- Client connection/disconnection
- Tool calls and responses
- Error and exception information
Connection Testing
Use the "Local Connection Test" function on the admin page to verify that the MCP server is working properly.
Precautions
- Use MCP server with appropriate firewall settings in security-critical environments.
- It is recommended to disable DEBUG log level in production environments.
- Perform appropriate permission checks when working with databases in custom tools.
License
This module is distributed under the GPL v2 license.
Developer
- Waterticket ([email protected])
- Website: https://potatosoft.kr
- Module Generator: https://www.poesis.dev/
Technical Support
If you encounter problems or need help:
- Ask questions in the Rhymix Official Community
- Register GitHub issues (if applicable)
Korean
๊ฐ์
MCP Server๋ ๋ผ์ด๋ฏน์ค(Rhymix) CMS์ ์ ์ฉํ ์ ์๋ Model Context Protocol (MCP) ์๋ฒ ๋ชจ๋์ ๋๋ค. ์ด ๋ชจ๋์ ํตํด AI ํด๋ผ์ด์ธํธ๊ฐ ๋ผ์ด๋ฏน์ค์ ๋ฐ์ดํฐ์ ๊ธฐ๋ฅ์ ์ ๊ทผํ ์ ์๋ ํ์คํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด ๋ชจ๋์ php-mcp/server๋ฅผ ๋ผ์ด๋ฏน์ค์์ ์ฌ์ฉํ ์ ์๋๋ก ํฌํ ํ ํ๋ก๊ทธ๋จ์ ๋๋ค. MCP ํด, ํ๋กฌํํธ, ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ์ ์ ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์ฐธ๊ณ ํ์ฌ ๊ฐ๋ฐํด์ผํฉ๋๋ค.
[!IMPORTANT]๋ณธ ๋ชจ๋์ ์ค์น๊ณผ์ ์์ ์๋ฒ ๋ฐ ๋ผ์ด๋ฏน์ค์ ๋ํ ๊ณ ๋์ ์ง์์ ์๊ตฌํฉ๋๋ค. ์๋ฒ์ ์ค์ ์ ๋ณ๊ฒฝํ ๋๋ ๋ฐ๋์ ์์ ์ด ๋ฌด์จ ์์ ์ ํ๋์ง ์ธ์งํ๊ณ ์งํํด์ผํฉ๋๋ค.
Model Context Protocol (MCP)๋?
MCP๋ AI ์ด์์คํดํธ๊ฐ ์ธ๋ถ ๋๊ตฌ์ ๋ฐ์ดํฐ ์์ค์ ์์ ํ๊ฒ ์ฐ๊ฒฐํ ์ ์๋๋ก ์ค๊ณ๋ ๊ฐ๋ฐฉํ ํ์ค ํ๋กํ ์ฝ์ ๋๋ค. ์ด๋ฅผ ํตํด AI ํด๋ผ์ด์ธํธ๋ ๋ค์ํ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ์๋น์ค์ ๊ธฐ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค.
์ฃผ์ ๊ธฐ๋ฅ
- โจ ํ์คํ๋ MCP ํ๋กํ ์ฝ ์ง์
- ๐ง ํ์ฅ ๊ฐ๋ฅํ ํด ์์คํ - ์ฌ์ฉ์๊ฐ ์ง์ MCP ํด์ ๊ฐ๋ฐํ ์ ์์
- ๐ ์๋ ๋๋ ํ ๋ฆฌ ์ค์บ - ๋ณ๋์ ๋ชจ๋์์ MCP ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ ์ ์๋๋ก ์๋ ์ค์บ
์ค์น ์๊ตฌ์ฌํญ
- PHP 8.2 ์ด์
- Rhymix 2.1 ์ด์
- Linux Shell ์์ ์ด ๊ฐ๋ฅํด์ผ ํจ
์ค์น ๋ฐฉ๋ฒ
- ๋ชจ๋์ ๋ผ์ด๋ฏน์ค์
modules/mcpserver
๋๋ ํ ๋ฆฌ์ ๋ณต์ฌํฉ๋๋ค. - ๊ณ ๊ธ > ์ค์น๋ ๋ชจ๋ > MCP Server ์์ ์ค์ ์ ๊ตฌ์ฑํฉ๋๋ค.
์ค์ ์ต์
์๋ฒ ์ค์
- ์๋ฒ ์ด๋ฆ: MCP ์๋ฒ์ ์๋ณ๋ช
- ์๋ฒ ๋ฒ์ : ๋ฒ์ ์ ๋ณด
- ํธ์คํธ: ์๋ฒ๊ฐ ๋ฐ์ธ๋ฉ๋ IP ์ฃผ์ (๊ธฐ๋ณธ: 127.0.0.1)
- ํฌํธ: ์๋ฒ๊ฐ ์ฌ์ฉํ ํฌํธ (๊ธฐ๋ณธ: 8080)
- MCP ๊ฒฝ๋ก: MCP ์๋ํฌ์ธํธ ๊ฒฝ๋ก (๊ธฐ๋ณธ: /mcp)
ํต์ ์ค์
- SSE ํ์ฑํ: Server-Sent Events ์ฌ์ฉ ์ฌ๋ถ
- Stateless ๋ชจ๋: ๋ฌด์ํ ๋ชจ๋ ํ์ฑํ ์ฌ๋ถ
๋ก๊น ์ค์
- ๋ก๊ทธ ์ถ๋ ฅ: ์ฝ์ ๋ก๊ทธ ์ถ๋ ฅ ํ์ฑํ
- ๋ก๊ทธ ๋ ๋ฒจ: ์ถ๋ ฅํ ๋ก๊ทธ ๋ ๋ฒจ ์ ํ (DEBUG, INFO, WARNING, ERROR ๋ฑ)
MCP ์๋ฒ ์คํ
๋ณธ ๋ชจ๋์ ๋ผ์ด๋ฏน์ค์ ๋ณ๋๋ก ์๋ฒ๋ฅผ ์คํํด์ผํฉ๋๋ค. ๋ชจ๋ > ์ค์ ๋งค๋ด์ผ์ ์ฐธ๊ณ ํ์ฌ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๊ณ , nginx์ ๊ฐ์ ์๋ฒ ํ๋ก๊ทธ๋จ์ ๋ฆฌ๋ฒ์ค ํ๋ก์ ์ค์ ๋ณ๊ฒฝ์ด ํ์ํฉ๋๋ค.
์ฌ์ฉ์ ์ ์ MCP ํด ๊ฐ๋ฐ
๊ธฐ๋ณธ ๊ตฌ์กฐ
์ฌ์ฉ์ ์ ์ MCP ํด์ modules/(์์์ ๋ชจ๋)/mcp/
๋๋ ํ ๋ฆฌ์ ์์ฑํฉ๋๋ค. ๋ชจ๋ MCP ํด ํด๋์ค๋ \Rhymix\Modules\Mcpserver\Models\MCPServerInterface
๋ฅผ ์์๋ฐ์์ผ ํฉ๋๋ค.
์์ : ๊ณ์ฐ๊ธฐ ํด (ExampleCalculatorElements.php)
<?php
namespace Rhymix\Modules\Mcpserver\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\Schema;
/**
* ๊ณ์ฐ๊ธฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ MCP ํด ์์
*/
class ExampleCalculatorElements extends MCPServerInterface
{
/**
* ๋ ์๋ฅผ ๋ํฉ๋๋ค.
*
* @param int $a ์ฒซ ๋ฒ์งธ ์ซ์
* @param int $b ๋ ๋ฒ์งธ ์ซ์
* @return int ๋ ์ซ์์ ํฉ
*/
#[McpTool(name: 'add_numbers')]
public function add(int $a, int $b): int
{
return $a + $b;
}
/**
* ๊ฑฐ๋ญ์ ๊ณฑ์ ๊ณ์ฐํฉ๋๋ค (์ ํจ์ฑ ๊ฒ์ฌ ํฌํจ).
*/
#[McpTool(name: 'calculate_power')]
public function power(
#[Schema(type: 'number', minimum: 0, maximum: 1000)]
float $base,
#[Schema(type: 'integer', minimum: 0, maximum: 10)]
int $exponent
): float {
return pow($base, $exponent);
}
}
์๋ก์ด MCP ํด ํด๋์ค ์์ฑํ๊ธฐ
ํ์ผ ์์ฑ:
modules/example/mcp/
๋๋ ํ ๋ฆฌ์ ์ PHP ํ์ผ(YourCustomTool.php)์ ์์ฑํฉ๋๋ค.๊ธฐ๋ณธ ํด๋์ค ๊ตฌ์กฐ:
<?php
namespace Rhymix\Modules\Example\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
use PhpMcp\Server\Attributes\Schema;
/**
* ์ฌ์ฉ์ ์ ์ MCP ํด
*/
class YourCustomTool extends MCPServerInterface
{
/**
* ํด ๋ฉ์๋ ์์
*/
#[McpTool(name: 'your_tool_name')]
public function yourMethod($param1, $param2)
{
// ์ฌ๊ธฐ์ ๋น์ฆ๋์ค ๋ก์ง ๊ตฌํ
return "๊ฒฐ๊ณผ";
}
}
๋ผ์ด๋ฏน์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ ์์
<?php
namespace Rhymix\Modules\Example\Mcp;
use Rhymix\Modules\Mcpserver\Models\MCPServerInterface;
use PhpMcp\Server\Attributes\McpTool;
class RhymixDatabaseTool extends MCPServerInterface
{
/**
* ํ์ ์ ๋ณด๋ฅผ ์กฐํํฉ๋๋ค.
*/
#[McpTool(name: 'get_member_info')]
public function getMemberInfo(int $member_srl): array
{
// ๋ผ์ด๋ฏน์ค ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ ์คํ
$output = executeQuery('member.getMemberInfoByMemberSrl', ['member_srl' => $member_srl]);
if (!$output->toBool()) {
throw new \Exception('ํ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค: ' . $output->getMessage());
}
$member = $output->data;
return [
'member_srl' => $member->member_srl,
'user_id' => $member->user_id,
'nick_name' => $member->nick_name,
'email_address' => $member->email_address
];
}
/**
* ๊ฒ์๋ฌผ ๋ชฉ๋ก์ ์กฐํํฉ๋๋ค.
*/
#[McpTool(name: 'get_document_list')]
public function getDocumentList(int $module_srl, int $page = 1): array
{
$args = new \stdClass();
$args->module_srl = $module_srl;
$args->page = $page;
$args->list_count = 10;
$output = executeQueryArray('document.getDocumentList', $args);
if (!$output->toBool()) {
throw new \Exception('๊ฒ์๋ฌผ ๋ชฉ๋ก์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค: ' . $output->getMessage());
}
return [
'total_count' => $output->total_count,
'documents' => $output->data
];
}
}
์คํค๋ง ์ ํจ์ฑ ๊ฒ์ฌ
MCP ํด์์๋ Schema
์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ฌ์ฉํ์ฌ ์
๋ ฅ ๋งค๊ฐ๋ณ์์ ๋ํ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค:
#[McpTool(name: 'validated_tool')]
public function validatedMethod(
#[Schema(type: 'string', minLength: 1, maxLength: 100)]
string $text,
#[Schema(type: 'integer', minimum: 1, maximum: 999)]
int $number,
#[Schema(type: 'number', minimum: 0.0, maximum: 100.0)]
float $percentage
): array {
return [
'text' => $text,
'number' => $number,
'percentage' => $percentage
];
}
์ด์ธ์ ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ํ๋ค๋ฉด php-mcp/server๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๋๋ฒ๊น
๋ก๊ทธ ํ์ธ
MCP ์๋ฒ๋ ์ค์ ์ ๋ฐ๋ผ ์์ธํ ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ๋ก๊ทธ๋ฅผ ํตํด ๋ค์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค:
- ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ/ํด์
- ํด ํธ์ถ ๋ฐ ์๋ต
- ์ค๋ฅ ๋ฐ ์์ธ ์ ๋ณด
์ฐ๊ฒฐ ํ ์คํธ
๊ด๋ฆฌ์ ํ์ด์ง์์ "๋ก์ปฌ ์ฐ๊ฒฐ ํ ์คํธ" ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ MCP ์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์๋ํ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
์ฃผ์์ฌํญ
- MCP ์๋ฒ๋ ๋ณด์์ด ์ค์ํ ํ๊ฒฝ์์๋ ์ ์ ํ ๋ฐฉํ๋ฒฝ ์ค์ ๊ณผ ํจ๊ป ์ฌ์ฉํ์ธ์.
- ํ๋ก๋์ ํ๊ฒฝ์์๋ DEBUG ๋ก๊ทธ ๋ ๋ฒจ์ ๋นํ์ฑํํ๋ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
- ์ฌ์ฉ์ ์ ์ ํด์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ ์ ์ ์ ํ ๊ถํ ๊ฒ์ฌ๋ฅผ ์ํํ์ธ์.
๋ผ์ด์ ์ค
์ด ๋ชจ๋์ GPL v2 ๋ผ์ด์ ์ค ํ์ ๋ฐฐํฌ๋ฉ๋๋ค.
๊ฐ๋ฐ์
- Waterticket ([email protected])
- ์น์ฌ์ดํธ: https://potatosoft.kr
- ๋ชจ๋ ์์ฑ๊ธฐ: https://www.poesis.dev/
๊ธฐ์ ์ง์
๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๋์์ด ํ์ํ ๊ฒฝ์ฐ:
- ๋ผ์ด๋ฏน์ค ๊ณต์ ์ปค๋ฎค๋ํฐ์์ ์ง๋ฌธ
- GitHub ์ด์ ๋ฑ๋ก (ํด๋นํ๋ ๊ฒฝ์ฐ)