Aspire and OpenTelemetry Integration Summary
Overview
This document summarizes the changes made to containerize the Roslyn-Stone MCP server using .NET Aspire and OpenTelemetry integration.
Changes Made
1. New Projects
RoslynStone.ServiceDefaults
- Purpose: Provides OpenTelemetry configuration and service defaults
- Location:
src/RoslynStone.ServiceDefaults/ - Key Components:
- Extensions.cs: Configures OpenTelemetry logging, metrics, and tracing
- Automatic OTLP exporter configuration
- Health check endpoints
- Service discovery support
RoslynStone.AppHost
- Purpose: Aspire orchestration host for local development
- Location:
src/RoslynStone.AppHost/ - Key Components:
- AppHost.cs: Configures MCP server as a containerized resource with HTTP transport
- Provides Aspire dashboard for telemetry visualization
- Manages service lifecycle and configuration
- MCP Inspector Integration: Uses CommunityToolkit.Aspire.Hosting.McpInspector package to automatically launch and configure the inspector in development mode
RoslynStone.AppHost.Tests
- Purpose: Integration tests for Aspire configuration
- Location:
tests/RoslynStone.AppHost.Tests/ - Key Components:
- AppHostTests.cs: 7 tests verifying AppHost configuration
- Tests verify HTTP transport, environment variables, resource setup, and inspector configuration
- Fast-running tests that don't require Docker or DCP
2. Modified Projects
RoslynStone.Api
- Changes:
- Added reference to ServiceDefaults project
- Integrated
AddServiceDefaults()in Program.cs - Supports both stdio and HTTP transport modes via
MCP_TRANSPORTenvironment variable - HTTP transport mode provides REST endpoints for MCP protocol
- Logging configured to stderr to avoid protocol interference
3. Transport Configuration
HTTP Transport (Default for Aspire)
- Port: Configurable via
MCP_HTTP_PORTenvironment variable (default: 8080) - Endpoints:
/mcpfor MCP HTTP protocol,/healthfor health checks - Usage: Designed for container deployment and testing with tools like MCP Inspector
- Security: No authentication by default - configure before public exposure
Stdio Transport
- Removed from AppHost: Stdio transport configuration removed from Aspire AppHost
- Still Available: Can still be used by running the API directly with
MCP_TRANSPORT=stdio - Use Case: Direct execution, Claude Desktop integration, local development
4. Containerization
Dockerfile
- Location:
src/RoslynStone.Api/Dockerfile - Features:
- Multi-stage build (build, publish, final)
- Optimized layer caching
- Based on .NET 10.0 SDK and runtime images
- Minimal runtime dependencies
- Configurable build configuration
.dockerignore
- Purpose: Optimize Docker build context
- Excludes: Build artifacts, tests, documentation, git files
docker-compose.yml
- Purpose: Local development with Aspire dashboard
- Services:
- roslyn-stone-mcp: The MCP server container
- aspire-dashboard: Telemetry visualization dashboard
- Features:
- Automatic network configuration
- OTLP endpoint configuration
- Dashboard accessible at http://localhost:18888
5. CI/CD
.github/workflows/container.yml
- Purpose: Build and publish container images to GHCR
- Triggers: Push to main, tags, pull requests
- Features:
- Multi-architecture builds (linux/amd64, linux/arm64)
- Build caching with GitHub Actions cache
- Automatic tagging strategy
- Artifact attestation
- Only pushes on non-PR events
6. Documentation
README.md
- Updates:
- Added Aspire and OpenTelemetry to features list
- Updated architecture diagram
- Added Docker and Aspire usage instructions
- New "Observability with OpenTelemetry" section
- Container registry information
- Updated technology stack
- Docker Desktop configuration examples
- Production deployment guidance
OpenTelemetry Configuration
Automatic Configuration
The ServiceDefaults project automatically configures:
- Logging: OpenTelemetry format with formatted messages and scopes
- Metrics: ASP.NET Core, HttpClient, and runtime instrumentation
- Tracing: Distributed tracing with activity sources
OTLP Exporter
Configured via environment variables:
OTEL_EXPORTER_OTLP_ENDPOINT: OTLP endpoint URLOTEL_SERVICE_NAME: Service identifierOTEL_RESOURCE_ATTRIBUTES: Additional resource metadata
Aspire Dashboard
- Provides real-time visualization during development
- Logs, metrics, and traces in a unified interface
- No configuration required for local development
Usage Scenarios
Local Development (Direct)
# Stdio transport (for Claude Desktop, etc.)
cd src/RoslynStone.Api
dotnet run
# HTTP transport
cd src/RoslynStone.Api
MCP_TRANSPORT=http dotnet run
Local Development (Aspire)
cd src/RoslynStone.AppHost
dotnet run
# Aspire dashboard available at http://localhost:18888
# MCP server HTTP endpoint available on configured port (default: 8080)
# MCP Inspector UI automatically starts at http://localhost:6274
Using MCP Inspector
The MCP Inspector is automatically launched when running the AppHost in development mode using the CommunityToolkit.Aspire.Hosting.McpInspector package.
Automatic Configuration:
- Inspector UI: http://localhost:6274 (configurable via
INSPECTOR_UI_PORT) - Inspector Proxy: http://localhost:6277 (configurable via
INSPECTOR_PROXY_PORT) - Automatically connects to the MCP server's HTTP endpoint
Usage:
- Start the Aspire AppHost:
cd src/RoslynStone.AppHost && dotnet run - Open the Inspector UI at http://localhost:6274
- The inspector is automatically connected to your MCP server
- Test MCP tools through the visual interface
- Export server configurations for Claude Desktop or other MCP clients
Technical Details:
- Uses
AddMcpInspector()extension from CommunityToolkit package - Automatically discovers and connects to MCP resources via
WithMcpServer() - Inspector endpoints are named "client" (UI) and "server-proxy" (proxy)
Docker Compose
docker-compose up --build
# Dashboard available at http://localhost:18888
# MCP server available via HTTP transport
Production Container
docker pull ghcr.io/dylanlangston/roslyn-stone:latest
docker run -i --rm \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://your-collector:4317 \
-e OTEL_SERVICE_NAME=roslyn-stone-mcp \
ghcr.io/dylanlangston/roslyn-stone:latest
Security Considerations
- No HTTP Endpoints: The MCP server uses stdio transport only
- Minimal Runtime Image: Based on aspnet:10.0 runtime (smaller attack surface)
- No Secrets in Container: All configuration via environment variables
- Diagnostics Disabled:
DOTNET_EnableDiagnostics=0in production
Testing
Unit and Integration Tests
All existing tests continue to pass:
- 101 tests passing
- 1 test skipped (slow network operations)
- 0 failures
- Build succeeds without warnings
Aspire Integration Tests
The RoslynStone.AppHost.Tests project provides integration tests for the Aspire configuration:
- 7 tests verifying AppHost setup and configuration
- Tests verify HTTP transport configuration
- Tests verify environment variables
- Tests verify resource endpoints
- Tests verify MCP Inspector integration
- Fast-running tests that don't require Docker or DCP
# Run Aspire tests
dotnet test tests/RoslynStone.AppHost.Tests
# Run all tests
dotnet test
MCP Inspector Integration
The MCP Inspector is automatically launched by the AppHost in development mode using the CommunityToolkit.Aspire.Hosting.McpInspector package:
Features:
- Automatically starts when running
dotnet runfrom AppHost in development - Uses managed Aspire resource instead of manual npx execution
- Automatically discovers and connects to MCP server resources
- Provides interactive web UI at
http://localhost:6274 - Test MCP tools without writing code
- View real-time request/response data
- Export server configurations for Claude Desktop and other clients
Ports:
6274: Inspector UI (web interface) - endpoint name: "client"6277: MCP Proxy (protocol bridge) - endpoint name: "server-proxy"
Environment Detection: The inspector only starts when:
ASPNETCORE_ENVIRONMENTorDOTNET_ENVIRONMENTis set toDevelopment- Or when no environment is specified (defaults to development)
Benefits:
- Seamless testing experience alongside Aspire dashboard
- No manual setup or configuration required
- Automatic connection to MCP server via
WithMcpServer()extension - Visual feedback on tool execution
- Easy configuration export
- Better integration with Aspire lifecycle management
Compatibility
- Backward Compatible: All existing functionality preserved
- Stdio Transport: MCP protocol communication unchanged
- Configuration: Existing environment variables still work
- Dependencies: Aspire packages are additive, no breaking changes
Deployment Options
Container Registries
- GitHub Container Registry (GHCR):
ghcr.io/dylanlangston/roslyn-stone - Can be pushed to any OCI-compatible registry
Orchestration
- Docker Compose
- Kubernetes
- Azure Container Apps
- AWS ECS/Fargate
- Google Cloud Run
Monitoring Solutions
- Azure Monitor / Application Insights
- AWS CloudWatch
- Google Cloud Operations
- Grafana / Prometheus / Jaeger
- Any OTLP-compatible collector
Future Enhancements
Potential improvements for future iterations:
- Kubernetes manifests with Helm charts
- Health check endpoints (currently only in development)
- Prometheus metrics endpoint
- Additional instrumentation for REPL operations
- Custom metrics for code execution performance
- Trace sampling configuration
- Log aggregation configuration
Support
For issues or questions:
- GitHub Issues: https://github.com/dylanlangston/Roslyn-Stone/issues
- Documentation: README.md
- Aspire Docs: https://learn.microsoft.com/en-us/dotnet/aspire/
- OpenTelemetry Docs: https://opentelemetry.io/docs/languages/net/