Configuration for a single MCP server.
| 38 | |
| 39 | |
| 40 | class ServerConfig(BaseModel): |
| 41 | """Configuration for a single MCP server.""" |
| 42 | |
| 43 | name: str |
| 44 | command: str | None = None |
| 45 | args: list[str] = Field(default_factory=list) |
| 46 | env: dict[str, str] = Field(default_factory=dict) |
| 47 | url: str | None = None # For HTTP/SSE servers |
| 48 | headers: dict[str, str] | None = None # HTTP headers (e.g., Authorization) |
| 49 | oauth: OAuthConfig | None = None # OAuth configuration |
| 50 | disabled: bool = False |
| 51 | |
| 52 | model_config = {"frozen": False, "arbitrary_types_allowed": True} |
| 53 | |
| 54 | @property |
| 55 | def transport(self) -> TransportType: |
| 56 | """Determine transport type from config.""" |
| 57 | if self.url: |
| 58 | return TransportType.HTTP |
| 59 | elif self.command: |
| 60 | return TransportType.STDIO |
| 61 | else: |
| 62 | # Return UNKNOWN when neither command nor url is provided |
| 63 | return TransportType.UNKNOWN |
| 64 | |
| 65 | @classmethod |
| 66 | def from_dict(cls, name: str, data: dict[str, Any]) -> "ServerConfig": |
| 67 | """Create from dictionary format with environment variable handling. |
| 68 | |
| 69 | Uses ServerConfigInput Pydantic model for validation instead of manual .get() calls. |
| 70 | """ |
| 71 | from mcp_cli.config.server_models import ServerConfigInput |
| 72 | |
| 73 | # Parse using Pydantic model (validates and provides defaults) |
| 74 | input_model = ServerConfigInput.model_validate(data) |
| 75 | |
| 76 | # Get env and ensure PATH is inherited |
| 77 | env = input_model.env.copy() |
| 78 | if "PATH" not in env: |
| 79 | env["PATH"] = os.environ.get("PATH", "") |
| 80 | |
| 81 | # Parse OAuth config if present |
| 82 | oauth = None |
| 83 | if input_model.oauth: |
| 84 | if isinstance(input_model.oauth, dict): |
| 85 | oauth = OAuthConfig.model_validate(input_model.oauth) |
| 86 | else: |
| 87 | oauth = input_model.oauth |
| 88 | |
| 89 | return cls( |
| 90 | name=name, |
| 91 | command=input_model.command, |
| 92 | args=input_model.args, |
| 93 | env=env, |
| 94 | url=input_model.url, |
| 95 | headers=input_model.headers, |
| 96 | oauth=oauth, |
| 97 | disabled=input_model.disabled, |
no outgoing calls