Coverage for mcp/resources/config.py: 88%
66 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-15 15:07 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-15 15:07 +0000
1"""Configuration resources (config:// scheme) for the GCO MCP server.
3Exposes the CDK configuration schema, feature toggles, environment variables,
4and the cdk.json configuration matrix used by tests.
5"""
7import json
8from pathlib import Path
10from server import mcp
12PROJECT_ROOT = Path(__file__).parent.parent.parent
15@mcp.resource("config://gco/index")
16def config_index() -> str:
17 """List configuration resources — CDK schema, feature toggles, env vars."""
18 lines = ["# GCO Configuration\n"]
19 lines.append("## CDK Configuration")
20 lines.append("- `config://gco/cdk.json` — Current CDK deployment configuration")
21 lines.append("- `config://gco/feature-toggles` — All feature toggles and their defaults")
22 lines.append(
23 "- `config://gco/env-vars` — Environment variables used by the MCP server and services\n"
24 )
25 lines.append("## Related")
26 lines.append("- `source://gco/config/pyproject.toml` — Python project metadata")
27 lines.append("- `source://gco/config/app.py` — CDK app entry point")
28 lines.append("- `docs://gco/docs/CUSTOMIZATION` — Full customization guide")
29 return "\n".join(lines)
32@mcp.resource("config://gco/cdk.json")
33def cdk_json_resource() -> str:
34 """Read the current CDK deployment configuration."""
35 path = PROJECT_ROOT / "cdk.json"
36 if not path.is_file(): 36 ↛ 37line 36 didn't jump to line 37 because the condition on line 36 was never true
37 return "cdk.json not found."
38 return path.read_text()
41@mcp.resource("config://gco/feature-toggles")
42def feature_toggles_resource() -> str:
43 """List all feature toggles available in cdk.json with their defaults.
45 This resource parses the current cdk.json and documents every
46 configurable feature toggle so the LLM can help users enable/disable
47 features.
48 """
49 path = PROJECT_ROOT / "cdk.json"
50 if not path.is_file(): 50 ↛ 51line 50 didn't jump to line 51 because the condition on line 50 was never true
51 return "cdk.json not found."
53 try:
54 config = json.loads(path.read_text())
55 context = config.get("context", {})
56 except json.JSONDecodeError, KeyError:
57 return "Could not parse cdk.json."
59 lines = ["# GCO Feature Toggles\n"]
60 lines.append("These are the configurable options in `cdk.json` under the `context` key.\n")
62 # Extract known toggle categories
63 if "regions" in context: 63 ↛ 64line 63 didn't jump to line 64 because the condition on line 63 was never true
64 lines.append(f"## Regions\n`regions`: {json.dumps(context['regions'])}\n")
66 helm = context.get("helm", {})
67 if helm: 67 ↛ 75line 67 didn't jump to line 75 because the condition on line 67 was always true
68 lines.append("## Helm Charts (Schedulers & Operators)\n")
69 for chart, cfg in sorted(helm.items()):
70 enabled = cfg.get("enabled", False) if isinstance(cfg, dict) else cfg
71 lines.append(f"- `helm.{chart}.enabled`: {enabled}")
72 lines.append("")
74 # Storage toggles
75 for key in ("fsx", "valkey", "aurora_pgvector"):
76 val = context.get(key, {})
77 if isinstance(val, dict): 77 ↛ 75line 77 didn't jump to line 75 because the condition on line 77 was always true
78 enabled = val.get("enabled", False)
79 lines.append(f"## {key}\n- `{key}.enabled`: {enabled}")
80 for k, v in sorted(val.items()):
81 if k != "enabled":
82 lines.append(f"- `{key}.{k}`: {v}")
83 lines.append("")
85 # Resource quotas
86 for key in ("manifest_processor", "queue_processor"):
87 val = context.get(key, {})
88 if val: 88 ↛ 86line 88 didn't jump to line 86 because the condition on line 88 was always true
89 lines.append(f"## {key}\n")
90 for k, v in sorted(val.items()):
91 if isinstance(v, dict):
92 for k2, v2 in sorted(v.items()):
93 lines.append(f"- `{key}.{k}.{k2}`: {v2}")
94 else:
95 lines.append(f"- `{key}.{k}`: {v}")
96 lines.append("")
98 return "\n".join(lines)
101@mcp.resource("config://gco/env-vars")
102def env_vars_resource() -> str:
103 """List environment variables used by the GCO MCP server and services."""
104 return """# GCO Environment Variables
106## MCP Server
108| Variable | Default | Description |
109|----------|---------|-------------|
110| `GCO_MCP_ROLE_ARN` | (unset) | IAM role ARN to assume at startup. When set, the MCP server uses STS AssumeRole for least-privilege access. |
111| `GCO_MCP_ROLE_SESSION_NAME` | `gco-mcp-server` | Session name for the assumed role. |
112| `GCO_MCP_ROLE_DURATION_SECONDS` | `3600` | Duration in seconds for the assumed role credentials. |
113| `GCO_ENABLE_CAPACITY_PURCHASE` | `false` | Set to `true` to enable the `reserve_capacity` tool (can incur AWS charges). |
115## CLI
117| Variable | Default | Description |
118|----------|---------|-------------|
119| `AWS_REGION` | (from config) | Default AWS region for CLI commands. |
120| `AWS_PROFILE` | (default) | AWS CLI profile to use. |
121| `GCO_CONFIG_PATH` | `cdk.json` | Path to the CDK configuration file. |
123## Services (Kubernetes)
125| Variable | Default | Description |
126|----------|---------|-------------|
127| `AUTH_SECRET_ARN` | (from stack) | Secrets Manager ARN for the authentication secret. |
128| `CLUSTER_NAME` | (from stack) | EKS cluster name. |
129| `JOB_QUEUE_URL` | (from stack) | SQS queue URL for job submission. |
130| `DLQ_URL` | (from stack) | Dead letter queue URL. |
131| `DYNAMODB_TABLE` | (from stack) | DynamoDB table name for job/template/webhook storage. |
132"""