mcp-acp 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_acp/__init__.py +3 -0
- mcp_acp/client.py +1885 -0
- mcp_acp/formatters.py +387 -0
- mcp_acp/server.py +842 -0
- mcp_acp/settings.py +226 -0
- mcp_acp-0.1.0.dist-info/METADATA +446 -0
- mcp_acp-0.1.0.dist-info/RECORD +10 -0
- mcp_acp-0.1.0.dist-info/WHEEL +5 -0
- mcp_acp-0.1.0.dist-info/entry_points.txt +2 -0
- mcp_acp-0.1.0.dist-info/top_level.txt +1 -0
mcp_acp/settings.py
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Configuration settings for MCP-ACP server.
|
|
2
|
+
|
|
3
|
+
Uses Pydantic BaseSettings for type-safe configuration with validation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
from pydantic import Field, field_validator
|
|
10
|
+
from pydantic_settings import BaseSettings
|
|
11
|
+
|
|
12
|
+
from utils.pylogger import get_python_logger
|
|
13
|
+
|
|
14
|
+
logger = get_python_logger()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ClusterConfig(BaseSettings):
|
|
18
|
+
"""Configuration for a single OpenShift cluster.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
server: OpenShift API server URL
|
|
22
|
+
default_project: Default project/namespace to use
|
|
23
|
+
description: Optional human-readable description
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
server: str = Field(
|
|
27
|
+
...,
|
|
28
|
+
description="OpenShift API server URL",
|
|
29
|
+
json_schema_extra={"example": "https://api.cluster.example.com:6443"},
|
|
30
|
+
)
|
|
31
|
+
default_project: str = Field(
|
|
32
|
+
...,
|
|
33
|
+
description="Default project/namespace for operations",
|
|
34
|
+
json_schema_extra={"example": "my-workspace"},
|
|
35
|
+
)
|
|
36
|
+
description: str | None = Field(
|
|
37
|
+
default=None,
|
|
38
|
+
description="Human-readable cluster description",
|
|
39
|
+
json_schema_extra={"example": "Production cluster"},
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@field_validator("server")
|
|
43
|
+
@classmethod
|
|
44
|
+
def validate_server_url(cls, v: str) -> str:
|
|
45
|
+
"""Validate server URL format."""
|
|
46
|
+
if not v.startswith(("https://", "http://")):
|
|
47
|
+
raise ValueError("Server URL must start with https:// or http://")
|
|
48
|
+
return v
|
|
49
|
+
|
|
50
|
+
@field_validator("default_project")
|
|
51
|
+
@classmethod
|
|
52
|
+
def validate_project_name(cls, v: str) -> str:
|
|
53
|
+
"""Validate project name follows DNS-1123 rules."""
|
|
54
|
+
if not v:
|
|
55
|
+
raise ValueError("default_project cannot be empty")
|
|
56
|
+
if len(v) > 63:
|
|
57
|
+
raise ValueError("default_project must be 63 characters or less")
|
|
58
|
+
if not v.replace("-", "").replace("_", "").isalnum():
|
|
59
|
+
raise ValueError("default_project must contain only alphanumeric characters, hyphens, or underscores")
|
|
60
|
+
return v
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ClustersConfig(BaseSettings):
|
|
64
|
+
"""Configuration for all OpenShift clusters.
|
|
65
|
+
|
|
66
|
+
Attributes:
|
|
67
|
+
clusters: Dictionary of cluster configurations
|
|
68
|
+
default_cluster: Name of the default cluster to use
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
clusters: dict[str, ClusterConfig] = Field(
|
|
72
|
+
default_factory=dict,
|
|
73
|
+
description="Map of cluster names to configurations",
|
|
74
|
+
)
|
|
75
|
+
default_cluster: str | None = Field(
|
|
76
|
+
default=None,
|
|
77
|
+
description="Name of the default cluster",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
@field_validator("default_cluster")
|
|
81
|
+
@classmethod
|
|
82
|
+
def validate_default_cluster(cls, v: str | None, info) -> str | None:
|
|
83
|
+
"""Ensure default_cluster exists in clusters."""
|
|
84
|
+
if v is not None:
|
|
85
|
+
clusters = info.data.get("clusters", {})
|
|
86
|
+
if v not in clusters:
|
|
87
|
+
raise ValueError(f"default_cluster '{v}' not found in clusters: {list(clusters.keys())}")
|
|
88
|
+
return v
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def from_yaml(cls, path: Path) -> "ClustersConfig":
|
|
92
|
+
"""Load configuration from YAML file.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
path: Path to clusters.yaml file
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Validated ClustersConfig instance
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
FileNotFoundError: If config file doesn't exist
|
|
102
|
+
ValueError: If config is invalid
|
|
103
|
+
"""
|
|
104
|
+
if not path.exists():
|
|
105
|
+
raise FileNotFoundError(f"Cluster configuration not found: {path}")
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
with open(path) as f:
|
|
109
|
+
data = yaml.safe_load(f)
|
|
110
|
+
|
|
111
|
+
if not data:
|
|
112
|
+
raise ValueError("Cluster configuration is empty")
|
|
113
|
+
|
|
114
|
+
# Convert cluster configs to ClusterConfig objects
|
|
115
|
+
clusters_data = data.get("clusters", {})
|
|
116
|
+
clusters = {}
|
|
117
|
+
for name, config in clusters_data.items():
|
|
118
|
+
try:
|
|
119
|
+
clusters[name] = ClusterConfig(**config)
|
|
120
|
+
except Exception as e:
|
|
121
|
+
logger.error(
|
|
122
|
+
"cluster_config_invalid",
|
|
123
|
+
cluster=name,
|
|
124
|
+
error=str(e),
|
|
125
|
+
)
|
|
126
|
+
raise ValueError(f"Invalid config for cluster '{name}': {e}") from e
|
|
127
|
+
|
|
128
|
+
return cls(
|
|
129
|
+
clusters=clusters,
|
|
130
|
+
default_cluster=data.get("default_cluster"),
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
except yaml.YAMLError as e:
|
|
134
|
+
logger.error("yaml_parse_error", path=str(path), error=str(e))
|
|
135
|
+
raise ValueError(f"Failed to parse YAML: {e}") from e
|
|
136
|
+
except Exception as e:
|
|
137
|
+
logger.error("config_load_error", path=str(path), error=str(e))
|
|
138
|
+
raise
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class Settings(BaseSettings):
|
|
142
|
+
"""Global settings for MCP-ACP server.
|
|
143
|
+
|
|
144
|
+
Attributes:
|
|
145
|
+
config_path: Path to clusters.yaml configuration file
|
|
146
|
+
log_level: Logging level
|
|
147
|
+
timeout_default: Default timeout for oc commands (seconds)
|
|
148
|
+
max_log_lines: Maximum log lines to retrieve
|
|
149
|
+
max_file_size: Maximum file size for exports (bytes)
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
config_path: Path = Field(
|
|
153
|
+
default=Path.home() / ".config" / "acp" / "clusters.yaml",
|
|
154
|
+
description="Path to cluster configuration file",
|
|
155
|
+
)
|
|
156
|
+
log_level: str = Field(
|
|
157
|
+
default="INFO",
|
|
158
|
+
description="Logging level",
|
|
159
|
+
json_schema_extra={"enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]},
|
|
160
|
+
)
|
|
161
|
+
timeout_default: int = Field(
|
|
162
|
+
default=300,
|
|
163
|
+
ge=1,
|
|
164
|
+
le=3600,
|
|
165
|
+
description="Default timeout for oc commands (seconds)",
|
|
166
|
+
)
|
|
167
|
+
max_log_lines: int = Field(
|
|
168
|
+
default=10000,
|
|
169
|
+
ge=1,
|
|
170
|
+
le=100000,
|
|
171
|
+
description="Maximum log lines to retrieve",
|
|
172
|
+
)
|
|
173
|
+
max_file_size: int = Field(
|
|
174
|
+
default=10 * 1024 * 1024, # 10MB
|
|
175
|
+
ge=1024,
|
|
176
|
+
le=100 * 1024 * 1024, # 100MB
|
|
177
|
+
description="Maximum file size for exports (bytes)",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
@field_validator("log_level")
|
|
181
|
+
@classmethod
|
|
182
|
+
def validate_log_level(cls, v: str) -> str:
|
|
183
|
+
"""Validate log level."""
|
|
184
|
+
valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
185
|
+
v_upper = v.upper()
|
|
186
|
+
if v_upper not in valid_levels:
|
|
187
|
+
raise ValueError(f"log_level must be one of {valid_levels}")
|
|
188
|
+
return v_upper
|
|
189
|
+
|
|
190
|
+
class Config:
|
|
191
|
+
"""Pydantic config."""
|
|
192
|
+
|
|
193
|
+
env_prefix = "MCP_ACP_"
|
|
194
|
+
case_sensitive = False
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def load_settings() -> Settings:
|
|
198
|
+
"""Load and validate global settings.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
Validated Settings instance
|
|
202
|
+
"""
|
|
203
|
+
return Settings()
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def load_clusters_config(settings: Settings | None = None) -> ClustersConfig:
|
|
207
|
+
"""Load and validate cluster configuration.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
settings: Optional Settings instance. If not provided, loads default settings.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
Validated ClustersConfig instance
|
|
214
|
+
|
|
215
|
+
Raises:
|
|
216
|
+
FileNotFoundError: If config file doesn't exist
|
|
217
|
+
ValueError: If config is invalid
|
|
218
|
+
"""
|
|
219
|
+
if settings is None:
|
|
220
|
+
settings = load_settings()
|
|
221
|
+
|
|
222
|
+
return ClustersConfig.from_yaml(settings.config_path)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# Global settings instance
|
|
226
|
+
settings = load_settings()
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-acp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for Ambient Code Platform (ACP) session management on OpenShift - list, delete, debug, and manage AgenticSession resources
|
|
5
|
+
Author: Ambient Code Team
|
|
6
|
+
Keywords: mcp,acp,ambient,ambient-code-platform,ambient-container-platform,openshift,kubernetes,agentic-session,agenticsession
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Python: >=3.12
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: mcp>=1.0.0
|
|
15
|
+
Requires-Dist: pydantic>=2.0.0
|
|
16
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
17
|
+
Requires-Dist: structlog>=25.0.0
|
|
18
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
19
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
20
|
+
Requires-Dist: pyyaml>=6.0
|
|
21
|
+
Requires-Dist: python-dateutil>=2.8.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.12.0; extra == "dev"
|
|
27
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pre-commit>=4.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: bandit>=1.7.0; extra == "dev"
|
|
30
|
+
|
|
31
|
+
# MCP ACP Server
|
|
32
|
+
|
|
33
|
+
A Model Context Protocol (MCP) server for managing Ambient Code Platform (ACP) sessions on OpenShift/Kubernetes clusters.
|
|
34
|
+
|
|
35
|
+
[Based on template-agent](https://github.com/redhat-data-and-ai/template-agent)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
Get started in 5 minutes:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Install
|
|
45
|
+
git clone https://github.com/ambient-code/mcp
|
|
46
|
+
claude mcp add mcp-acp -t stdio mcp/dist/mcp_acp-*.whl
|
|
47
|
+
|
|
48
|
+
# Configure
|
|
49
|
+
mkdir -p ~/.config/acp
|
|
50
|
+
cat > ~/.config/acp/clusters.yaml <<EOF
|
|
51
|
+
clusters:
|
|
52
|
+
my-cluster:
|
|
53
|
+
server: https://api.your-cluster.example.com:443
|
|
54
|
+
default_project: my-workspace
|
|
55
|
+
default_cluster: my-cluster
|
|
56
|
+
EOF
|
|
57
|
+
|
|
58
|
+
# Authenticate
|
|
59
|
+
oc login --server=https://api.your-cluster.example.com:443
|
|
60
|
+
|
|
61
|
+
# Add to Claude Desktop config
|
|
62
|
+
{
|
|
63
|
+
"mcpServers": {
|
|
64
|
+
"acp": {
|
|
65
|
+
"command": "mcp-acp"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**First Command**: `List my ambient sessions that are older than a week`
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Overview
|
|
76
|
+
|
|
77
|
+
This MCP server provides 27 comprehensive tools for interacting with the Ambient Code Platform, enabling:
|
|
78
|
+
|
|
79
|
+
- **Session Management**: List, create, delete, restart, clone sessions
|
|
80
|
+
- **Label Management**: Tag and organize sessions with custom labels
|
|
81
|
+
- **Bulk Operations**: Efficiently manage multiple sessions at once
|
|
82
|
+
- **Advanced Filtering**: Filter by status, age, display name, labels, and more
|
|
83
|
+
- **Debugging**: Retrieve logs, transcripts, and metrics
|
|
84
|
+
- **Cluster Management**: Multi-cluster support with easy switching
|
|
85
|
+
- **Safety First**: Dry-run mode on all mutating operations
|
|
86
|
+
|
|
87
|
+
**Security:** This server implements comprehensive security measures including input validation, command injection prevention, timeout controls, and resource limits. See [SECURITY.md](SECURITY.md) for details.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Features
|
|
92
|
+
|
|
93
|
+
### Session Management
|
|
94
|
+
|
|
95
|
+
- **acp_list_sessions**: Enhanced filtering by status, display name, age, labels, and sorting
|
|
96
|
+
- **acp_delete_session**: Delete sessions with dry-run preview
|
|
97
|
+
- **acp_restart_session**: Restart stopped sessions
|
|
98
|
+
- **acp_clone_session**: Clone existing session configurations
|
|
99
|
+
- **acp_create_session_from_template**: Create sessions from predefined templates
|
|
100
|
+
- **acp_update_session**: Update session metadata
|
|
101
|
+
|
|
102
|
+
### Label Management
|
|
103
|
+
|
|
104
|
+
- **acp_label_resource**: Add labels to sessions or other resources
|
|
105
|
+
- **acp_unlabel_resource**: Remove labels from resources
|
|
106
|
+
- **acp_bulk_label_resources**: Label multiple resources (max 3 with confirmation)
|
|
107
|
+
- **acp_bulk_unlabel_resources**: Remove labels from multiple resources
|
|
108
|
+
- **acp_list_sessions_by_label**: List sessions matching label selectors
|
|
109
|
+
|
|
110
|
+
### Bulk Operations
|
|
111
|
+
|
|
112
|
+
- **acp_bulk_delete_sessions**: Delete multiple sessions with confirmation
|
|
113
|
+
- **acp_bulk_stop_sessions**: Stop multiple running sessions with confirmation
|
|
114
|
+
- **acp_bulk_delete_sessions_by_label**: Delete sessions by label selector
|
|
115
|
+
- **acp_bulk_stop_sessions_by_label**: Stop sessions by label selector
|
|
116
|
+
- **acp_bulk_restart_sessions**: Restart multiple sessions (max 3)
|
|
117
|
+
- **acp_bulk_restart_sessions_by_label**: Restart sessions by label selector
|
|
118
|
+
|
|
119
|
+
### Debugging & Monitoring
|
|
120
|
+
|
|
121
|
+
- **acp_get_session_logs**: Retrieve container logs for debugging
|
|
122
|
+
- **acp_get_session_transcript**: Retrieve conversation history
|
|
123
|
+
- **acp_get_session_metrics**: Get usage statistics and analytics
|
|
124
|
+
- **acp_export_session**: Export session data for archival
|
|
125
|
+
|
|
126
|
+
### Cluster Management
|
|
127
|
+
|
|
128
|
+
- **acp_list_clusters**: List configured cluster aliases
|
|
129
|
+
- **acp_whoami**: Check authentication status
|
|
130
|
+
- **acp_login**: Web-based authentication flow
|
|
131
|
+
- **acp_switch_cluster**: Switch between configured clusters
|
|
132
|
+
- **acp_add_cluster**: Add new cluster configurations
|
|
133
|
+
|
|
134
|
+
### Workflows
|
|
135
|
+
|
|
136
|
+
- **acp_list_workflows**: Discover available workflows
|
|
137
|
+
|
|
138
|
+
**Safety Features**:
|
|
139
|
+
|
|
140
|
+
- **Dry-Run Mode**: All mutating operations support a `dry_run` parameter for safe preview before executing
|
|
141
|
+
- **Bulk Operation Limits**: Maximum 3 items per bulk operation with confirmation requirement
|
|
142
|
+
- **Label Format**: `acp.ambient-code.ai/label-{key}={value}` for Kubernetes compatibility
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Installation
|
|
147
|
+
|
|
148
|
+
### From PyPI (when published)
|
|
149
|
+
|
|
150
|
+
### From Source
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
git clone https://github.com/ambient-code/mcp
|
|
154
|
+
pip install dist/mcp_acp-*.whl
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Requirements:**
|
|
158
|
+
|
|
159
|
+
- Python 3.10+
|
|
160
|
+
- OpenShift CLI (`oc`) installed and in PATH
|
|
161
|
+
- Access to an OpenShift cluster with ACP
|
|
162
|
+
|
|
163
|
+
See [QUICKSTART.md](QUICKSTART.md) for detailed installation instructions.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Configuration
|
|
168
|
+
|
|
169
|
+
### 1. Create Cluster Configuration
|
|
170
|
+
|
|
171
|
+
Create `~/.config/acp/clusters.yaml`:
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
clusters:
|
|
175
|
+
vteam-stage:
|
|
176
|
+
server: https://api.vteam-stage.xxxx.p3.openshiftapps.com:443
|
|
177
|
+
description: "V-Team Staging Environment"
|
|
178
|
+
default_project: jeder-workspace
|
|
179
|
+
|
|
180
|
+
vteam-prod:
|
|
181
|
+
server: https://api.vteam-prod.xxxx.p3.openshiftapps.com:443
|
|
182
|
+
description: "V-Team Production"
|
|
183
|
+
default_project: jeder-workspace
|
|
184
|
+
|
|
185
|
+
default_cluster: vteam-stage
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### 2. Configure MCP Client
|
|
189
|
+
|
|
190
|
+
For Claude Desktop, edit your configuration file:
|
|
191
|
+
|
|
192
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
193
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
194
|
+
**Linux**: `~/.config/claude/claude_desktop_config.json`
|
|
195
|
+
|
|
196
|
+
Add the ACP server:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"mcpServers": {
|
|
201
|
+
"acp": {
|
|
202
|
+
"command": "mcp-acp",
|
|
203
|
+
"args": [],
|
|
204
|
+
"env": {
|
|
205
|
+
"ACP_CLUSTER_CONFIG": "${HOME}/.config/acp/clusters.yaml"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 3. Authenticate with OpenShift
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
oc login --server=https://api.your-cluster.example.com:443
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
> **Note**: Direct OpenShift CLI authentication is required for testing until the frontend API is available (tracked in PR #558).
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Usage Examples
|
|
223
|
+
|
|
224
|
+
### List Sessions with Filtering
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
# List only running sessions
|
|
228
|
+
List running sessions in my-workspace
|
|
229
|
+
|
|
230
|
+
# List sessions older than 7 days
|
|
231
|
+
Show me sessions older than 7 days in my-workspace
|
|
232
|
+
|
|
233
|
+
# List sessions by label
|
|
234
|
+
List sessions with env=test and team=qa labels in my-workspace
|
|
235
|
+
|
|
236
|
+
# List sessions sorted by creation date
|
|
237
|
+
List sessions in my-workspace, sorted by creation date, limit 20
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Label Management
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
# Add labels to a session
|
|
244
|
+
Add env=test and team=qa labels to my-session in my-workspace
|
|
245
|
+
|
|
246
|
+
# List sessions by label
|
|
247
|
+
List sessions with env=test label in my-workspace
|
|
248
|
+
|
|
249
|
+
# Bulk delete sessions by label
|
|
250
|
+
Delete all sessions with env=test label in my-workspace (dry-run first)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Delete Session with Dry-Run
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
# Preview what would be deleted
|
|
257
|
+
Delete test-session from my-workspace in dry-run mode
|
|
258
|
+
|
|
259
|
+
# Actually delete
|
|
260
|
+
Delete test-session from my-workspace
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Bulk Operations
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
# Stop multiple sessions
|
|
267
|
+
Stop session-1, session-2, and session-3 in my-workspace
|
|
268
|
+
|
|
269
|
+
# Delete old sessions with dry-run
|
|
270
|
+
Delete old-session-1 and old-session-2 from my-workspace in dry-run mode
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Get Session Logs
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
# Get logs from runner container
|
|
277
|
+
Get logs from debug-session in my-workspace, runner container, last 100 lines
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
See [QUICKSTART.md](QUICKSTART.md) for detailed examples and workflow patterns.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Tool Reference
|
|
285
|
+
|
|
286
|
+
For complete API specifications, see [API_REFERENCE.md](API_REFERENCE.md).
|
|
287
|
+
|
|
288
|
+
### Quick Reference
|
|
289
|
+
|
|
290
|
+
| Category | Tool | Description |
|
|
291
|
+
|----------|------|-------------|
|
|
292
|
+
| **Session** | `acp_list_sessions` | List/filter sessions with advanced options |
|
|
293
|
+
| | `acp_delete_session` | Delete session with dry-run support |
|
|
294
|
+
| | `acp_restart_session` | Restart stopped sessions |
|
|
295
|
+
| | `acp_clone_session` | Clone session configuration |
|
|
296
|
+
| | `acp_update_session` | Update session metadata |
|
|
297
|
+
| **Labels** | `acp_label_resource` | Add labels to sessions |
|
|
298
|
+
| | `acp_unlabel_resource` | Remove labels from sessions |
|
|
299
|
+
| | `acp_list_sessions_by_label` | Find sessions by label |
|
|
300
|
+
| **Bulk Ops** | `acp_bulk_delete_sessions` | Delete multiple sessions (max 3) |
|
|
301
|
+
| | `acp_bulk_stop_sessions` | Stop multiple sessions (max 3) |
|
|
302
|
+
| | `acp_bulk_restart_sessions` | Restart multiple sessions (max 3) |
|
|
303
|
+
| | `acp_bulk_delete_sessions_by_label` | Delete sessions by label |
|
|
304
|
+
| **Debug** | `acp_get_session_logs` | Get container logs |
|
|
305
|
+
| | `acp_get_session_transcript` | Get conversation history |
|
|
306
|
+
| | `acp_get_session_metrics` | Get usage statistics |
|
|
307
|
+
| | `acp_export_session` | Export session data |
|
|
308
|
+
| **Cluster** | `acp_list_clusters` | List configured clusters |
|
|
309
|
+
| | `acp_whoami` | Check authentication status |
|
|
310
|
+
| | `acp_login` | Authenticate to cluster |
|
|
311
|
+
| | `acp_switch_cluster` | Switch cluster context |
|
|
312
|
+
| | `acp_add_cluster` | Add cluster to config |
|
|
313
|
+
| **Workflows** | `acp_list_workflows` | Discover available workflows |
|
|
314
|
+
| | `acp_create_session_from_template` | Create from template |
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Architecture
|
|
319
|
+
|
|
320
|
+
The server is built using:
|
|
321
|
+
|
|
322
|
+
- **MCP SDK**: Standard MCP protocol implementation
|
|
323
|
+
- **OpenShift CLI**: Underlying `oc` commands for ACP operations
|
|
324
|
+
- **Async I/O**: Non-blocking operations for performance
|
|
325
|
+
- **YAML Configuration**: Flexible cluster management
|
|
326
|
+
|
|
327
|
+
See [CLAUDE.md](CLAUDE.md#architecture-overview) for complete system design.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Security
|
|
332
|
+
|
|
333
|
+
This server implements defense-in-depth security:
|
|
334
|
+
|
|
335
|
+
- **Input Validation**: DNS-1123 format validation for all resource names
|
|
336
|
+
- **Command Injection Prevention**: Secure subprocess execution (never shell=True)
|
|
337
|
+
- **Resource Exhaustion Protection**: Timeouts and limits on all operations
|
|
338
|
+
- **Secure Temporary Files**: Random prefixes, 0600 permissions
|
|
339
|
+
- **Path Traversal Prevention**: Configuration and workflow file validation
|
|
340
|
+
- **Resource Type Whitelist**: Only agenticsession, pods, event resources
|
|
341
|
+
- **Sensitive Data Filtering**: Tokens/passwords removed from logs
|
|
342
|
+
|
|
343
|
+
See [SECURITY.md](SECURITY.md) for complete security documentation.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Development
|
|
348
|
+
|
|
349
|
+
### Running Tests
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Run all tests
|
|
353
|
+
pytest
|
|
354
|
+
|
|
355
|
+
# Run with coverage
|
|
356
|
+
pytest --cov=src/mcp_acp --cov-report=html
|
|
357
|
+
|
|
358
|
+
# Run security tests
|
|
359
|
+
pytest tests/test_security.py -v
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Code Quality
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# Format code
|
|
366
|
+
black src/ tests/
|
|
367
|
+
ruff check src/ tests/
|
|
368
|
+
|
|
369
|
+
# Type checking
|
|
370
|
+
mypy src/
|
|
371
|
+
|
|
372
|
+
# All checks
|
|
373
|
+
make check
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
See [CLAUDE.md](CLAUDE.md#development-commands) for contributing guidelines.
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Documentation
|
|
381
|
+
|
|
382
|
+
- **[QUICKSTART.md](QUICKSTART.md)** - Complete usage guide with examples
|
|
383
|
+
- **[API_REFERENCE.md](API_REFERENCE.md)** - Full API specifications for all 27 tools
|
|
384
|
+
- **[CLAUDE.md](CLAUDE.md)** - System architecture and design
|
|
385
|
+
- **[SECURITY.md](SECURITY.md)** - Security features and best practices
|
|
386
|
+
- **[CLAUDE.md](CLAUDE.md)** - Development and contributing guide
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Roadmap
|
|
391
|
+
|
|
392
|
+
Current implementation provides all planned features (19 tools). Future enhancements may include:
|
|
393
|
+
|
|
394
|
+
- **Rate Limiting**: Per-client request limits for HTTP exposure
|
|
395
|
+
- **Audit Logging**: Structured audit trail and SIEM integration
|
|
396
|
+
- **Enhanced Authentication**: OAuth2/OIDC support, MFA
|
|
397
|
+
- **Network Security**: mTLS for MCP transport, certificate pinning
|
|
398
|
+
- **Advanced Metrics**: Cost analysis, performance tracking
|
|
399
|
+
|
|
400
|
+
See the [GitHub issue tracker](https://github.com/ambient-code/mcp/issues) for planned features and community requests.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Contributing
|
|
405
|
+
|
|
406
|
+
Contributions are welcome! Please:
|
|
407
|
+
|
|
408
|
+
1. Fork the repository
|
|
409
|
+
2. Create a feature branch
|
|
410
|
+
3. Add tests for new functionality
|
|
411
|
+
4. Ensure all tests pass (`pytest`)
|
|
412
|
+
5. Ensure code quality checks pass (`make check`)
|
|
413
|
+
6. Submit a pull request
|
|
414
|
+
|
|
415
|
+
See [CLAUDE.md](CLAUDE.md#development-commands) for detailed guidelines.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## License
|
|
420
|
+
|
|
421
|
+
MIT License - See LICENSE file for details
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Support
|
|
426
|
+
|
|
427
|
+
For issues and feature requests, please use the [GitHub issue tracker](https://github.com/ambient-code/mcp/issues).
|
|
428
|
+
|
|
429
|
+
For usage questions, see:
|
|
430
|
+
|
|
431
|
+
- [QUICKSTART.md](QUICKSTART.md) - Complete usage guide
|
|
432
|
+
- [API_REFERENCE.md](API_REFERENCE.md) - API specifications
|
|
433
|
+
- [SECURITY.md](SECURITY.md) - Security features
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## Status
|
|
438
|
+
|
|
439
|
+
**Code**: ✅ Production-Ready
|
|
440
|
+
**Tests**: ✅ All Passing (13/13 security tests)
|
|
441
|
+
**Documentation**: ✅ Complete
|
|
442
|
+
**Security**: ✅ Hardened with defense-in-depth
|
|
443
|
+
**Tools**: ✅ 27 tools fully implemented
|
|
444
|
+
**Features**: ✅ Label management, bulk operations, advanced filtering
|
|
445
|
+
|
|
446
|
+
**Ready for production use** 🚀
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
mcp_acp/__init__.py,sha256=pHwpUKrVevjpRdx_yyClYPKVuP2fWqEMWSTIMjq3JIk,88
|
|
2
|
+
mcp_acp/client.py,sha256=u25Ih3w4nFyufva_IkNn3gb-p6k2QbHHbmp5SUyzskc,69100
|
|
3
|
+
mcp_acp/formatters.py,sha256=8lL5q9dH4jemDfDKAeRVPsbScVQkDkESK0RzMthOE3Q,13150
|
|
4
|
+
mcp_acp/server.py,sha256=2H44r7fDFXC8BasyyG0cy7-VdzzXG7LVMBwGUr4oAGA,30157
|
|
5
|
+
mcp_acp/settings.py,sha256=MVWyYmEzD6aOrWS3LITvUdNtcdyQzZuMCmlXFvZ2WSI,7017
|
|
6
|
+
mcp_acp-0.1.0.dist-info/METADATA,sha256=NU2D24eKgpzeuBDT-mq6x9sp7xia2dlcvetTFI_ScJw,13076
|
|
7
|
+
mcp_acp-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
8
|
+
mcp_acp-0.1.0.dist-info/entry_points.txt,sha256=D13PybhJJVRI9eiftU8WoIYzCZKEisgQi1ToLHyAmMU,47
|
|
9
|
+
mcp_acp-0.1.0.dist-info/top_level.txt,sha256=m31LfOaPsjjCq7zw0ofZDOdrDo2p9kM3-eSK3IeRXhM,8
|
|
10
|
+
mcp_acp-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mcp_acp
|