Skip to main content
Glama
swapnilbabladkar

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).

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct CloudWatch resource and action: listing log groups, searching within a log group, and listing active alarms. There is no meaningful overlap between them, so an agent can select correctly without hesitation.

Naming Consistency5/5

All three tools follow a strict verb_noun snake_case pattern (list_log_groups, search_logs, get_active_alarms). The convention is uniform and predictable.

Tool Count4/5

Three tools is on the thin side for an observability server, but each one is well-scoped and earns its place for log/alarm triage. It sits slightly under what the domain could support rather than being excessive.

Completeness3/5

Logs and alarms are covered, but the observability surface omits other core CloudWatch pillars such as metrics and traces, and there is no way to inspect alarm history or log stream metadata. Agents can triage common issues but will hit dead ends for metric-based investigations.

Maintenance

ActivityMaintained
ResponsivenessNo issues