mcp-aws-observability-server
README.md
# mcp-aws-observability-server
A small, **dependency-free** MCP (Model Context Protocol) server that
exposes AWS CloudWatch Logs and Alarms as tools an LLM client (Claude
Desktop, an agent runtime, a custom MCP client) can call — `list_log_groups`,
`search_logs`, and `get_active_alarms`.
This is a reference implementation modelled on the kind of MCP server
I've built and deployed to AWS at Equal Experts for centralized
logging/monitoring/observability across a shared GenAI platform: the
same tool surface, but standing on a mock backend here instead of a
real account, so anyone can clone and run it in under a minute.
## Why no SDK dependency
The official `mcp` SDK is great, but for a reference/demo repo I wanted
zero install friction and the transport mechanics to be visible rather
than hidden behind a library. `src/mcp_observability/protocol.py`
implements the newline-delimited JSON-RPC 2.0 stdio transport and the
`initialize` / `tools/list` / `tools/call` lifecycle directly from the
[MCP specification](https://modelcontextprotocol.io/specification). It's
~200 lines and fully tested — a good place to actually read how MCP
works under the hood.
## Quickstart
```bash
git clone https://github.com/swapnilbabladkar/mcp-aws-observability-server.git
cd mcp-aws-observability-server
# run the test suite (stdlib unittest, no install required)
PYTHONPATH=src python3 -m unittest discover -s tests -v
# run the full stdio flow against a real subprocess
python3 examples/demo_client.py
# or run the server directly (reads JSON-RPC from stdin, writes to stdout)
PYTHONPATH=src python3 -m mcp_observability
```
## Using it from Claude Desktop
Add to your MCP client config (e.g. Claude Desktop's
`claude_desktop_config.json`):
```json
{
"mcpServers": {
"aws-observability": {
"command": "python3",
"args": ["-m", "mcp_observability"],
"env": { "PYTHONPATH": "/absolute/path/to/mcp-aws-observability-server/src" }
}
}
}
```
Restart Claude Desktop and ask it something like *"any active alarms on
the platform right now?"* or *"search the mcp-server log group for
errors in the last two hours."*
## Switching to real AWS data
By default the server runs on `MockObservabilityBackend`, which returns
realistic canned data (log groups/events/alarms shaped like a real
EKS-hosted MCP server + RAG pipeline platform) so the whole tool-call
flow works with zero AWS setup.
To point it at a real account, install the optional AWS extra and swap
the backend in `server.py`:
```bash
pip install -e ".[aws]"
```
```python
# server.py
from .backends import AWSObservabilityBackend
def default_server() -> MCPServer:
return build_server(AWSObservabilityBackend(region_name="eu-west-1"))
```
`AWSObservabilityBackend` (in `backends.py`) implements the same
interface via `boto3`'s `logs` and `cloudwatch` clients — real
`describe_log_groups` / `filter_log_events` / `describe_alarms` calls,
paginated. It needs a role/profile with `logs:Describe*`,
`logs:FilterLogEvents`, and `cloudwatch:DescribeAlarms`.
## Project layout
```
src/mcp_observability/
protocol.py # MCP JSON-RPC/stdio transport — the actual protocol implementation
backends.py # ObservabilityBackend interface + Mock and AWS implementations
server.py # registers the 3 tools against a backend
__main__.py # `python -m mcp_observability` entrypoint
tests/ # unittest coverage for protocol + mock backend
examples/
demo_client.py # spawns the server as a subprocess and drives it end-to-end
```
## Running the tests
```bash
PYTHONPATH=src python3 -m unittest discover -s tests -v
```
16 tests, covering the JSON-RPC error cases (parse errors, unknown
methods, unknown tools, tool-level failures vs. protocol failures) as
well as the mock backend's filtering logic.
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues