> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plugged.in/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Protocol Compliance

> Technical details of how Plugged.in MCP Proxy implements the Model Context Protocol specification.

# MCP Protocol Compliance

The Plugged.in MCP Proxy is **100% compliant** with the [Model Context Protocol specification](https://spec.modelcontextprotocol.io/). This document outlines the technical implementation details, protocol requirements, and validation testing.

<Info>
  As of version 1.10.6, the proxy passes all 84+ protocol compliance tests covering CORS, headers, version negotiation, error codes, and transport mechanisms.
</Info>

## Streamable HTTP Transport

The proxy implements the MCP Streamable HTTP transport with full spec compliance:

### HTTP Headers

| Header                 | Direction     | Format             | Purpose                                   |
| ---------------------- | ------------- | ------------------ | ----------------------------------------- |
| `Mcp-Session-Id`       | Bidirectional | Title-Case         | Session identification and management     |
| `Mcp-Protocol-Version` | Bidirectional | Title-Case         | Protocol version negotiation (2024-11-05) |
| `Authorization`        | Request       | `Bearer <token>`   | Optional API authentication               |
| `Content-Type`         | Bidirectional | `application/json` | JSON-RPC 2.0 message format               |

**Header Casing Rules:**

* Custom headers use Title-Case format per MCP spec: `Mcp-Session-Id`, not `mcp-session-id`
* Server accepts headers with any casing in requests (case-insensitive)
* Server always responds with correct Title-Case format
* All custom headers are exposed via `Access-Control-Expose-Headers` for JavaScript clients

### Protocol Version Validation

```typescript theme={null}
// Current supported version
MCP_PROTOCOL_VERSION = '2024-11-05'
```

**Validation behavior:**

* Protocol version header is **optional** in requests
* If provided, server validates against supported version (2024-11-05)
* Unsupported versions return JSON-RPC error `-32600` (Invalid Request)
* Server always includes `Mcp-Protocol-Version: 2024-11-05` in responses
* Header casing is normalized (server accepts any case, returns Title-Case)

## CORS Configuration

Full CORS support for web-based MCP clients:

```http theme={null}
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version
Access-Control-Expose-Headers: Mcp-Session-Id, Mcp-Protocol-Version
```

**CORS Features:**

* Preflight OPTIONS requests handled on all endpoints
* Custom MCP headers exposed to JavaScript clients
* Consistent CORS headers across `/mcp`, `/health`, and `/.well-known` endpoints

## JSON-RPC 2.0 Error Codes

The proxy uses standardized error codes per JSON-RPC 2.0 specification:

| Code     | Name              | When Used                                        |
| -------- | ----------------- | ------------------------------------------------ |
| `-32600` | Invalid Request   | Malformed request, unsupported protocol version  |
| `-32601` | Method Not Found  | HTTP method not allowed (e.g., PUT on /mcp)      |
| `-32603` | Internal Error    | Server-side exception, transport failure         |
| `-32001` | Unauthorized      | Authentication failure (invalid/missing API key) |
| `-32000` | Application Error | Session not found, business logic errors         |

**Error Response Format:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "HTTP method PUT not allowed"
  },
  "id": null
}
```

## Supported HTTP Methods

| Method    | Endpoint                  | Purpose                     | Session Required               |
| --------- | ------------------------- | --------------------------- | ------------------------------ |
| `POST`    | `/mcp`, `/`               | JSON-RPC requests           | Optional (created if missing)  |
| `GET`     | `/mcp`, `/`               | Server-Sent Events (SSE)    | Optional                       |
| `DELETE`  | `/mcp`, `/`               | Session termination         | Optional (graceful if missing) |
| `OPTIONS` | All                       | CORS preflight              | No                             |
| `GET`     | `/health`                 | Health check                | No                             |
| `GET`     | `/.well-known/mcp-config` | Server discovery (Smithery) | No                             |

**Request Handling:**

* `POST` requests receive parsed JSON body via Express middleware
* `GET` requests (SSE) receive `undefined` body (no request body expected)
* `DELETE` requests gracefully handle missing sessions (200 OK response)
* Unsupported methods return `-32601` error

## Session Management

The proxy supports both stateful (session-based) and stateless operation modes:

### Stateful Mode (Default)

```bash theme={null}
# Session reuse enabled
npx @pluggedin/pluggedin-mcp-proxy --transport streamable-http
```

**Behavior:**

* Server generates or reuses session ID from `Mcp-Session-Id` header
* Sessions stored in memory map: `Map<sessionId, StreamableHTTPServerTransport>`
* Same session ID reuses existing transport (performance optimization)
* DELETE request terminates session and removes from map
* Missing session ID in DELETE returns 200 OK (idempotent)

### Stateless Mode

```bash theme={null}
# Fresh transport per request
npx @pluggedin/pluggedin-mcp-proxy --transport streamable-http --stateless
```

**Behavior:**

* New transport created for every request
* No session persistence between requests
* Session headers ignored
* DELETE always returns success
* Ideal for serverless deployments (AWS Lambda, Cloudflare Workers)

## Authentication

Optional Bearer token authentication for tool/resource operations:

```bash theme={null}
# Enable authentication requirement
--require-api-auth
```

**Authentication Rules:**

* **Lazy authentication**: Only required for tool/resource calls
* **Discovery exempt**: `tools/list`, `resources/list`, `prompts/list` work without auth
* **Header format**: `Authorization: Bearer <PLUGGEDIN_API_KEY>`
* **Error handling**: Missing/invalid tokens return `-32001` (Unauthorized)
* **Malformed headers**: Non-Bearer format rejected with `-32001`

**Authenticated Methods:**

* `tools/call`
* `resources/read`
* Any method starting with `tools/` or `resources/`

**Unauthenticated Methods (always allowed):**

* `initialize`
* `tools/list`
* `resources/list`
* `prompts/list`
* Health checks

## Architecture & Code Organization

The proxy implementation follows clean architecture principles:

### Core Files

**`src/constants.ts`** - Protocol constants

```typescript theme={null}
export const MCP_PROTOCOL_VERSION = '2024-11-05';
export const MCP_SESSION_ID_HEADER = 'Mcp-Session-Id';
export const MCP_PROTOCOL_VERSION_HEADER = 'Mcp-Protocol-Version';
export const JSON_RPC_ERROR_CODES = {
  INVALID_REQUEST: -32600,
  METHOD_NOT_FOUND: -32601,
  INTERNAL_ERROR: -32603,
  UNAUTHORIZED: -32001,
  APPLICATION_ERROR: -32000,
};
```

**`src/middleware.ts`** - Reusable middleware

* `corsMiddleware` - CORS header management
* `versionMiddleware` - Protocol version validation
* `acceptMiddleware` - Accept header normalization
* `createAuthMiddleware()` - Authentication factory
* `resolveTransport()` - Session/transport resolution

**`src/streamable-http.ts`** - HTTP server implementation

* Express-based HTTP server
* Middleware composition
* Request routing
* Session management

### Port Validation

```typescript theme={null}
// src/server.ts
let port = parseInt(config.PORT || String(DEFAULT_PORT), 10);
if (isNaN(port) || port < MIN_PORT || port > MAX_PORT) {
  port = DEFAULT_PORT; // Falls back to 12006
}
```

**Validation Rules:**

* Must be valid integer
* Range: 1-65535
* Invalid values default to 12006
* Prevents port conflicts and security issues

## Well-Known Discovery

MCP server discovery for Smithery and other platforms:

```json theme={null}
// .well-known/mcp-config
{
  "schemaVersion": "1.0",
  "name": "pluggedin-mcp-proxy",
  "version": "1.10.5",
  "description": "Plugged.in MCP Proxy - Unified interface for multiple MCP servers",
  "capabilities": {
    "tools": true,
    "resources": true,
    "prompts": true
  }
}
```

**Endpoints:**

* `/.well-known/mcp-config` - Standard location
* `/mcp/.well-known/mcp-config` - Reverse proxy support

**Headers:**

* `Content-Type: application/json` automatically set
* CORS headers included for web access

## Testing & Validation

The proxy includes comprehensive test coverage:

### Test Categories

**CORS Headers (4 tests)**

* ✅ Access-Control-Expose-Headers present
* ✅ MCP headers allowed in requests
* ✅ OPTIONS preflight on `/mcp`
* ✅ OPTIONS preflight on `/health`

**Protocol Version (5 tests)**

* ✅ Requests without version accepted
* ✅ Valid version (2024-11-05) accepted
* ✅ Invalid version rejected with -32600
* ✅ Version included in all responses
* ✅ Header casing normalized (accepts any case)

**Session Headers (2 tests)**

* ✅ Response uses Title-Case (Mcp-Session-Id)
* ✅ Request accepts any casing

**Error Codes (4 tests)**

* ✅ -32601 for unsupported HTTP methods
* ✅ -32001 for missing Authorization
* ✅ -32001 for malformed Authorization
* ✅ -32603 for internal errors

**Session Management (3 tests)**

* ✅ Session creation and reuse
* ✅ Session deletion
* ✅ Graceful handling of missing sessions

### Running Tests

```bash theme={null}
# Run all tests
npm test

# Watch mode for development
npm run test:watch

# Generate coverage report
npm run test:coverage

# Interactive UI
npm run test:ui
```

**Current Status:**

* ✅ 84 tests passing
* ✅ 100% protocol compliance
* ✅ Zero deprecation warnings

## Performance Characteristics

**Stateful Mode:**

* Session lookup: O(1) via Map
* Memory: \~1KB per active session
* Recommended: Desktop clients, persistent connections

**Stateless Mode:**

* Per-request overhead: \~5ms (transport creation)
* Memory: No session storage
* Recommended: Serverless, load-balanced deployments

**Middleware Performance:**

* CORS: \<0.1ms (header setting)
* Version validation: \<0.1ms (string comparison)
* Accept normalization: \<0.1ms (array operations)
* Authentication: \<0.5ms (header parsing + validation)

## Deployment Considerations

### Production Checklist

* [ ] Set `REQUIRE_API_AUTH=true` for remote deployments
* [ ] Use `--stateless` for serverless environments
* [ ] Configure reverse proxy to preserve headers
* [ ] Set up health check monitoring (`/health`)
* [ ] Enable HTTPS termination (proxy supports HTTP only)
* [ ] Consider rate limiting at reverse proxy level

### Smithery Cloud

Smithery deployment uses the `src/server.ts` entry point:

```typescript theme={null}
export async function createServer(config: z.infer<typeof configSchema>) {
  // Validates PORT, starts HTTP server, returns cleanup function
}
```

**Configuration via Smithery UI:**

* `PLUGGEDIN_API_KEY` - Your API key
* `PLUGGEDIN_API_BASE_URL` - API endpoint (default: [https://plugged.in](https://plugged.in))
* `PORT` - Server port (default: 12006)
* `REQUIRE_API_AUTH` - Enable auth (default: false)

### Docker Deployment

```dockerfile theme={null}
# MCP-compliant HTTP transport
EXPOSE 12006
ENV PORT=12006
CMD ["node", "dist/index.js", "--transport", "streamable-http", "--port", "12006"]
```

## Breaking Changes Policy

The proxy follows semantic versioning:

* **Major version**: Breaking protocol changes
* **Minor version**: New features, backward compatible
* **Patch version**: Bug fixes, no API changes

**Current Version:** 1.10.6

* ✅ Fully backward compatible
* ✅ No breaking changes since 1.0.0
* ✅ Protocol version validation is optional

## References

* **MCP Specification**: [https://spec.modelcontextprotocol.io/](https://spec.modelcontextprotocol.io/)
* **JSON-RPC 2.0**: [https://www.jsonrpc.org/specification](https://www.jsonrpc.org/specification)
* **CORS Spec**: [https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
* **Smithery Docs**: [https://smithery.ai/docs](https://smithery.ai/docs)
* **Source Code**: [https://github.com/VeriTeknik/pluggedin-mcp](https://github.com/VeriTeknik/pluggedin-mcp)

## Changelog

### v1.10.6 (Latest)

* ✅ Added `Access-Control-Expose-Headers` for MCP compliance
* ✅ Implemented protocol version validation (2024-11-05)
* ✅ Fixed header casing to Title-Case per spec
* ✅ Standardized JSON-RPC error codes
* ✅ Added 13 new protocol compliance tests
* ✅ Extracted constants and middleware for maintainability
* ✅ Improved PORT validation with range checking
* ✅ All 84 tests passing

### v1.10.5

* Previous stable release
* Basic Streamable HTTP support

***

**Need Help?** Check the [Troubleshooting Guide](/troubleshooting) or [Installation Guide](/mcp-proxy/installation) for common issues and solutions.
