MCP服务器工具执行服务

为MCP服务器提供工具定义和执行能力,允许在MediaWiki扩展中定义工具并由MCP服务器使用。

  • by hallowelt
  • PHP
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 hallowelt/mwstake-mediawiki-component-mcp

使用说明

MCP服务器配套

此组件为MCP服务器提供工具定义和执行能力。 MCP服务器使用它来检索工具定义并执行它们,从而允许定义工具 在MediaWiki扩展中,由MCP服务器使用 (这在MCP服务器本身非常困难和不便,因为它是一个Node.js应用程序)。

在wiki端设置

要设置组件,请将以下内容添加到您的 LocalSettings.php 文件:

$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'] = $GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'] ?? [];

$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'][] = '/mws/v1/mcp/get_wiki_map';
$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'][] = '/mws/v1/app-token/generate';
$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'][] = '/mws/v1/app-token/verify';
$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'][] = '/mws/v1/mcp/list_tools';
$GLOBALS['mwsgTokenAuthenticatorServiceAllowedRestPaths'][] = '/mws/v1/mcp/get_wiki_map';

添加工具

创建一个定义工具的类


use MWStake\MediaWiki\Component\MCP\ExecutionHandler\RestApiHandler;
use MWStake\MediaWiki\Component\MCP\FieldSchema;
use MWStake\MediaWiki\Component\MCP\IMcpTool;
use MWStake\MediaWiki\Component\MCP\IMcpToolExecutionHandler;
use MWStake\MediaWiki\Component\MCP\ToolDefinition;

class CreatePage implements IMcpTool {

	public function getKey(): string {
		return 'createPage';
	}

	/**
	 * @return ToolDefinition
	 */
	public function getDefinition(): ToolDefinition {
		$inputSchema = ( new FieldSchema() )
			->addString( 'source', 'Text, content of the page' )
			->addString( 'title', 'Title of the page' )
			->addString( 'comment', 'Summary of the edit. Can be null' )
			->setNullable( 'comment' )
			->setRequired( [ 'source', 'title', 'comment' ] );

		$outputSchema = ( new FieldSchema() )
			->addInteger( 'id', 'ID of the page that was just created' )
			->addString( 'title', 'Title of the page that was just created' )
			->addString( 'key', 'DB-key of the page that was just created' );

		return new ToolDefinition(
			'Create a wiki page',
			'Create aage with given content',
			$inputSchema,
			$outputSchema
		);
	}

	/**
	 * @return IMcpToolExecutionHandler
	 */
	public function getExecutionMethod(): IMcpToolExecutionHandler {
		return new RestApiHandler( '/v1/page/', 'POST' );
	}
}

或者,指定为通用工具(没有自定义类)

$inputSchema = ( new FieldSchema() )
    ->addString( 'source', 'Text, content of the page' )
    ->addString( 'title', 'Title of the page' )
    ->addString( 'comment', 'Summary of the edit. Can be null' )
    ->setNullable( 'comment' )
    ->setRequired( [ 'source', 'title', 'comment' ] );

$outputSchema = ( new FieldSchema() )
    ->addInteger( 'id', 'ID of the page that was just created' )
    ->addString( 'title', 'Title of the page that was just created' )
    ->addString( 'key', 'DB-key of the page that was just created' );

$definition = new ToolDefinition(
    'Create a wiki page',
    'Create aage with given content',
    $inputSchema,
    $outputSchema
);

$tool = new MWStake\MediaWiki\Component\MCP\Tool\GenericTool(
    'createPage',
    $definition,
    new RestApiHandler( '/v1/page/', 'POST' )
);

然后,在DI容器中注册该工具:


function onMediaWikiServices( $services ) {
    $registry = $services->getService( 'MWStake.MCP.ToolRegistry' );
    $registry->registerTool( $tool );
}

执行方法

如上所示,工具返回 IMcpToolExecutionHandler这定义了应该如何执行此工具。 工具可以执行常规的、已经存在的API

return new RestApiHandler( '/v1/page/', 'POST' );
return new ActionApiHandler( 'edit' )

或者他们可以为工具定义一个自定义处理程序


class MyCustomToolExecutor implement IMcpToolExecutor {
    public function execute( IMcpTool $tool, array $input ): array {
        // Process $input (which will be in format as specified by tool's input schema) and execute the tool's action
        // Return output in format specified by tool's output schema
    }
}

在这种情况下,请在 getExecutionMethod 工具的方法

return new DirectExecution( [
    'class' => MyCustomToolExecutor::class,
    'args' => ...
] );

看 examples/Examples.MD 了解更多工具和执行方法的示例。

备注

  • 避免实施运行的工具 POST 针对ActionAPI的请求。它需要检索CSRF令牌, 增加了流量和延迟。尽可能使用REST对应项
  • 工具列表始终从以下位置检索 w。因此,对于所有实例,它总是相同的,并且检索到的所有工具都需要 可用于所有入口(无论如何都是这样,但只需提及:)