rootly-mcp-server 1.0.0__tar.gz → 2.0.1__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.
- rootly_mcp_server-2.0.1/.github/workflows/pypi-release.yml +33 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/.gitignore +15 -1
- rootly_mcp_server-2.0.1/.semaphore/deploy.yml +55 -0
- rootly_mcp_server-2.0.1/.semaphore/semaphore.yml +45 -0
- rootly_mcp_server-2.0.1/.semaphore/update-task-definition.sh +43 -0
- rootly_mcp_server-2.0.1/CLAUDE.md +68 -0
- rootly_mcp_server-2.0.1/Dockerfile +28 -0
- rootly_mcp_server-2.0.1/PKG-INFO +225 -0
- rootly_mcp_server-2.0.1/README.md +200 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/pyproject.toml +12 -16
- rootly_mcp_server-2.0.1/rootly_fastmcp_server.py +148 -0
- rootly_mcp_server-2.0.1/rootly_fastmcp_server_routemap.py +210 -0
- rootly_mcp_server-2.0.1/rootly_openapi_loader.py +96 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/src/rootly_mcp_server/__init__.py +1 -1
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/src/rootly_mcp_server/__main__.py +78 -10
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/src/rootly_mcp_server/client.py +40 -26
- rootly_mcp_server-2.0.1/src/rootly_mcp_server/routemap_server.py +206 -0
- rootly_mcp_server-2.0.1/src/rootly_mcp_server/server.py +525 -0
- rootly_mcp_server-2.0.1/src/rootly_mcp_server/test_client.py +148 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/uv.lock +164 -13
- rootly_mcp_server-1.0.0/PKG-INFO +0 -128
- rootly_mcp_server-1.0.0/README.md +0 -104
- rootly_mcp_server-1.0.0/src/rootly_mcp_server/data/swagger.json +0 -1
- rootly_mcp_server-1.0.0/src/rootly_mcp_server/server.py +0 -451
- rootly_mcp_server-1.0.0/src/rootly_mcp_server/test_client.py +0 -67
- rootly_mcp_server-1.0.0/swagger.json +0 -1
- rootly_mcp_server-1.0.0/test_mcp_client.py +0 -106
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/LICENSE +0 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/rootly-mcp-server-demo.gif +0 -0
- {rootly_mcp_server-1.0.0 → rootly_mcp_server-2.0.1}/src/rootly_mcp_server/data/__init__.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish Python 🐍 distribution 📦 to PyPI on tag
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build-and-publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- name: Checkout code
|
|
13
|
+
uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Set up Python
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
|
|
20
|
+
- name: Install uv and build tools
|
|
21
|
+
run: |
|
|
22
|
+
pip install build twine
|
|
23
|
+
|
|
24
|
+
- name: Build package
|
|
25
|
+
run: |
|
|
26
|
+
python -m build
|
|
27
|
+
|
|
28
|
+
- name: Publish to PyPI
|
|
29
|
+
env:
|
|
30
|
+
TWINE_USERNAME: __token__
|
|
31
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
32
|
+
run: |
|
|
33
|
+
twine upload dist/*
|
|
@@ -77,6 +77,7 @@ target/
|
|
|
77
77
|
|
|
78
78
|
# Jupyter Notebook
|
|
79
79
|
.ipynb_checkpoints
|
|
80
|
+
*.ipynb
|
|
80
81
|
|
|
81
82
|
# IPython
|
|
82
83
|
profile_default/
|
|
@@ -173,4 +174,17 @@ cython_debug/
|
|
|
173
174
|
# PyPI configuration file
|
|
174
175
|
.pypirc
|
|
175
176
|
|
|
176
|
-
|
|
177
|
+
# IDE/Editor files
|
|
178
|
+
.cursor
|
|
179
|
+
.vscode/
|
|
180
|
+
*.swp
|
|
181
|
+
*.swo
|
|
182
|
+
*~
|
|
183
|
+
|
|
184
|
+
# MCP Server specific
|
|
185
|
+
# Downloaded swagger.json files (auto-fetched from URL)
|
|
186
|
+
swagger.json
|
|
187
|
+
|
|
188
|
+
# Test outputs and temporary files
|
|
189
|
+
test_output/
|
|
190
|
+
*.tmp
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
version: v1.0
|
|
2
|
+
name: Build and Deploy
|
|
3
|
+
|
|
4
|
+
queue:
|
|
5
|
+
name: Deployment Queue
|
|
6
|
+
scope: project
|
|
7
|
+
|
|
8
|
+
agent:
|
|
9
|
+
machine:
|
|
10
|
+
type: r1-standard-4
|
|
11
|
+
os_image: ubuntu2204
|
|
12
|
+
|
|
13
|
+
blocks:
|
|
14
|
+
- name: 'Deploy'
|
|
15
|
+
dependencies: []
|
|
16
|
+
task:
|
|
17
|
+
secrets:
|
|
18
|
+
- name: 'AWS Credentials'
|
|
19
|
+
prologue:
|
|
20
|
+
commands:
|
|
21
|
+
- export AWS_PROFILE=production
|
|
22
|
+
- export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
23
|
+
- aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com
|
|
24
|
+
jobs:
|
|
25
|
+
- name: Deploy
|
|
26
|
+
commands:
|
|
27
|
+
- checkout
|
|
28
|
+
- |
|
|
29
|
+
export TASK_FAMILY=rootly-mcp-server
|
|
30
|
+
export CONTAINER_NAME=mcp
|
|
31
|
+
export IMAGE=657716690934.dkr.ecr.us-east-1.amazonaws.com/rootly/mcp:${SEMAPHORE_GIT_SHA}
|
|
32
|
+
NEW_TASK_DEFINITION_ARN=$(./.semaphore/update-task-definition.sh)
|
|
33
|
+
|
|
34
|
+
aws ecs update-service \
|
|
35
|
+
--cluster rootly-web \
|
|
36
|
+
--service rootly-mcp-server \
|
|
37
|
+
--task-definition "$NEW_TASK_DEFINITION_ARN" \
|
|
38
|
+
--deployment-configuration "deploymentCircuitBreaker={enable=true,rollback=true},maximumPercent=200,minimumHealthyPercent=100" \
|
|
39
|
+
--force-new-deployment >/dev/null
|
|
40
|
+
|
|
41
|
+
echo "Waiting for service to stabilize at the new revision..."
|
|
42
|
+
|
|
43
|
+
# Wait for the service to stabilize for up to 10 minutes
|
|
44
|
+
for i in {1..40}; do
|
|
45
|
+
if aws ecs describe-services --cluster rootly-web --service rootly-mcp-server --output json | jq -e \
|
|
46
|
+
'.services | map(select((.deployments | length) != 1 or .runningCount != .desiredCount)) | length == 0' >/dev/null; then
|
|
47
|
+
break
|
|
48
|
+
fi
|
|
49
|
+
sleep 15
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
if [ $i -eq 40 ]; then
|
|
53
|
+
echo "Service failed to stabilize after 10 minutes"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
version: v1.0
|
|
2
|
+
name: Build and Deploy
|
|
3
|
+
|
|
4
|
+
queue:
|
|
5
|
+
name: Build Queue
|
|
6
|
+
scope: project
|
|
7
|
+
|
|
8
|
+
auto_cancel:
|
|
9
|
+
queued:
|
|
10
|
+
when: 'true'
|
|
11
|
+
|
|
12
|
+
agent:
|
|
13
|
+
machine:
|
|
14
|
+
type: r1-standard-4
|
|
15
|
+
os_image: ubuntu2204
|
|
16
|
+
|
|
17
|
+
blocks:
|
|
18
|
+
- name: 'Build'
|
|
19
|
+
dependencies: []
|
|
20
|
+
task:
|
|
21
|
+
secrets:
|
|
22
|
+
- name: 'AWS Credentials'
|
|
23
|
+
prologue:
|
|
24
|
+
commands:
|
|
25
|
+
- export AWS_PROFILE=production
|
|
26
|
+
- export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
|
27
|
+
- aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com
|
|
28
|
+
jobs:
|
|
29
|
+
- name: Build
|
|
30
|
+
commands:
|
|
31
|
+
- checkout
|
|
32
|
+
- export BUILDKIT_PROGRESS=plain
|
|
33
|
+
- |
|
|
34
|
+
docker build --push \
|
|
35
|
+
-t 657716690934.dkr.ecr.us-east-1.amazonaws.com/rootly/mcp:${SEMAPHORE_GIT_SHA} \
|
|
36
|
+
-t 657716690934.dkr.ecr.us-east-1.amazonaws.com/rootly/mcp:latest \
|
|
37
|
+
-t 657716690934.dkr.ecr.us-east-1.amazonaws.com/rootly/mcp:production .
|
|
38
|
+
|
|
39
|
+
promotions:
|
|
40
|
+
- name: Deploy
|
|
41
|
+
pipeline_file: deploy.yml
|
|
42
|
+
deployment_target: production
|
|
43
|
+
|
|
44
|
+
auto_promote:
|
|
45
|
+
when: branch = 'main' AND result = 'passed'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# Updates a task definition with a new container image
|
|
6
|
+
# Returns the new task definition ARN
|
|
7
|
+
#
|
|
8
|
+
# Required environment variables:
|
|
9
|
+
# TASK_FAMILY - Task definition family
|
|
10
|
+
# CONTAINER_NAME - Container name to update
|
|
11
|
+
# IMAGE - New container image to deploy
|
|
12
|
+
|
|
13
|
+
if [ -z "$TASK_FAMILY" ] || [ -z "$CONTAINER_NAME" ] || [ -z "$IMAGE" ]; then
|
|
14
|
+
echo "Error: TASK_FAMILY, CONTAINER_NAME, and IMAGE environment variables are required"
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
TASK_DEFINITION="$(aws ecs describe-task-definition --task-definition=$TASK_FAMILY | jq '.taskDefinition')"
|
|
19
|
+
|
|
20
|
+
# Remove fields that can't be used in register-task-definition
|
|
21
|
+
TASK_DEFINITION="$(jq 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy)' <<< "$TASK_DEFINITION")"
|
|
22
|
+
|
|
23
|
+
# Find the index of the specified container
|
|
24
|
+
CONTAINER_INDEX="$(jq --arg NAME "$CONTAINER_NAME" '.containerDefinitions | map(.name) | index($NAME)' <<< "$TASK_DEFINITION")"
|
|
25
|
+
|
|
26
|
+
if [ "$CONTAINER_INDEX" = "null" ]; then
|
|
27
|
+
echo "Error: Container '$CONTAINER_NAME' not found in task definition"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Update the container image
|
|
32
|
+
NEW_TASK_DEFINITION="$(jq --arg INDEX "$CONTAINER_INDEX" --arg IMAGE "$IMAGE" '.containerDefinitions[$INDEX | tonumber].image = $IMAGE' <<< "$TASK_DEFINITION")"
|
|
33
|
+
|
|
34
|
+
# Register the new task definition
|
|
35
|
+
NEW_TASK_DEFINITION_ARN="$(aws ecs register-task-definition --cli-input-json "$NEW_TASK_DEFINITION" --output text --query 'taskDefinition.taskDefinitionArn')"
|
|
36
|
+
|
|
37
|
+
echo "$TASK_DEFINITION" > task-definition.json
|
|
38
|
+
echo "$NEW_TASK_DEFINITION" > new-task-definition.json
|
|
39
|
+
|
|
40
|
+
echo "Applying update:" >&2
|
|
41
|
+
diff -u task-definition.json new-task-definition.json >&2 || :
|
|
42
|
+
|
|
43
|
+
echo "$NEW_TASK_DEFINITION_ARN"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Development Commands
|
|
6
|
+
|
|
7
|
+
### Environment Setup
|
|
8
|
+
```bash
|
|
9
|
+
# Install dependencies using uv
|
|
10
|
+
uv pip install .
|
|
11
|
+
|
|
12
|
+
# Create and activate virtual environment
|
|
13
|
+
uv venv .venv
|
|
14
|
+
source .venv/bin/activate
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Testing and Quality
|
|
18
|
+
```bash
|
|
19
|
+
# Run test client to verify setup
|
|
20
|
+
python test_mcp_client.py
|
|
21
|
+
|
|
22
|
+
# Linting and type checking (if you add dev dependencies)
|
|
23
|
+
ruff check src/
|
|
24
|
+
pyright src/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Package Building
|
|
28
|
+
```bash
|
|
29
|
+
# Build the package
|
|
30
|
+
uv build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Architecture Overview
|
|
34
|
+
|
|
35
|
+
This is an MCP (Model Context Protocol) server that provides AI agents access to the Rootly API for incident management. The project uses Python 3.12+ with `uv` for dependency management.
|
|
36
|
+
|
|
37
|
+
### Core Components
|
|
38
|
+
|
|
39
|
+
- **`server.py`**: Main MCP server implementation (`RootlyMCPServer` class)
|
|
40
|
+
- Dynamically generates MCP tools from Rootly's OpenAPI/Swagger specification
|
|
41
|
+
- Filters available endpoints via `allowed_paths` configuration for security and context management
|
|
42
|
+
- Implements automatic pagination (default 10 items) for incident endpoints
|
|
43
|
+
- Uses FastMCP framework with ERROR log level to prevent UI noise
|
|
44
|
+
|
|
45
|
+
- **`client.py`**: Rootly API client (`RootlyClient` class)
|
|
46
|
+
- Handles authentication via `ROOTLY_API_TOKEN` environment variable
|
|
47
|
+
- Supports both JSON and JSON-API formats depending on endpoint requirements
|
|
48
|
+
- Base URL defaults to `https://api.rootly.com`
|
|
49
|
+
- Auto-prefixes paths with `/v1` if not present
|
|
50
|
+
|
|
51
|
+
- **`data/swagger.json`**: Cached OpenAPI specification
|
|
52
|
+
- Falls back to downloading from `https://rootly-heroku.s3.amazonaws.com/swagger/v1/swagger.json`
|
|
53
|
+
- Server searches local directories before downloading
|
|
54
|
+
|
|
55
|
+
### Key Design Patterns
|
|
56
|
+
|
|
57
|
+
- **Dynamic Tool Generation**: Tools are created at runtime based on Swagger spec rather than hardcoded
|
|
58
|
+
- **Path Whitelisting**: Only specific endpoints in `allowed_paths` are exposed to prevent context overflow and maintain security
|
|
59
|
+
- **JSON-API Support**: Automatically wraps request bodies in JSON-API format for create/update operations
|
|
60
|
+
- **Error Resilience**: Comprehensive error handling with structured JSON error responses
|
|
61
|
+
|
|
62
|
+
### Configuration
|
|
63
|
+
|
|
64
|
+
The `allowed_paths` array in `server.py:56-92` controls which Rootly API endpoints are available. Modify this list to expose additional endpoints. Paths should be specified without the `/v1` prefix.
|
|
65
|
+
|
|
66
|
+
### Environment Variables
|
|
67
|
+
|
|
68
|
+
- `ROOTLY_API_TOKEN`: Required authentication token for Rootly API access
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Use Python 3.12 slim image as base
|
|
2
|
+
FROM python:3.12-slim
|
|
3
|
+
|
|
4
|
+
# Set working directory
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
# Install system dependencies
|
|
8
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
9
|
+
gcc curl ca-certificates \
|
|
10
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
11
|
+
|
|
12
|
+
# Install uv
|
|
13
|
+
RUN pip install --no-cache-dir uv
|
|
14
|
+
|
|
15
|
+
# Copy the entire project first for installation
|
|
16
|
+
COPY . .
|
|
17
|
+
|
|
18
|
+
# Install the package and its dependencies
|
|
19
|
+
RUN uv pip install --system --no-cache-dir -e .
|
|
20
|
+
|
|
21
|
+
# Expose the port the app runs on
|
|
22
|
+
EXPOSE 8000
|
|
23
|
+
|
|
24
|
+
# Set environment variables
|
|
25
|
+
ENV PYTHONUNBUFFERED=1
|
|
26
|
+
|
|
27
|
+
# Run the application
|
|
28
|
+
CMD ["rootly-mcp-server", "--transport", "sse", "--log-level", "INFO", "--host", "0.0.0.0", "--port", "8000", "--hosted"]
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rootly-mcp-server
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: A Model Context Protocol server for Rootly APIs using OpenAPI spec
|
|
5
|
+
Project-URL: Homepage, https://github.com/Rootly-AI-Labs/Rootly-MCP-server
|
|
6
|
+
Project-URL: Issues, https://github.com/Rootly-AI-Labs/Rootly-MCP-server/issues
|
|
7
|
+
Author-email: Rootly AI Labs <support@rootly.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: automation,incidents,llm,mcp,rootly
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Requires-Dist: fastmcp==2.4.0
|
|
18
|
+
Requires-Dist: httpx>=0.24.0
|
|
19
|
+
Requires-Dist: pydantic>=2.0.0
|
|
20
|
+
Requires-Dist: requests>=2.28.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: isort>=5.0.0; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# Rootly MCP Server
|
|
27
|
+
|
|
28
|
+
An MCP server for the [Rootly API](https://docs.rootly.com/api-reference/overview) that integrates seamlessly with MCP-compatible editors like Cursor, Windsurf, and Claude. Resolve production incidents in under a minute without leaving your IDE.
|
|
29
|
+
|
|
30
|
+
[](https://cursor.com/install-mcp?name=rootly&config=eyJjb21tYW5kIjoibnB4IC15IG1jcC1yZW1vdGUgaHR0cHM6Ly9tY3Aucm9vdGx5LmNvbS9zc2UgLS1oZWFkZXIgQXV0aG9yaXphdGlvbjoke1JPT1RMWV9BVVRIX0hFQURFUn0iLCJlbnYiOnsiUk9PVExZX0FVVEhfSEVBREVSIjoiQmVhcmVyIDxZT1VSX1JPT1RMWV9BUElfVE9LRU4%2BIn19)
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
## Prerequisites
|
|
35
|
+
|
|
36
|
+
- Python 3.12 or higher
|
|
37
|
+
- `uv` package manager
|
|
38
|
+
```bash
|
|
39
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
40
|
+
```
|
|
41
|
+
- [Rootly API token](https://docs.rootly.com/api-reference/overview#how-to-generate-an-api-key%3F)
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
Install via our [PyPi package](https://pypi.org/project/rootly-mcp-server/) or by cloning this repository.
|
|
46
|
+
|
|
47
|
+
Configure your MCP-compatible editor (tested with Cursor and Windsurf) with the following:
|
|
48
|
+
|
|
49
|
+
### With uv
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"rootly": {
|
|
55
|
+
"command": "uv",
|
|
56
|
+
"args": [
|
|
57
|
+
"tool",
|
|
58
|
+
"run",
|
|
59
|
+
"--from",
|
|
60
|
+
"rootly-mcp-server",
|
|
61
|
+
"rootly-mcp-server",
|
|
62
|
+
],
|
|
63
|
+
"env": {
|
|
64
|
+
"ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### With uv-tool-uvx
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"mcpServers": {
|
|
76
|
+
"rootly": {
|
|
77
|
+
"command": "uvx",
|
|
78
|
+
"args": [
|
|
79
|
+
"--from",
|
|
80
|
+
"rootly-mcp-server",
|
|
81
|
+
"rootly-mcp-server",
|
|
82
|
+
],
|
|
83
|
+
"env": {
|
|
84
|
+
"ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
To customize `allowed_paths` and access additional Rootly API paths, clone the repository and use this configuration:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"mcpServers": {
|
|
96
|
+
"rootly": {
|
|
97
|
+
"command": "uv",
|
|
98
|
+
"args": [
|
|
99
|
+
"run",
|
|
100
|
+
"--directory",
|
|
101
|
+
"/path/to/rootly-mcp-server",
|
|
102
|
+
"rootly-mcp-server"
|
|
103
|
+
],
|
|
104
|
+
"env": {
|
|
105
|
+
"ROOTLY_API_TOKEN": "<YOUR_ROOTLY_API_TOKEN>"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Features
|
|
113
|
+
|
|
114
|
+
- **Dynamic Tool Generation**: Automatically creates MCP resources from Rootly's OpenAPI (Swagger) specification
|
|
115
|
+
- **Smart Pagination**: Defaults to 10 items per request for incident endpoints to prevent context window overflow
|
|
116
|
+
- **API Filtering**: Limits exposed API endpoints for security and performance
|
|
117
|
+
|
|
118
|
+
### Whitelisted Endpoints
|
|
119
|
+
|
|
120
|
+
By default, the following Rootly API endpoints are exposed to the AI agent (see `allowed_paths` in `src/rootly_mcp_server/server.py`):
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
/v1/incidents
|
|
124
|
+
/v1/incidents/{incident_id}/alerts
|
|
125
|
+
/v1/alerts
|
|
126
|
+
/v1/alerts/{alert_id}
|
|
127
|
+
/v1/severities
|
|
128
|
+
/v1/severities/{severity_id}
|
|
129
|
+
/v1/teams
|
|
130
|
+
/v1/teams/{team_id}
|
|
131
|
+
/v1/services
|
|
132
|
+
/v1/services/{service_id}
|
|
133
|
+
/v1/functionalities
|
|
134
|
+
/v1/functionalities/{functionality_id}
|
|
135
|
+
/v1/incident_types
|
|
136
|
+
/v1/incident_types/{incident_type_id}
|
|
137
|
+
/v1/incident_action_items
|
|
138
|
+
/v1/incident_action_items/{incident_action_item_id}
|
|
139
|
+
/v1/incidents/{incident_id}/action_items
|
|
140
|
+
/v1/workflows
|
|
141
|
+
/v1/workflows/{workflow_id}
|
|
142
|
+
/v1/workflow_runs
|
|
143
|
+
/v1/workflow_runs/{workflow_run_id}
|
|
144
|
+
/v1/environments
|
|
145
|
+
/v1/environments/{environment_id}
|
|
146
|
+
/v1/users
|
|
147
|
+
/v1/users/{user_id}
|
|
148
|
+
/v1/users/me
|
|
149
|
+
/v1/status_pages
|
|
150
|
+
/v1/status_pages/{status_page_id}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Why Path Limiting?
|
|
154
|
+
|
|
155
|
+
We limit exposed API paths for two key reasons:
|
|
156
|
+
|
|
157
|
+
1. **Context Management**: Rootly's comprehensive API can overwhelm AI agents, affecting their ability to perform simple tasks effectively
|
|
158
|
+
2. **Security**: Control which information and actions are accessible through the MCP server
|
|
159
|
+
|
|
160
|
+
To expose additional paths, modify the `allowed_paths` variable in `src/rootly_mcp_server/server.py`.
|
|
161
|
+
|
|
162
|
+
## About Rootly AI Labs
|
|
163
|
+
|
|
164
|
+
This project was developed by [Rootly AI Labs](https://labs.rootly.ai/), where we're building the future of system reliability and operational excellence. As an open-source incubator, we share ideas, experiment, and rapidly prototype solutions that benefit the entire community.
|
|
165
|
+

|
|
166
|
+
|
|
167
|
+
## Developer Setup & Troubleshooting
|
|
168
|
+
|
|
169
|
+
### Prerequisites
|
|
170
|
+
- Python 3.12 or higher
|
|
171
|
+
- [`uv`](https://github.com/astral-sh/uv) for dependency management
|
|
172
|
+
|
|
173
|
+
### 1. Set Up Virtual Environment
|
|
174
|
+
|
|
175
|
+
Create and activate a virtual environment:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
uv venv .venv
|
|
179
|
+
source .venv/bin/activate # Always activate before running scripts
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 2. Install Dependencies
|
|
183
|
+
|
|
184
|
+
Install all project dependencies:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
uv pip install .
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
To add new dependencies during development:
|
|
191
|
+
```bash
|
|
192
|
+
uv pip install <package>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 3. Verify Installation
|
|
196
|
+
|
|
197
|
+
Run the test client to ensure everything is configured correctly:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
python test_mcp_client.py
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Connect to Hosted MCP Server
|
|
204
|
+
|
|
205
|
+
Alternatively, connect directly to our hosted MCP server:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"mcpServers": {
|
|
210
|
+
"rootly": {
|
|
211
|
+
"command": "npx",
|
|
212
|
+
"args": [
|
|
213
|
+
"-y",
|
|
214
|
+
"mcp-remote",
|
|
215
|
+
"https://mcp.rootly.com/sse",
|
|
216
|
+
"--header",
|
|
217
|
+
"Authorization:${ROOTLY_AUTH_HEADER}"
|
|
218
|
+
],
|
|
219
|
+
"env": {
|
|
220
|
+
"ROOTLY_AUTH_HEADER": "Bearer <YOUR_ROOTLY_API_TOKEN>"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|