Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add rules/kerlos/elysia-mcp/json-rpcgit clone --depth 1 https://github.com/kerlos/elysia-mcpWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/rules/kerlos/elysia-mcp/json-rpc)<a href="https://agentmods.dev/rules/kerlos/elysia-mcp/json-rpc"><img src="https://agentmods.dev/badge/rules/kerlos/elysia-mcp/json-rpc.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.09138 |
| Opus 5 | $0.00000 | $0.04569 |
| Sonnet 5 | $0.00000 | $0.01828 |
| Haiku 4.5 | $0.00000 | $0.00914 |
Grade A, and why
json-rpc scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 1,404 lines — stays where its author put it; the contents beside it link to each section on GitHub.
import { z, ZodTypeAny } from "zod";
export const LATEST_PROTOCOL_VERSION = "2025-03-26"; export const SUPPORTED_PROTOCOL_VERSIONS = [ LATEST_PROTOCOL_VERSION, "2024-11-05", "2024-10-07", ];
/* JSON-RPC types */ export const JSONRPC_VERSION = "2.0";
/**
- A progress token, used to associate progress notifications with the original request. */ export const ProgressTokenSchema = z.union([z.string(), z.number().int()]);
/**
- An opaque token used to represent a cursor for pagination. */ export const CursorSchema = z.string();
const RequestMetaSchema = z .object({ /** * If specified, the caller is requesting out-of-band progress notifications for this request (as represented by notifications/progress). The value of this parameter is an opaque token that will be attached to any subsequent notifications. The receiver is not obligated to provide these notifications. */ progressToken: z.optional(ProgressTokenSchema), }) .passthrough();
const BaseRequestParamsSchema = z .object({ _meta: z.optional(RequestMetaSchema), }) .passthrough();
export const RequestSchema = z.object({ method: z.string(), params: z.optional(BaseRequestParamsSchema), });
const BaseNotificationParamsSchema = z .object({ /** * This parameter name is reserved by MCP to allow clients and servers to attach additional metadata to their notifications. */ _meta: z.optional(z.object({}).passthrough()), }) .passthrough();
export const NotificationSchema = z.object({ method: z.string(), params: z.optional(BaseNotificationParamsSchema), });
export const ResultSchema = z .object({ /** * This result property is reserved by the protocol to allow clients and servers to attach additional metadata to their responses. */ _meta: z.optional(z.object({}).passthrough()), }) .passthrough();
/**
- A uniquely identifying ID for a request in JSON-RPC. */ export const RequestIdSchema = z.union([z.string(), z.number().int()]);
/**
- A request that expects a response. */ export const JSONRPCRequestSchema = z .object({ jsonrpc: z.literal(JSONRPC_VERSION), id: RequestIdSchema, }) .merge(RequestSchema) .strict();
export const isJSONRPCRequest = (value: unknown): value is JSONRPCRequest => JSONRPCRequestSchema.safeParse(value).success;
/**
- A notification which does not expect a response. */ export const JSONRPCNotificationSchema = z .object({ jsonrpc: z.literal(JSONRPC_VERSION), }) .merge(NotificationSchema) .strict();
export const isJSONRPCNotification = ( value: unknown ): value is JSONRPCNotification => JSONRPCNotificationSchema.safeParse(value).success;
/**
- A successful (non-error) response to a request. */ export const JSONRPCResponseSchema = z .object({ jsonrpc: z.literal(JSONRPC_VERSION), id: RequestIdSchema, result: ResultSchema, }) .strict();
export const isJSONRPCResponse = (value: unknown): value is JSONRPCResponse => JSONRPCResponseSchema.safeParse(value).success;
/**
- Error codes defined by the JSON-RPC specification. */ export enum ErrorCode { // SDK error codes ConnectionClosed = -32000, RequestTimeout = -32001,
// Standard JSON-RPC error codes ParseError = -32700, InvalidRequest = -32600, MethodNotFound = -32601, InvalidParams = -32602, InternalError = -32603, }
/**
- A response to a request that indicates an error occurred. / export const JSONRPCErrorSchema = z .object({ jsonrpc: z.literal(JSONRPC_VERSION), id: RequestIdSchema, error: z.object({ /* * The error type that occurred. / code: z.number().int(), /* * A short description of the error. The message SHOULD be limited to a concise single sentence. / message: z.string(), /* * Additional information about the error. The value of this member is defined by the sender (e.g. detailed error information, nested errors etc.). */ data: z.optional(z.unknown()), }), }) .strict();
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 5d ago First seen · 1,404 lines · 0 tokens per session scan A c6a92ea1d8b3
json-rpc is a cursor rule published in the GitHub repository kerlos/elysia-mcp (47 stars, last pushed 2mo ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 9,138 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other cursor rules, from other repositories
schema-coupling
Guidance for keeping TypeScript types and Zod schemas synchronized.
pn-go-backend
Go backend style, env, and error handling. Use for API and server code (Gin, Fiber, Echo).
pn-php-backend
PHP backend style, env, and error handling. Use for API and server code (Laravel, Slim).
pn-python-backend
Python backend style, env/secrets, and error handling. Use for API and server code (FastAPI, Flask).
pn-ruby-backend
Ruby backend style, env, and error handling. Use for API and server code (Rails, Sinatra).
pn-rust-backend
Rust backend style, env, and error handling. Use for API and server code (Actix-web, Axum).