Use when working with the MCP server endpoint, JSON-RPC handling, tool registry, authentication, or files in packages/mcp/
Scanned 9/12/2026
Install to Claude Code
npx -y skills add aibot88/sec_skill_store --skill mcp-endpoint --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mcp Endpoint?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/aibot88-mcp-endpoint)More formats (shields.io, HTML) on the badges page.
---
name: waaseyaa:mcp-endpoint
description: Use when working with the MCP server endpoint, JSON-RPC handling, tool registry, authentication, or files in packages/mcp/
---
# MCP Endpoint Specialist
## Scope
This skill covers the MCP (Model Context Protocol) package:
- `packages/mcp/src/` -- McpEndpoint, McpResponse, McpRouteProvider, McpServerCard
- `packages/mcp/src/Auth/` -- McpAuthInterface, BearerTokenAuth
- `packages/mcp/src/Bridge/` -- ToolRegistryInterface, ToolExecutorInterface
Use this skill when:
- Adding or modifying the MCP HTTP endpoint
- Working with JSON-RPC protocol handling
- Changing MCP authentication
- Adding new JSON-RPC methods or tool capabilities
- Wiring MCP routes into the front controller
- Working with the tool registry or executor bridge
## Key Interfaces
### McpEndpoint (packages/mcp/src/McpEndpoint.php)
```php
final readonly class McpEndpoint
{
public function __construct(
private McpAuthInterface $auth,
private ToolRegistryInterface $registry,
private ToolExecutorInterface $executor,
) {}
public function handle(
string $method,
string $body,
?string $authorizationHeader,
): McpResponse;
}
```
Single entry point for all MCP traffic. Authenticates, parses JSON-RPC, dispatches to internal handlers.
### McpResponse (packages/mcp/src/McpResponse.php)
```php
final readonly class McpResponse
{
public function __construct(
public string $body,
public int $statusCode = 200,
public string $contentType = 'application/json',
) {}
}
```
### McpAuthInterface (packages/mcp/src/Auth/McpAuthInterface.php)
```php
interface McpAuthInterface
{
public function authenticate(?string $authorizationHeader): ?AccountInterface;
}
```
Returns `AccountInterface` on success, `null` on failure. `BearerTokenAuth` is the MVP implementation mapping opaque tokens to accounts.
### ToolRegistryInterface (packages/mcp/src/Bridge/ToolRegistryInterface.php)
```php
interface ToolRegistryInterface
{
/** @return McpToolDefinition[] */
public function getTools(): array;
public function getTool(string $name): ?McpToolDefinition;
}
```
### ToolExecutorInterface (packages/mcp/src/Bridge/ToolExecutorInterface.php)
```php
interface ToolExecutorInterface
{
public function execute(string $toolName, array $arguments): array;
}
```
Returns MCP tool result format: `{content: [{type: "text", text: "..."}], isError?: bool}`.
## Architecture
### JSON-RPC Dispatch Flow
```
POST /mcp
-> McpEndpoint::handle()
-> authenticate($authorizationHeader) -> AccountInterface | null (401)
-> json_decode($body) -> parse error (-32700) | invalid request (-32600)
-> match $request['method']:
'initialize' -> protocol version, capabilities, server info
'ping' -> empty result
'tools/list' -> ToolRegistryInterface::getTools() -> toArray()
'tools/call' -> ToolExecutorInterface::execute($name, $arguments)
default -> method not found (-32601)
```
### JSON-RPC Error Codes
| Code | Meaning |
|------|---------|
| `-32700` | Parse error (invalid JSON) |
| `-32600` | Invalid request (missing `method` field) |
| `-32601` | Method not found |
| `-32602` | Invalid params (missing tool name, unknown tool) |
| `-32001` | Unauthorized (auth failure) |
### Routes
`McpRouteProvider` registers two routes:
| Route | Path | Methods | Auth |
|-------|------|---------|------|
| `mcp.endpoint` | `/mcp` | POST, GET | Required (bearer token) |
| `mcp.server_card` | `/.well-known/mcp.json` | GET | Public |
**Note:** Routes are defined in `McpRouteProvider` but not yet wired into `public/index.php`. This is a known gap.
### Package Dependencies
- **Layer 6** (Interfaces) -- can import from layers 0-5
- Depends on: `waaseyaa/ai-schema` (McpToolDefinition), `waaseyaa/ai-agent` (AgentExecutor), `waaseyaa/routing`, `waaseyaa/access` (AccountInterface)
## Common Mistakes
### JSON symmetry
Always pair `json_encode(..., JSON_THROW_ON_ERROR)` with `json_decode(..., JSON_THROW_ON_ERROR)`. The endpoint already does this correctly -- maintain it.
### AccountInterface, not concrete User
The auth interface returns `?AccountInterface` (from `waaseyaa/access`), not a concrete `User` class (from `waaseyaa/user`). The MCP package must not depend on `waaseyaa/user`.
### Tool result format
Tool executor must return `{content: [{type: "text", text: "..."}]}`. The `isError` key is optional (defaults to false). Don't return raw strings or arrays -- wrap in the content block format.
### php://input is single-read
`HttpRequest::createFromGlobals()` consumes `php://input`. The front controller must pass the body via `$httpRequest->getContent()`, not re-read `php://input`.
### Final classes cannot be mocked
All concrete classes are `final readonly class`. Use real instances in tests:
```php
// Auth: use BearerTokenAuth with known tokens
$auth = new BearerTokenAuth(['test-token' => $account]);
// Registry/Executor: use anonymous classes implementing the interfaces
$registry = new class implements ToolRegistryInterface { ... };
$executor = new class implements ToolExecutorInterface { ... };
$endpoint = new McpEndpoint($auth, $registry, $executor);
$response = $endpoint->handle('POST', $body, 'Bearer test-token');
```
## Testing Patterns
### Unit Testing McpEndpoint
```php
$auth = new BearerTokenAuth(['tok' => $account]);
$registry = new class implements ToolRegistryInterface {
public function getTools(): array { return []; }
public function getTool(string $name): ?McpToolDefinition { return null; }
};
$executor = new class implements ToolExecutorInterface {
public function execute(string $toolName, array $arguments): array {
return ['content' => [['type' => 'text', 'text' => 'ok']]];
}
};
$endpoint = new McpEndpoint($auth, $registry, $executor);
// Test auth failure
$response = $endpoint->handle('POST', '{}', null);
assert($response->statusCode === 401);
// Test ping
$body = json_encode(['jsonrpc' => '2.0', 'method' => 'ping', 'id' => 1]);
$response = $endpoint->handle('POST', $body, 'Bearer tok');
assert($response->statusCode === 200);
```
### Testing BearerTokenAuth
```php
$auth = new BearerTokenAuth(['secret' => $account]);
assert($auth->authenticate(null) === null);
assert($auth->authenticate('Bearer wrong') === null);
assert($auth->authenticate('Bearer secret') === $account);
assert($auth->authenticate('bearer secret') === $account); // case-insensitive
```
### Testing McpServerCard
```php
$card = new McpServerCard(name: 'Test', version: '1.0.0', endpoint: '/mcp');
$json = $card->toJson();
$decoded = json_decode($json, true);
assert($decoded['endpoint'] === '/mcp');
assert($decoded['transport'] === 'streamable-http');
```
## Related Specs
- `docs/specs/mcp-endpoint.md` -- Full MCP endpoint specification
- `docs/specs/ai-integration.md` -- AI layer that provides McpToolDefinition and AgentExecutor
- `CLAUDE.md` -- Project-wide gotchas including JSON symmetry and AccountInterface vs User
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!