Search by

kinetis / mcp-protocol

aln-1

Model Context Protocol 2025-06-18 over JSON-RPC 2.0 — envelope validation, typed tool and resource contracts, progress notifications, and checked newline-delimited stdio framing. Requires PHP only.

Package info

github.com/kinetis-dev/mcp-protocol

pkg:composer/kinetis/mcp-protocol

Statistics

Installs: 24

Dependents: 6

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-09-17 20:34 UTC

This package is auto-updated.

Last update: 2026-09-17 20:54:37 UTC


README

Kinetis

kinetis/mcp-protocol
MCP 2025-06-18 over JSON-RPC, as a framework-agnostic library

Packagist Version Packagist Downloads PHP Version License CI

Part of Kinetis, a non-blocking PHP framework for API-first applications, developed in the kinetis-dev/kinetis monorepo.

The Model Context Protocol mechanics three Kinetis servers share: JSON-RPC 2.0 envelopes, one MCP revision, typed tool and resource descriptions, progress notifications, and a checked newline-delimited stdio loop. It requires PHP and nothing else.

Install

composer require kinetis/mcp-protocol

What it owns

  • One revision, 2025-06-18. initialize always selects it, whichever revision the client asks for — the specification's rule is that a server answers with a version it supports and the client decides whether to continue.
  • Envelope validation. One decode and structural-validation path for every transport, preserving JSON object-versus-array identity so {} and [] stay distinct all the way to a tool's arguments.
  • initialize, ping, tools/list, tools/call, resources/list, resources/read, and the notification rules around them.
  • Stdio framing. Bounded reads, a 2 MiB payload cap, checked partial writes, and progress notifications ordered before the final response.

What it does not own

No framework, container, HTTP transport, attribute, reflection, discovery, documentation fetching, filesystem policy, application bootstrap, or connection session. It stores nothing between messages, which is what lets one instance serve a persistent stdio process and a stateless HTTP route at the same time.

Writing a server

A consumer implements McpApplication and hands it to McpServer:

use Kinetis\McpProtocol\McpApplication;
use Kinetis\McpProtocol\McpServer;
use Kinetis\McpProtocol\ProgressEmitter;
use Kinetis\McpProtocol\ResourceDescription;
use Kinetis\McpProtocol\ResourceResult;
use Kinetis\McpProtocol\ServerInfo;
use Kinetis\McpProtocol\StdioLoop;
use Kinetis\McpProtocol\ToolDescription;
use Kinetis\McpProtocol\ToolResult;

final class Clock implements McpApplication
{
    public function tools(): array
    {
        return [new ToolDescription(
            'now',
            'Returns the current UTC time.',
            ['type' => 'object', 'properties' => new stdClass(), 'additionalProperties' => false],
        )];
    }

    public function resources(): array
    {
        return [];
    }

    public function callTool(string $name, stdClass $arguments, ProgressEmitter $progress, ?object $context): ToolResult
    {
        return ToolResult::text(new DateTimeImmutable('now', new DateTimeZone('UTC'))->format(DATE_ATOM));
    }

    public function readResource(string $uri, ?object $context): ResourceResult
    {
        throw new LogicException('This server publishes no resources.');
    }
}

$server = new McpServer(new ServerInfo('clock', '1.0.0'), new Clock());

new StdioLoop()->run($server, STDIN, STDOUT);

The server resolves name and uri against those two lists before it calls anything, so callTool() and readResource() are only ever reached for a name the consumer itself published. Capabilities are advertised from the same lists: the server above offers tools and not resources.

A consumer needing a per-message unit of work — a container scope, a transaction — implements MessageHandler around the server and passes its own object as the opaque $context, which travels to callTool() and readResource() untouched.

Documentation

Kinetis MCP guide · Appendix: MCP Reference

License

MIT