Download the PHP package knetesin/json-rpc-server without Composer
On this page you can find all versions of the php package knetesin/json-rpc-server. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download knetesin/json-rpc-server
More information about knetesin/json-rpc-server
Files in knetesin/json-rpc-server
Package json-rpc-server
Short Description Modern JSON-RPC 2.0 server bundle for Symfony with DTOs, validation, streaming, MCP, caching, rate limiting, and built-in observability.
License MIT
Homepage https://github.com/knetesin/json-rpc-server
Informations about the package json-rpc-server
JsonRpc Server Bundle
A modern JSON-RPC 2.0 server for Symfony — built around attributes, DTOs, and the rest of the framework you already use. Speaks JSON-RPC for your own clients, MCP for AI agents, and NDJSON / SSE when you need to stream.
That's a full handler. No routing, no controllers, no manual validation, no container wiring — the bundle does the boring parts.
Documentation
Full guide in RU):
| Chapter | Covers |
|---|---|
| Getting started | Install, first handler, first call |
| Methods | #[Rpc\Method], batch, notifications, deprecation |
| Parameters & DTOs | DTO denormalization, #[Rpc\Param], dates |
| Security & roles | roles, RoleMatch, security-core integration |
| Caching | #[Rpc\Cache], scopes, pools, tags, invalidator |
| Rate limiting | Four policies, three scopes |
| Streaming | NDJSON / SSE / JSON-array, error frames |
| MCP | Tool listing, invoke, formats, transformer |
| OpenRPC | Generate the spec |
| Errors | Exception hierarchy, custom server errors |
| Observability | Events, profiler, logging, Sentry, OpenTelemetry |
| CLI & maker | debug:rpc, rpc:cache:clear, make:rpc-method |
| Configuration reference | Every YAML knob |
| Context | The Context object, request id |
The same chapters are also served at
knetesin.github.io/json-rpc-server
once GitHub Pages is enabled on the docs/ folder.
Table of contents
- Why this bundle
- Requirements
- Install
- Five-minute tour
- Feature highlights
- Configuration
- Versioning
- Contributing
- License
Why this bundle
- Real Symfony, not glued on. Methods are services, DTOs go through Symfony Serializer, validation through Symfony Validator, authorisation through Symfony Security. No parallel universe to maintain.
- Attribute-driven.
#[Rpc\Method],#[Rpc\Cache],#[Rpc\RateLimit],#[Rpc\Stream],#[Rpc\Mcp]. One place to read, one place to grep. - Compile-time discovery. Every method is registered in a container compiler pass — zero reflection in the hot path, zero boot tax.
- First-class MCP. Expose handlers as MCP tools with auto-generated JSON
Schemas. Five rendering formats (
json,pretty_json,markdown,plain,toon) so the same tool can answer LLM agents and machine clients with shapes each prefers. - Streaming on its own endpoint. NDJSON, Server-Sent Events, JSON-array.
Spec-compliant
/rpcstays unchanged;/rpc/streamis the deliberate extension. - Built-in observability. Drop a flag in YAML and get PSR-3 logs, Symfony Web Profiler entries, Sentry breadcrumbs, or vendor-neutral OpenTelemetry traces + metrics + W3C trace-context propagation.
- Safe defaults. Handlers are non-shared (no state leak under RoadRunner / FrankenPHP / Swoole). DTOs reject unknown fields. Cache invalidation by tag. Per-method body-size limits. Deprecation headers.
Requirements
- PHP 8.3+ (typed class constants are used throughout)
- Symfony 7.x or 8.x
ext-jsonsymfony/expression-language(routeconditions for per-route enable flags)
Optional packages (everything degrades gracefully when absent — the container build fails loudly only if you reference a feature whose package is missing):
| Package | Enables |
|---|---|
symfony/security-bundle |
role checks, authenticated Context::$user, user-scoped rate limit / cache |
symfony/cache |
tag-aware cache invalidation (RpcCacheInvalidator::purgeMethod / purgeTags) |
symfony/rate-limiter |
#[Rpc\RateLimit] |
symfony/maker-bundle |
bin/console make:rpc-method scaffolder |
symfony/web-profiler-bundle |
RPC panel in the Symfony Web Profiler |
sentry/sentry-symfony |
Sentry breadcrumbs / tags / spans |
open-telemetry/sdk |
OpenTelemetry traces / metrics / propagation |
Install
With Symfony Flex the bundled recipe should create two files:
config/packages/json_rpc_server.yaml (settings) and
config/routes/json_rpc_server.yaml (route import — required for
debug:router to show /rpc). The recipe ships in the package (.symfony/recipe/);
if composer require did not copy them, see Getting started.
Without Flex (or if the recipe was skipped), add manually:
That's it. Default routes:
| Route | Path | Method |
|---|---|---|
rpc |
/rpc |
POST |
rpc_stream |
/rpc/stream |
POST |
rpc_mcp_tools |
/mcp/tools |
GET |
rpc_mcp_call |
/mcp/call |
POST |
All paths configurable; any route disable-able via
json_rpc_server.routes.{name}.enabled: false.
Five-minute tour
A handler
A DTO
Invalid input surfaces as -32602 Invalid params with per-field violation
paths in error.data. No try/catch in your handler.
Inspecting
Scaffolding (with symfony/maker-bundle)
Feature highlights
DTOs and validation
DTOs are plain PHP classes. The bundle denormalizes incoming JSON via Symfony
Serializer (enums, dates, nested VOs, value objects with constructors —
everything), validates via Symfony Validator, and surfaces violations with
their field paths. #[Rpc\Param] is available for handlers that prefer
scalar parameters over a DTO.
Roles
any (default) requires one of the roles; all requires every role. Public
methods omit roles.
Caching
Cache key composed from method + scope contributor (user / IP / your own) +
hashed params. Notifications never cached. Tag-aware invalidation via
RpcCacheInvalidator when symfony/cache is installed.
Rate limiting
Four policies (FixedWindow, SlidingWindow, TokenBucket, NoLimit),
three scopes (User, Ip, GlobalScope). Excess calls throw
RateLimitExceededException (code -32003) with retryAfter in data.
Exempt selected callers (verified search-engine crawlers, internal IPs, health
checks) by implementing RateLimitBypassInterface — it's auto-tagged and
consulted before the counter. See Rate limiting.
Streaming
POST the same JSON-RPC envelope to /rpc/stream. Three formats: Ndjson,
Sse, JsonArray. Mid-stream errors emit an inline error frame in the
active format instead of breaking the HTTP response.
MCP — for LLM agents
Two ways to expose methods as Model Context Protocol tools:
- Opt-in per method:
#[Rpc\Mcp(description: '…')] - Opt-out by prefix:
json_rpc_server.mcp.expose_all: true+exclude_prefixes: ['auth.']
GET /mcp/tools lists tools with auto-generated JSON Schemas built from the
DTO constructor and a curated set of Symfony Validator constraints
(NotBlank, Length, Range, Positive, Choice, Email, Url,
Regex). POST /mcp/call invokes them.
Five rendering formats — chosen per-request via header / query / attribute:
| Format | Output |
|---|---|
json (default) |
compact JSON, one line — smallest payload |
pretty_json |
indented JSON — chat UI |
markdown |
tables for lists, text for scalars, JSON for the rest |
plain |
scalars unquoted, objects pretty JSON |
toon |
TOON — indentation-based, token-efficient for LLM consumers |
Typed exceptions
Bundle-provided exceptions cover -32700 Parse, -32600 InvalidRequest,
-32601 MethodNotFound, -32602 InvalidParams, -32603 Internal,
-32001 AccessDenied, -32002 NotFound, -32003 RateLimitExceeded.
Context
No Security::getUser() calls everywhere; the dispatcher hands you Context
when you ask for it.
Observability — pick your stack, all opt-in
| Stack | Switch |
|---|---|
| PSR-3 logging | json_rpc_server.logging.enabled: true |
| Symfony Web Profiler | auto-active in kernel.debug |
| Sentry (breadcrumbs / tag / spans) | json_rpc_server.sentry.enabled: true |
| OpenTelemetry (traces / metrics / propagation) | json_rpc_server.opentelemetry.enabled: true |
All four read the same three PSR-14 events the dispatcher fires
(MethodInvocationStarted/Completed/Failed), plus the streaming events.
Wire your own listener for anything custom.
OpenRPC document
OpenRpcDocumentBuilder generates an OpenRPC spec
of every registered method — feed it to SDK generators / Postman / docs sites.
Deprecation
#[Rpc\Method(deprecated: 'use user.v2.update instead')] — every call is
logged with the reason, and the response carries Deprecation: true (RFC
9745) plus the human-readable hint in the configurable
X-Rpc-Deprecated header. Deprecated methods auto-hidden from MCP.
Configuration
Every knob, all defaults shown. Place under
config/packages/json_rpc_server.yaml.
Full reference with every knob's rationale: docs/en/13-configuration.md.
Versioning
Semantic Versioning. Anything outside the documented public API
(Knetesin\JsonRpcServerBundle\Attribute\*, Knetesin\JsonRpcServerBundle\Context\*,
Knetesin\JsonRpcServerBundle\Exception\*, Knetesin\JsonRpcServerBundle\Type\*, event classes,
configuration tree) is internal and may change in patch releases.
Contributing
Pull requests welcome. Discussion / questions: GitHub Discussions. Bugs: issues.
For larger features, please open a discussion first — the bundle aims to stay small at the core and push everything else to opt-in subscribers.
License
MIT. © Contributors of
knetesin/json-rpc-server.
All versions of json-rpc-server with dependencies
ext-json Version *
phpdocumentor/type-resolver Version ^2.0
phpstan/phpdoc-parser Version ^2.3
psr/cache Version ^2.0 || ^3.0
psr/container Version ^1.1 || ^2.0
psr/event-dispatcher Version ^1.0
psr/log Version ^1 || ^2 || ^3
symfony/config Version ^7.0 || ^8.0
symfony/dependency-injection Version ^7.0 || ^8.0
symfony/expression-language Version ^7.0 || ^8.0
symfony/http-foundation Version ^7.0 || ^8.0
symfony/http-kernel Version ^7.0 || ^8.0
symfony/property-info Version ^7.4 || ^8.0
symfony/routing Version ^7.0 || ^8.0
symfony/security-core Version ^7.0 || ^8.0
symfony/serializer Version ^7.0 || ^8.0
symfony/validator Version ^7.0 || ^8.0