agpm_cli/mcp/models.rs
1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5/// Settings structure for `.claude/settings.local.json`.
6/// This represents the complete settings file that may contain various configurations.
7#[derive(Debug, Default, Serialize, Deserialize)]
8pub struct ClaudeSettings {
9 /// Map of server names to their configurations
10 #[serde(rename = "mcpServers", skip_serializing_if = "Option::is_none")]
11 pub mcp_servers: Option<HashMap<String, McpServerConfig>>,
12
13 /// Hook configurations for event-based automation
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub hooks: Option<Value>,
16
17 /// Permissions configuration
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub permissions: Option<Value>,
20
21 /// Other settings preserved from the original file
22 #[serde(flatten)]
23 pub other: HashMap<String, Value>,
24}
25
26/// The main MCP configuration file structure for `.mcp.json`.
27///
28/// This represents the complete MCP configuration file that Claude Code reads
29/// to connect to MCP servers. The file may contain both AGPM-managed and
30/// user-managed server configurations.
31#[derive(Debug, Default, Serialize, Deserialize)]
32pub struct McpConfig {
33 /// Map of server names to their configurations
34 #[serde(rename = "mcpServers")]
35 pub mcp_servers: HashMap<String, McpServerConfig>,
36}
37
38/// Individual MCP server configuration.
39///
40/// This structure represents a single MCP server entry in the `.mcp.json` file.
41/// It supports both command-based and HTTP transport configurations.
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
43pub struct McpServerConfig {
44 /// The command to execute to start the server (command-based servers)
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub command: Option<String>,
47
48 /// Arguments to pass to the command (command-based servers)
49 #[serde(default, skip_serializing_if = "Vec::is_empty")]
50 pub args: Vec<String>,
51
52 /// Environment variables to set when running the server (command-based servers)
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub env: Option<HashMap<String, Value>>,
55
56 /// Transport type (HTTP-based servers) - Claude Code uses "type" field
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub r#type: Option<String>,
59
60 /// Server URL (HTTP-based servers)
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub url: Option<String>,
63
64 /// HTTP headers (HTTP-based servers)
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub headers: Option<HashMap<String, Value>>,
67
68 /// AGPM management metadata (only present for AGPM-managed servers)
69 #[serde(rename = "_agpm", skip_serializing_if = "Option::is_none")]
70 pub agpm_metadata: Option<AgpmMetadata>,
71}
72
73/// AGPM management metadata for tracking managed servers.
74///
75/// This metadata is added to server configurations that are managed by AGPM,
76/// allowing us to distinguish between AGPM-managed and user-managed servers.
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
78pub struct AgpmMetadata {
79 /// Indicates this server is managed by AGPM
80 pub managed: bool,
81
82 /// Source repository
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub source: Option<String>,
85
86 /// Version or git reference
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub version: Option<String>,
89
90 /// Timestamp when the server was installed/updated
91 pub installed_at: String,
92
93 /// Original manifest dependency name
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub dependency_name: Option<String>,
96}