Skip to content
Back to skills

Mcp Endpoint

ASecurity

Use when working with the MCP server endpoint, JSON-RPC handling, tool registry, authentication, or files in packages/mcp/

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
ai-agentsgophptesting

Works with

  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 12, 2026

npx -y skills add aibot88/sec_skill_store --skill mcp-endpoint --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mcp Endpoint?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mcp Endpoint
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aibot88-mcp-endpoint/badge)](https://www.skillsdirectory.com/skills/aibot88-mcp-endpoint)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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

Files in this skill

  • SKILL.md6.9 KB
  • source.json637 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.