cloud-bicep-mcp-server 0.3.0__tar.gz

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.
@@ -0,0 +1,33 @@
1
+ # Server Configuration
2
+ # Default binds to loopback for security; set 0.0.0.0 for containers/production behind ingress
3
+ MCP_HOST=127.0.0.1
4
+ MCP_PORT=8080
5
+ MCP_DEBUG=false
6
+ LOG_LEVEL=INFO
7
+
8
+ # API Key Configuration (REQUIRED for client authentication)
9
+ # Generate a strong, random API key for production
10
+ MCP_API_KEY=your-api-key-here
11
+
12
+ # GitHub Repository Configuration (owner and repository REQUIRED - no defaults)
13
+ GITHUB_REPO_OWNER=xtratuscloud
14
+ GITHUB_REPO_NAME=cloud_bicep-registry-modules
15
+ # Optional: branch used to build documentation links (defaults to main)
16
+ GITHUB_DEFAULT_BRANCH=main
17
+
18
+ # GitHub Token Configuration
19
+ # Generate a PAT at: https://github.com/settings/tokens
20
+ # Scope: repo (for private repositories)
21
+ # IMPORTANT: This token must be authorized for SAML SSO if organization has it enabled
22
+ GITHUB_TOKEN=your-github-token-here
23
+
24
+ # Bicep module registry (REQUIRED - no defaults)
25
+ # OCI registry and repository path where bicep modules are published
26
+ # Used to build the module references (br:<registry>/<name>:<version>)
27
+ BICEP_MODULE_REGISTRY=yourregistry.azurecr.io/bicep/modules
28
+
29
+ # Cache Configuration
30
+ # Disk cache directory: empty = system temp directory
31
+ MCP_CACHE_DIR=
32
+ # TTL for cache entries in seconds (default 24h)
33
+ MCP_CACHE_TTL_SECONDS=86400
@@ -0,0 +1,53 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual Environment
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+ env/
28
+
29
+ # Environment variables
30
+ .env
31
+
32
+ # Test scripts
33
+ /test_*.py
34
+
35
+ # Testing
36
+ .pytest_cache/
37
+ .coverage
38
+ htmlcov/
39
+ *.cover
40
+ .hypothesis/
41
+ /results.xml
42
+ /coverage.xml
43
+
44
+ # IDE
45
+ .vscode/
46
+ .idea/
47
+ *.swp
48
+ *.swo
49
+ *~
50
+
51
+ # OS
52
+ .DS_Store
53
+ Thumbs.db
@@ -0,0 +1,171 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.3.0] - 2026-10-15
9
+
10
+ ### Changed
11
+
12
+ - **Inventory caching for `list_bicep_modules` and `search_bicep_modules`**: the module inventory is now cached, keyed by a fingerprint of the module directory listing (names and tree SHAs)
13
+ - Any content change inside a module folder (including version bumps) changes its tree SHA and invalidates the cache
14
+ - Steady-state calls use a single GitHub API request instead of one version request and one metadata request per module
15
+ - Reduces latency and GitHub rate-limit consumption, and prevents fallback versions ("1.0.0") caused by rate limiting
16
+ - **Required settings** (breaking change): `GITHUB_REPO_OWNER`, `GITHUB_REPO_NAME` and `BICEP_MODULE_REGISTRY` no longer have default values; the server fails to start with a validation error when any of them is not explicitly configured (`GITHUB_DEFAULT_BRANCH` keeps its `main` default)
17
+ - **Renamed `ACR_REGISTRY` to `BICEP_MODULE_REGISTRY`** (breaking change): the setting now contains the full OCI registry and repository path (e.g., `yourregistry.azurecr.io/bicep/modules`) instead of just the registry host
18
+ - Module references are built as `br:<BICEP_MODULE_REGISTRY>/<name>:<version>`; the `/bicep/modules/` path is no longer hardcoded
19
+ - Registry-agnostic: supports ACR, ghcr.io, Docker Hub or any OCI-compliant registry, at any repository path depth
20
+ - The tool output field `acrReference` is now `moduleReference`, and the `## ACR Reference` section in `scrape_bicep_module_details` is now `## Module Reference` (no compatibility alias: this is the first public release)
21
+ - **Removed the Redis cache backend** (breaking change): the disk cache is now the only backend, which persists across sessions in local STDIO deployments without requiring external services
22
+ - Removed settings: `MCP_CACHE_BACKEND` and `MCP_CACHE_REDIS_URL`
23
+ - Removed the `RedisCacheBackend` class and its tests
24
+ - **Removed GitHub OIDC authentication** (breaking change): the server now authenticates against GitHub exclusively with the configured `GITHUB_TOKEN`
25
+ - Removed GitHub App OIDC token exchange, OIDC token validation and the request-scoped OIDC token storage
26
+ - Removed settings: `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_CLIENT_ID`, `OIDC_ENABLED`, `OIDC_ISSUER`, `OIDC_AUDIENCE`, `OIDC_ALLOWED_REPOSITORIES`
27
+ - Removed the `pyjwt` and `cryptography` dependencies (only used for OIDC)
28
+ - `GITHUB_TOKEN` is required when accessing private repositories; authenticated HTTP/SSE requests also enforce its presence (health and icon routes remain public, and public-repository STDIO use can omit it)
29
+ - **Local-first distribution**: `server.json` now declares STDIO packages for GitHub Packages (`ghcr.io`, `runtimeHint: docker`) and PyPI (`runtimeHint: uvx`), surfacing the required environment variables to MCP clients
30
+ - **Docker image moved to GitHub Packages** (breaking change): the CI workflow now publishes the image to `ghcr.io/xtratuscloud/cloud-bicep-mcp-server` instead of the internal ACR registry; the release workflow publishes the package to PyPI
31
+ - Image tags: pre-releases `<BASE_VERSION>.YYYYMMDD.<RUN_NUMBER>`, official releases `<BASE_VERSION>` and `latest`
32
+ - Required repository secrets: `GHCR_USERNAME`, `GHCR_TOKEN`, `PYPI_API_TOKEN`
33
+ - **Documentation now focuses on local execution**: client setup sections (VSCode, Devin) document local uvx and Docker STDIO configurations instead of remote HTTP deployments
34
+ - **Package metadata cleanup**: author, repository URLs and icon references no longer point to internal resources; the icon is served from a public URL
35
+
36
+ ## [0.2.1] - 2026-10-13
37
+
38
+ ### Changed
39
+
40
+ - **Release workflow**: aligned `bicep-mcp-release.yml` with the modules release implementation
41
+ - Uses the official GitHub CLI (`gh release create`) instead of the third-party `softprops/action-gh-release` action
42
+ - Release notes now embed the changelog section for the released version under "What's Changed" (previously just a link to the CHANGELOG)
43
+ - **Idempotent releases**: rerunning the release workflow no longer skips the whole job when the tag already exists
44
+ - Only tag creation is skipped; a missing GitHub Release is still created
45
+ - Existing releases get their notes regenerated from the changelog (`gh release edit`)
46
+ - The same idempotency fix was applied to `bicep-modules-release.yml` to keep both release workflows aligned
47
+ - **Deployment metadata**: server version references are now driven by `server.json`/`pyproject.toml`
48
+ - `server.json` package version kept in sync with the project version
49
+ - The `/health` endpoint reports the version from `server.json` instead of a hardcoded string
50
+
51
+ ## [0.2.0] - 2026-10-13
52
+
53
+ ### Added
54
+
55
+ - **Health Check Endpoint**: Added `/health` endpoint for Kubernetes liveness, readiness, and startup probes
56
+ - Returns server status, version, and timestamp
57
+ - Returns 200 status when server is healthy
58
+ - Returns 503 status on errors
59
+ - **Caching System**: Implemented comprehensive caching for module README content to reduce GitHub API calls
60
+ - Disk-based cache backend (default) with configurable TTL
61
+ - Redis-based cache backend for distributed deployments
62
+ - Version-aware caching: cache is invalidated when module version changes
63
+ - Configurable cache directory and TTL via environment variables
64
+ - Thread-safe cache operations
65
+ - **Enhanced README Extraction**: Improved pattern matching for module README sections
66
+ - Support for multiple resource section patterns: "Resources Created", "Deployed Resources", "Resource Types"
67
+ - Support for multiple usage example patterns: "Usage Examples", "Examples"
68
+ - Better handling of different README structures
69
+ - **Documentation**: Added comprehensive README format documentation
70
+ - Documented expected section names and patterns
71
+ - Listed module compliance status
72
+ - Provided examples for each section type
73
+ - **ACR Module References**: Bicep module references (`br:<registry>/bicep/modules/<name>:<version>`) are now exposed to MCP clients
74
+ - New `acrReference` field in `list_bicep_modules` output
75
+ - New `## ACR Reference` section in `scrape_bicep_module_details` output
76
+ - New `ACR_REGISTRY` setting (default: `yourregistry.azurecr.io`), documented in `.env.example` and README
77
+ - **Module Search**: New `search_bicep_modules` tool with a required search term
78
+ - Matches against module name, display name, canonical Azure resource type and description (case-insensitive)
79
+ - Multi-word terms match when the full term (or its compact/hyphenated variants) is a substring, or when every word is present
80
+ - Complements `list_bicep_modules` (full inventory) with a dedicated filtering tool
81
+
82
+ ### Changed
83
+
84
+ - `list_bicep_modules` now returns a lightweight full module inventory (`name`, `displayName`, `acrReference`) to keep responses small; the optional `modulename` filter moved to `search_bicep_modules`, which returns complete module information
85
+ - Removed the `find_bicep_module_prompt` prompt (redundant with the new `search_bicep_modules` tool)
86
+ - Integrated caching into `scrape_bicep_module_details` tool
87
+ - Checks cache before fetching from GitHub
88
+ - Updates cache after successful extraction
89
+ - Logs cache hits and misses for monitoring
90
+ - Updated Dockerfile to include new `cache.py` module
91
+ - Updated package configuration (pyproject.toml) to include cache.py in distribution
92
+ - Enhanced test coverage with comprehensive cache tests
93
+ - Disk cache backend tests (TTL, expiration, thread safety)
94
+ - Redis cache backend tests (connection, operations)
95
+ - Integration tests for cache functions
96
+ - **Refactored code organization for better separation of concerns**:
97
+ - Created `github.py` for all GitHub API interactions
98
+ - Functions: `get_github_headers`, `get_github_token_from_oidc`, `get_cached_github_token`,
99
+ `validate_github_oidc_token`, `get_allowed_repositories`, `get_module_version_from_github`,
100
+ `get_effective_github_token`, `set_oidc_github_token`
101
+ - Created `auth.py` for authentication middleware
102
+ - Contains `APIKeyAuthMiddleware` class for client authentication
103
+ - Designed to support additional authentication mechanisms in the future
104
+ - Renamed `test_auth.py` to `test_github.py` to reflect the new module structure
105
+ - Created new `test_auth.py` for authentication middleware tests
106
+ - `server.py` now focuses solely on MCP server logic and tool definitions
107
+
108
+ ### Fixed
109
+
110
+ - **Security**: SSE transport now uses ASGI app with API Key middleware (previously bypassed authentication)
111
+ - **Security**: The OIDC-exchanged GitHub token is now stored request-scoped (`contextvars.ContextVar`) and cleared after each request (previously stored in `threading.local` without reset, leaking the token to concurrent or subsequent requests on the same ASGI worker thread)
112
+ - Renamed `list_bicep_modules` field from `versions` to `currentVersion` to accurately reflect that only the current version is returned
113
+ - Updated documentation to clarify that `currentVersion` returns the version from `version.json`, not all historical versions
114
+ - Fixed documentation URL to use `GITHUB_DEFAULT_BRANCH` instead of hardcoded "main"
115
+ - Fixed README path construction in `scrape_bicep_module_details` to handle both direct README.md URLs and directory URLs
116
+ - **README section extraction**: fixed two regex bugs in `scrape_bicep_module_details`
117
+ - "Usage Examples" as the last section of a README returned only the heading (multiline `$` matched the end of the heading line instead of the end of the document)
118
+ - Sections containing `###` subsections (e.g. "Type definitions") were truncated at the first subsection because the section terminator was not anchored to the start of a line
119
+
120
+ ### Performance
121
+
122
+ - Reduced GitHub API calls through intelligent caching
123
+ - Faster response times for repeated module detail requests
124
+ - Configurable cache TTL (default 24 hours) to balance freshness and performance
125
+
126
+
127
+ ## [0.1.0] - 2026-10-07
128
+
129
+ ### Added
130
+
131
+ - `list_bicep_modules` tool to search and list Cloud Bicep modules from the private GitHub repository
132
+ - `scrape_bicep_module_details` tool to extract Resource Types, Parameters, Outputs, and Usage Examples from module READMEs
133
+ - Support for multiple transport methods: STDIO (default), HTTP, and SSE
134
+ - API Key authentication for client validation (mandatory for all requests)
135
+ - GitHub authentication support with two methods:
136
+ - GitHub Personal Access Token (PAT) for initial testing
137
+ - GitHub Actions OIDC with GitHub App for production deployments (not tested yet)
138
+ - Intelligent module search with fuzzy matching (supports multiple name formats)
139
+ - Module metadata integration (reads metadata.json and version.json files)
140
+ - MCP prompts for finding modules, getting module details, and suggesting modules for Azure services
141
+ - Docker container support for easy deployment
142
+ - Configuration via environment variables with .env file support
143
+ - Comprehensive documentation including Kubernetes deployment guide
144
+ - Debug logging mode for troubleshooting production issues
145
+ - Code linting with ruff for consistent code style
146
+
147
+ ### Changed
148
+
149
+ - Refactored server to use FastMCP V2 native HTTP and SSE support instead of manual Starlette implementation
150
+ - Reduced code from ~839 lines to ~736 lines (~12% reduction)
151
+ - Simplified STDIO transport using `mcp.run()` directly
152
+ - Simplified HTTP transport using `mcp.http_app(middleware=middleware)`
153
+ - Simplified SSE transport using `mcp.run(transport="sse")`
154
+ - Simplified custom routes using `@mcp.custom_route()` decorator
155
+ - Updated code style to comply with ruff linting rules
156
+ - Improved test mocks to properly simulate HTTP responses with headers
157
+
158
+ ### Features
159
+
160
+ - Search modules by name with intelligent matching (exact, hyphenated, space-separated, compact formats)
161
+ - Retrieve module versions directly from the repository
162
+ - Extract detailed parameter information and usage examples from module documentation
163
+ - Direct repository access to private GitHub repository with proper authentication
164
+ - Configurable host, port, and debug settings
165
+ - Support for both development (PAT) and production (OIDC) authentication scenarios
166
+ - Ready-to-use Docker images for containerized deployments
167
+ - Complete setup guides for Claude Desktop, VSCode, and Kubernetes
168
+
169
+ [0.3.0]: https://github.com/xtratuscloud/cloud_bicep-registry-modules/releases/tag/mcp/v0.3.0
170
+ [0.2.0]: https://github.com/xtratuscloud/cloud_bicep-registry-modules/releases/tag/mcp/v0.2.0
171
+ [0.1.0]: https://github.com/xtratuscloud/cloud_bicep-registry-modules/releases/tag/v0.1.0
@@ -0,0 +1,79 @@
1
+ # Build stage
2
+ FROM python:3.13.2-slim AS builder
3
+
4
+ WORKDIR /app
5
+
6
+ # Install Poetry
7
+ RUN pip install --no-cache-dir poetry
8
+
9
+ # Copy Poetry configuration files and README
10
+ COPY pyproject.toml poetry.lock* README.md ./
11
+
12
+ # Copy application code
13
+ COPY server.py server.json config.py github.py cache.py auth.py ./
14
+ COPY images/cloud-bicep-mcp-96.png ./images/
15
+
16
+ # Configure Poetry to not create virtualenv and install dependencies
17
+ RUN poetry config virtualenvs.create false \
18
+ && poetry install --no-interaction --without dev \
19
+ && poetry check \
20
+ && rm -rf ~/.cache/pypoetry \
21
+ && rm -rf ~/.cache/pip
22
+
23
+ # Runtime stage
24
+ FROM python:3.13.2-slim
25
+
26
+ WORKDIR /app
27
+
28
+ # Copy application code from builder
29
+ COPY --from=builder /app /app
30
+
31
+ # Copy installed dependencies from builder
32
+ COPY --from=builder /usr/local/lib /usr/local/lib
33
+ COPY --from=builder /usr/local/bin /usr/local/bin
34
+
35
+ # Clean up pip cache in runtime stage
36
+ RUN pip cache purge \
37
+ && rm -rf /tmp/* /var/tmp/* ~/.cache/pip
38
+
39
+ # Set environment variables with defaults that can be overridden
40
+ # the transport can be set to "stdio", "sse" or "http". Defaults to "http".
41
+ # "stdio" uses standard input/output for communication.
42
+ # "sse" is the server-sent events mode and uses HTTP (Server-Sent Events) for communication.
43
+ # "http" enables the Streamable HTTP transport as defined by the MCP specification.
44
+ ENV MCP_TRANSPORT=http
45
+ # The port is used by the "sse" and "http" transport modes and defaults to 8080.
46
+ ENV MCP_PORT=8080
47
+ # The host address to bind to. Defaults to 0.0.0.0 for containerized deployments.
48
+ # WARNING: When using 0.0.0.0, MCP_API_KEY must be set for security.
49
+ ENV MCP_HOST=0.0.0.0
50
+
51
+ # Create entrypoint script
52
+ RUN echo '#!/bin/bash\n\
53
+ TRANSPORT_ARG=""\n\
54
+ PORT_ARG=""\n\
55
+ HOST_ARG=""\n\
56
+ \n\
57
+ # Only add transport parameter if MCP_TRANSPORT is set\n\
58
+ if [ -n "$MCP_TRANSPORT" ]; then\n\
59
+ TRANSPORT_ARG="--transport $MCP_TRANSPORT"\n\
60
+ fi\n\
61
+ \n\
62
+ # Only add port parameter if MCP_PORT is set\n\
63
+ if [ -n "$MCP_PORT" ]; then\n\
64
+ PORT_ARG="--port $MCP_PORT"\n\
65
+ fi\n\
66
+ \n\
67
+ # Only add host parameter if MCP_HOST is set\n\
68
+ if [ -n "$MCP_HOST" ]; then\n\
69
+ HOST_ARG="--host $MCP_HOST"\n\
70
+ fi\n\
71
+ \n\
72
+ python server.py $TRANSPORT_ARG $PORT_ARG $HOST_ARG\n\
73
+ ' > /app/docker-entrypoint.sh \
74
+ && chmod +x /app/docker-entrypoint.sh
75
+
76
+ EXPOSE 8080
77
+
78
+ # Set the entry point for the container
79
+ ENTRYPOINT ["/app/docker-entrypoint.sh"]