定制 milpa/mcp-server 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

milpa/mcp-server

Composer 安装命令:

composer require milpa/mcp-server

包简介

Model Context Protocol (MCP) transport core for the Milpa PHP framework: a transport-agnostic JSON-RPC 2.0 dispatcher over the tool-runtime registry, plus the auth seam a host implements to turn a bearer token into an authenticated caller.

README 文档

README

Milpa

Milpa McpServer

The Model Context Protocol (MCP) transport core for the Milpa PHP framework, built on milpa/core and milpa/tool-runtime. A transport-agnostic JSON-RPC 2.0 dispatcher over the tool-runtime registry (initialize, notifications/initialized, tools/list, tools/call), plus the auth seam a host implements to turn a bearer token into an authenticated caller. No HTTP kernel, no SSE, no concrete token store — those live in your host application.

CI Packagist PHP License Docs

Install

composer require milpa/mcp-server

What it is

Milpa splits its surface into small, dependency-light packages. milpa/tool-runtime is the concrete engine that runs #[Tool]-attributed methods through one pipeline (resolve, validate, authorize, execute, audit); milpa/mcp-server is one transport for that engine — the Model Context Protocol, the JSON-RPC-based protocol LLM clients speak to discover and call tools over MCP.

This package is deliberately narrow. It ships:

  • JsonRpcService — decodes a JSON-RPC 2.0 request array, dispatches initialize, notifications/initialized, tools/list, and tools/call against a Milpa\ToolRuntime\ToolRegistry, and returns a JSON-RPC response array. It never touches HTTP, SSE, stdio, or a socket — it operates on plain arrays in, plain arrays out.
  • Auth\TokenValidatorInterface + Auth\Principal — the seam a host implements to authenticate an MCP caller. The transport layer needs exactly one thing from auth: turn a bearer token into a Principal (or null) it can build a ToolContext from. It does not need — and this package does not ship — a concrete token store, a Doctrine entity, or an identity provider.

What it does not ship, on purpose: the HTTP endpoint that terminates MCP's Streamable HTTP transport, the SSE stream, or an OAuth 2.0 authorization server for token issuance/exchange (registration, PKCE, the /oauth/* endpoints MCP clients probe per RFC 8414/9728). Those are real, substantial pieces of a production MCP server, but they are host wiring — they depend on your HTTP framework's request/response types, your session/storage layer, and your product's own auth UI — not on the MCP protocol logic itself. Build them in your host application as an adapter around JsonRpcService and TokenValidatorInterface.

Quick example

use Milpa\McpServer\JsonRpcService;
use Milpa\ToolRuntime\Contracts\ToolContext;
use Milpa\ToolRuntime\ToolRegistry;
use Psr\Log\NullLogger;

$registry = new ToolRegistry(new NullLogger());
// ... register tools on $registry, e.g. via ToolScanner ...

$rpc = new JsonRpcService($registry);

$ctx = new ToolContext(principal: 'user:42', channel: 'mcp', scopes: ['notes:read']);

$response = $rpc->handle([
    'jsonrpc' => '2.0',
    'method' => 'tools/call',
    'params' => ['name' => 'list_notes', 'arguments' => ['page' => 1]],
    'id' => 1,
], $ctx);

// $response is a plain JSON-RPC 2.0 response array — json_encode() it onto whatever
// transport your host terminates (an HTTP POST body, a stdio pipe, ...).

The auth seam

JsonRpcService itself takes an already-resolved ?ToolContext — it has no opinion on how you got there. The seam this package does define is one layer up: how a host turns a raw bearer token, arriving over whatever transport it terminates, into the Principal that becomes that ToolContext.

use Milpa\McpServer\Auth\Principal;
use Milpa\McpServer\Auth\TokenValidatorInterface;

final class DatabaseTokenValidator implements TokenValidatorInterface
{
    public function validate(string $token, ?string $ip = null): ?Principal
    {
        $record = $this->tokens->findValidByToken($token); // your own store, your own rules
        if ($record === null) {
            return null;
        }

        $record->recordUsage($ip); // optional side effect, entirely up to the implementation

        return new Principal(
            id: "user:{$record->ownerId()}",
            displayName: $record->ownerName(),
            scopes: $record->scopes(),
            extra: ['token_prefix' => $record->prefix()],
        );
    }
}

Your transport adapter (an HTTP controller, typically) then does three things per request: extract the bearer token, call $validator->validate($token, $ip), and — on a non-null Principal — build the ToolContext via $principal->toToolContext($ip, $userAgent) before handing the request to JsonRpcService::handle(). A null result means "reject with 401"; nothing about why it was null (expired vs. revoked vs. unknown) crosses this seam — that distinction, if you want it, lives entirely inside your TokenValidatorInterface implementation.

Why one interface, not two

The obvious alternative is splitting "is this token valid" from "who does it belong to" into two seams (a validator and a separate principal resolver). This package does not, because nothing in its own reference host ever calls them independently — every real call site authenticates a request by immediately needing both the yes/no and the principal in the same breath. A second seam here would be indirection with no consumer, not abstraction.

What lives where

Layer Package Owns
Contracts milpa/core Framework-wide primitives — events, attributes, DI/container contracts.
Tool engine milpa/tool-runtime ToolRegistry, #[Tool], ToolContext, the resolve→validate→authorize→execute→audit pipeline.
MCP transport milpa/mcp-server (this package) JsonRpcService (the JSON-RPC 2.0 ⇄ ToolRegistry bridge) and the TokenValidatorInterface/Principal auth seam.
Your app your host / plugins The concrete HTTP/SSE endpoint, the concrete TokenValidatorInterface implementation (token storage, expiry, revocation), and — if you need MCP clients to obtain tokens themselves — an OAuth 2.0 authorization server in front of it.

Requirements

Documentation

Full API reference: getmilpa.github.io/mcp-server — generated straight from the source DocBlocks and dressed with the Milpa design system.

Contributing

Contributions are welcome — see CONTRIBUTING.md. Please report security issues via SECURITY.md, and note that this project follows a Code of Conduct.

License

Apache-2.0 © TeamX Agency.

Milpa is designed, built, and maintained by TeamX Agency.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: Apache-2.0
  • 更新时间: 2026-07-07

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固