gamecode_mcp2/
protocol.rs

1// Minimal protocol definitions - only what MCP requires, nothing more.
2// All types are explicit with no hidden behavior.
3
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7// JSON-RPC 2.0 base types - standard protocol, no extensions
8#[derive(Debug, Serialize, Deserialize)]
9pub struct JsonRpcRequest {
10    pub jsonrpc: String,
11    pub id: Value,
12    pub method: String,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub params: Option<Value>,
15}
16
17#[derive(Debug, Serialize, Deserialize)]
18pub struct JsonRpcResponse {
19    pub jsonrpc: String,
20    pub id: Value,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub result: Option<Value>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub error: Option<JsonRpcError>,
25}
26
27#[derive(Debug, Serialize, Deserialize)]
28pub struct JsonRpcError {
29    pub code: i32,
30    pub message: String,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub data: Option<Value>,
33}
34
35#[derive(Debug, Serialize, Deserialize)]
36pub struct JsonRpcNotification {
37    pub jsonrpc: String,
38    pub method: String,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub params: Option<Value>,
41}
42
43// MCP protocol types - minimal surface area for LLM interaction
44#[derive(Debug, Serialize, Deserialize)]
45pub struct InitializeParams {
46    #[serde(rename = "protocolVersion")]
47    pub protocol_version: String,
48    pub capabilities: ClientCapabilities,
49    #[serde(rename = "clientInfo")]
50    pub client_info: ClientInfo,
51}
52
53#[derive(Debug, Serialize, Deserialize)]
54pub struct ClientCapabilities {
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub tools: Option<ToolsCapability>,
57}
58
59#[derive(Debug, Serialize, Deserialize)]
60pub struct ToolsCapability {}
61
62#[derive(Debug, Serialize, Deserialize)]
63pub struct ClientInfo {
64    pub name: String,
65    pub version: String,
66}
67
68#[derive(Debug, Serialize, Deserialize)]
69pub struct InitializeResult {
70    #[serde(rename = "protocolVersion")]
71    pub protocol_version: String,
72    pub capabilities: ServerCapabilities,
73    #[serde(rename = "serverInfo")]
74    pub server_info: ServerInfo,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub instructions: Option<String>,
77}
78
79#[derive(Debug, Serialize, Deserialize)]
80pub struct ServerCapabilities {
81    pub tools: ToolsCapability,
82}
83
84#[derive(Debug, Serialize, Deserialize)]
85pub struct ServerInfo {
86    pub name: String,
87    pub version: String,
88}
89
90// Tool schema is explicit - LLM sees exactly what we define
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct Tool {
93    pub name: String,
94    pub description: String,
95    #[serde(rename = "inputSchema")]
96    pub input_schema: Value,
97}
98
99#[derive(Debug, Serialize, Deserialize)]
100pub struct ListToolsResult {
101    pub tools: Vec<Tool>,
102}
103
104#[derive(Debug, Serialize, Deserialize)]
105pub struct CallToolParams {
106    pub name: String,
107    pub arguments: Value,
108}
109
110#[derive(Debug, Serialize, Deserialize)]
111pub struct CallToolResult {
112    pub content: Vec<ContentBlock>,
113    #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
114    pub is_error: Option<bool>,
115}
116
117#[derive(Debug, Serialize, Deserialize)]
118#[serde(tag = "type")]
119pub enum ContentBlock {
120    #[serde(rename = "text")]
121    Text { text: String },
122}
123
124// Standard JSON-RPC error codes - no custom extensions
125pub const PARSE_ERROR: i32 = -32700;
126pub const INVALID_REQUEST: i32 = -32600;
127pub const METHOD_NOT_FOUND: i32 = -32601;
128pub const INVALID_PARAMS: i32 = -32602;