Hello, I'm Shrijith. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.
Let’s dig into the Model Context Protocol (MCP)—specifically its base protocol layer.If you’re crafting client-server apps and want a reliable, flexible communication system, this is your ticket.
The MCP base protocol, rooted in JSON-RPC 2.0, is the core of it all.
It’s straightforward but packed with power, and I'll walk you through it with plenty of details and examples.
Buckle up—this is going to be an interesting exploration!
What’s the MCP Base Protocol All About?
The MCP base protocol is the foundation of the Model Context Protocol, last updated on March 26, 2025.
*It’s the essential layer that *every MCP implementation must support, defining how clients and servers exchange messages using JSON-RPC 2.0. **
As of April 07, 2025, this is the latest spec, and it’s designed to be modular—pair it with lifecycle management (we’ll get there), and add only the extras your app needs, like server tools or client sampling.
Key Point: It’s all about separation of concerns. The base protocol handles core messaging, leaving room for optional features to slot in as needed.
Think of it as the minimal, must-have glue for client-server chatter.
Core Message Types: The Building Blocks
MCP leans on three message types, all following JSON-RPC 2.0 rules.
Let’s break them down with examples you can copy-paste and tweak.
Requests: Asking for Action
A request kicks off an operation. Here’s a client asking a server to process some data:
{
"jsonrpc": "2.0",
"id": "101",
"method": "processData",
"params": {
"input": "Hello, MCP!",
"priority": 1
}
}
-
id: Unique string or number (e.g.,
"101"). Null isn’t allowed, and you can’t reuse IDs in a session. -
method: The action, like
"processData". - params: Optional key-value pairs for the method.
Example Use: A client might send this to a server to analyze text. The server knows it’s request "101" and can reply accordingly.
Responses: Delivering Results or Errors
The server replies with a response—success or failure. Success looks like this:
{
"jsonrpc": "2.0",
"id": "101",
"result": {
"output": "Hello, MCP! Processed.",
"status": "complete"
}
}
Failure might be:
{
"jsonrpc": "2.0",
"id": "101",
"error": {
"code": -32000,
"message": "Invalid input format",
"data": {
"details": "Input must be UTF-8"
}
}
}
- id: Matches the request’s ID.
- result or error: One’s present, never both. Errors need a numeric code and a message.
Example Use: The server confirms it processed "101" or flags an issue. The client can act based on the outcome.
Notifications: One-Way Updates
Notifications are fire-and-forget messages—no response needed:
{
"jsonrpc": "2.0",
"method": "logStatus",
"params": {
"event": "Server started",
"timestamp": "2025-04-07T10:00:00Z"
}
}
- No id—it’s not tracked.
- Used for updates like logs or status pings.
Example Use: A server might send this to log its startup. The client sees it but doesn’t reply.
Batching: Grouping Messages for Efficiency
MCP lets you batch multiple messages into one array. Here’s a client sending a request and a notification together:
[
{
"jsonrpc": "2.0",
"id": "102",
"method": "fetchData",
"params": { "query": "recent_logs" }
},
{
"jsonrpc": "2.0",
"method": "logEvent",
"params": { "event": "Batch sent" }
}
]
- Server Requirement: Must handle batches if received.
- Client Option: Sending batches is optional but supported.
Example Use: Cuts down network trips. The server processes "fetchData" and logs the event in one go.
Transports: How Messages Travel
MCP defines two standard transports—stdio and Streamable HTTP—plus room for custom ones. Let’s explore with examples.
Stdio Transport: Local Simplicity
The client launches the server as a subprocess, using stdin/stdout for messaging:
- Client → Server: Writes to stdin.
- Server → Client: Writes to stdout.
- Logs: Server can write to stderr.
| Direction | Channel | Example Content |
|---|---|---|
| Client → Server | stdin | {"jsonrpc":"2.0","id":"1","method":"ping"}\n |
| Server → Client | stdout | {"jsonrpc":"2.0","id":"1","result":{}}\n |
| Server → Client | stderr | Log: Ping received |
- Messages end with newlines (
\n). - No embedded newlines allowed.
Example Use: A CLI tool spawns an MCP server, sends a ping via stdin, and reads the response from stdout.
Streamable HTTP Transport: Network Power
For networked setups, Streamable HTTP uses HTTP POST and optional Server-Sent Events (SSE):
-
Client POST: Sends a message to
/mcp. - Server Response: JSON or an SSE stream.
Example POST:
POST /mcp HTTP/1.1
Host: example.com
Accept: application/json, text/event-stream
Content-Type: application/json
{"jsonrpc":"2.0","id":"103","method":"streamData"}
Server might reply with SSE:
HTTP/1.1 200 OK
Content-Type: text/event-stream
data: {"jsonrpc":"2.0","id":"103","result":{"chunk":1}}
data: {"jsonrpc":"2.0","id":"103","result":{"chunk":2}}
- Accept Header: Signals client supports JSON or SSE.
Example Use: A web app streams real-time data from the server over SSE, keeping the UI updated.
Spec Link: MCP Transports
Lifecycle Management: Start, Run, Stop
MCP connections follow a clear lifecycle, tied to the base protocol:
-
Initialization:
- Client sends
initialize:
{ "jsonrpc": "2.0", "id": "1", "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": { "sampling": {} } } } - Client sends
-
Server responds:
{ "jsonrpc": "2.0", "id": "1", "result": { "protocolVersion": "2025-03-26", "capabilities": { "tools": {} } } } -
Client confirms with
initialized:
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
- Operation: Normal messaging flows.
- Shutdown: Client closes stdin (stdio) or HTTP connection ends.
Example Use: Ensures both sides sync on version and features before proceeding.
Spec Link: MCP Lifecycle Management
Authorization: Locking It Down
MCP’s optional auth framework shines with HTTP:
- OAuth 2.1: Supports flows like Authorization Code.
-
Header:
Authorization: Bearer <token>.
Example request with auth:
POST /mcp HTTP/1.1
Host: example.com
Authorization: Bearer abc123
Content-Type: application/json
{"jsonrpc":"2.0","id":"104","method":"secureTask"}
- Stdio skips this, using environment creds.
- Custom auth? Go for it! Join the GitHub Discussions to brainstorm.
Example Use: A client accesses a restricted server endpoint with a token.
Spec Link: MCP Authorization
Schema: The Spec’s Source
The protocol’s defined in a TypeScript schema—the ultimate reference. A JSON Schema is auto-generated for tools. ItThe MCP base protocol is developer-friendly:
- Lightweight: JSON-RPC 2.0 keeps it simple.
- Flexible: Stdio or HTTP, your choice.
- Modular: Only use what you need.
Try it out! Spin up a server with the official examples, send some requests, and see it in action.
What’s your next project that could use this? Share it in the comments!
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*
Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.
⭐ Star it on GitHub:
HexmosTech
/
git-lrc
Free, Unlimited AI Code Reviews That Run on Commit
AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.
See It In Action
See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements
git-lrc-intro-60s.mp4
Why
- 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
- 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
- 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
- 🔗 Why git? Git is universal. Every editor, every IDE, every AI…
Top comments (1)
data: {"jsonrpc":"2.0","id":"103","result":{"chunk":1}}
data: {"jsonrpc":"2.0","id":"103","result":{"chunk":2}}
This is not supported as per the protocol.