rootly-mcp-server 2.3.7__tar.gz → 2.3.9__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.
Files changed (86) hide show
  1. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/workflows/dependency-review.yml +1 -1
  2. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.gitignore +1 -0
  3. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/CHANGELOG.md +55 -0
  4. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/Dockerfile +7 -0
  5. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/PKG-INFO +97 -40
  6. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/README.md +94 -37
  7. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/pyproject.toml +3 -3
  8. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/__main__.py +56 -3
  9. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/server.py +156 -58
  10. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/server_defaults.py +130 -27
  11. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/spec_transform.py +7 -6
  12. rootly_mcp_server-2.3.9/src/rootly_mcp_server/tools/alerts.py +87 -0
  13. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/tools/incidents.py +112 -0
  14. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/tools/oncall.py +280 -310
  15. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/tools/resources.py +1 -1
  16. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/transport.py +157 -1
  17. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/utils.py +31 -0
  18. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/integration/local/test_tool_allowlists.py +6 -1
  19. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/integration/remote/test_essential.py +7 -4
  20. rootly_mcp_server-2.3.9/tests/unit/test_alert_tools.py +135 -0
  21. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_main_transport.py +152 -0
  22. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_oncall_handoff.py +364 -0
  23. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_server.py +54 -4
  24. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_server_defaults_module.py +32 -0
  25. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_tools.py +71 -0
  26. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_transport_module.py +175 -11
  27. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/uv.lock +86 -86
  28. rootly_mcp_server-2.3.7/src/rootly_mcp_server/tools/alerts.py +0 -105
  29. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.dockerignore +0 -0
  30. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.gitattributes +0 -0
  31. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/dependabot.yml +0 -0
  32. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/openapi-audit-remote-baseline.json +0 -0
  33. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/workflows/ci.yml +0 -0
  34. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/workflows/openapi-audit.yml +0 -0
  35. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.github/workflows/pypi-release.yml +0 -0
  36. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.mcp.json +0 -0
  37. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.semaphore/deploy-staging.yml +0 -0
  38. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.semaphore/deploy.yml +0 -0
  39. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.semaphore/semaphore.yml +0 -0
  40. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/.semaphore/update-task-definition.sh +0 -0
  41. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/CONTRIBUTING.md +0 -0
  42. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/LICENSE +0 -0
  43. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/examples/skills/README.md +0 -0
  44. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/gemini-extension.json +0 -0
  45. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/rootly-mcp-server-demo.gif +0 -0
  46. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/rootly_openapi.json +0 -0
  47. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/scripts/audit_openapi.py +0 -0
  48. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/scripts/setup-hooks.sh +0 -0
  49. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/server.json +0 -0
  50. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/__init__.py +0 -0
  51. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/audit.py +0 -0
  52. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/client.py +0 -0
  53. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/code_mode.py +0 -0
  54. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/data/__init__.py +0 -0
  55. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/exceptions.py +0 -0
  56. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/legacy_server.py +0 -0
  57. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/mcp_error.py +0 -0
  58. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/monitoring.py +0 -0
  59. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/och_client.py +0 -0
  60. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/pagination.py +0 -0
  61. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/payload_stripping.py +0 -0
  62. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/security.py +0 -0
  63. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/smart_utils.py +0 -0
  64. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/tools/__init__.py +0 -0
  65. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/src/rootly_mcp_server/validators.py +0 -0
  66. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/README.md +0 -0
  67. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/conftest.py +0 -0
  68. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/integration/local/test_basic.py +0 -0
  69. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/integration/local/test_smart_tools.py +0 -0
  70. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/test_client.py +0 -0
  71. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_alert_stripping.py +0 -0
  72. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_authentication.py +0 -0
  73. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_code_mode_module.py +0 -0
  74. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_exceptions.py +0 -0
  75. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_http_headers.py +0 -0
  76. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_legacy_server_module.py +0 -0
  77. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_mcp_error_module.py +0 -0
  78. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_och_client.py +0 -0
  79. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_oncall_metrics.py +0 -0
  80. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_oncall_new_tools.py +0 -0
  81. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_oncall_severity_normalization.py +0 -0
  82. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_payload_stripping_module.py +0 -0
  83. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_security.py +0 -0
  84. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_smart_utils.py +0 -0
  85. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_utils.py +0 -0
  86. {rootly_mcp_server-2.3.7 → rootly_mcp_server-2.3.9}/tests/unit/test_validators.py +0 -0
@@ -12,4 +12,4 @@ jobs:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
14
  - name: Dependency Review
15
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
15
+ uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v4
@@ -199,3 +199,4 @@ test_output/
199
199
  !CONTRIBUTING.md
200
200
  !CHANGELOG.md
201
201
  .beads/
202
+ .claude/
@@ -5,6 +5,61 @@ All notable changes to the Rootly MCP Server will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.3.9] - Released 2026-05-21
9
+
10
+ ### Performance
11
+
12
+ - **Hosted Default Tool Surface Slimmed**: Default hosted deployments now expose a curated core profile of 55 high-usage tools instead of the full 200+ tool surface, improving MCP client tool-discovery performance while preserving a broad self-hosted default
13
+ - **Hosted and Self-Hosted Defaults Split**: Hosted/serverless instances now default to the slim allowlist, while local and self-hosted deployments continue to expose the full tool catalog unless explicitly overridden
14
+
15
+ ### Configuration
16
+
17
+ - **Hosted Allowlist Override Behavior**: `ROOTLY_MCP_ENABLED_TOOLS` now cleanly overrides the hosted default profile when operators want a narrower or broader remote tool surface
18
+
19
+ ### Documentation
20
+
21
+ - **README Deployment Guidance Updated**: Documented the new hosted-versus-self-hosted tool defaults, the hosted override behavior, and the current approximate tool counts for each mode
22
+
23
+ ### Dependencies
24
+
25
+ - **Lockfile Sync**: Regenerated `uv.lock` so the lockfile matches the current pinned versions in `pyproject.toml`, including `requests==2.34.0` and `pydantic==2.13.4`
26
+
27
+ ## [2.3.8] - Released 2026-05-19
28
+
29
+ ### Security
30
+
31
+ - **Bearer Auth Enforcement on Hosted Transports**: Required Bearer authentication on MCP transport paths in hosted mode so unauthenticated requests are rejected before any tool dispatch
32
+ - **Upstream Token Validation**: Validated Bearer tokens against the upstream Rootly API before granting MCP access, surfacing malformed or expired credentials at the edge with clearer errors
33
+ - **Dependency Advisories**: Bumped `urllib3` (≥2.7.0), `python-multipart` (≥0.0.27), and `pip` (≥26.1) to resolve five open Dependabot advisories (urllib3 CVE-2026-44431/44432, python-multipart CVE-2026-42561, pip CVE-2026-6357/3219)
34
+
35
+ ### Performance
36
+
37
+ - **`get_alert_by_short_id` Now O(1)**: Replaced the up-to-20-page sequential scan with a single direct `GET /v1/alerts/{short_id}` point lookup. P95 spikes of 41s on this tool collapse to ~200ms; not-found responses no longer cost 10+ seconds; workspaces with >2,000 alerts no longer silently fail
38
+ - **`get_oncall_handoff_summary` Fan-Out Parallelized**: Replaced sequential per-schedule shift and incident fetches with `asyncio.gather` capped by a `Semaphore(10)`. Worst-case p95 of ~15s on populated workspaces drops to ~1–2s
39
+ - **Lookup-Maps Helper Parallelized**: `_fetch_users_and_schedules_maps` (used by `list_shifts`, `check_responder_availability`, `check_oncall_health_risk`, `create_override_recommendation`, `find_related_incidents`) now runs the three independent resource fetches concurrently with intra-resource page fan-out. Cold-cache worst case drops from ~15s to ~1s — meaningfully more impactful since v2.3.7 made sessions stateless and the in-memory cache is repaid more often
40
+ - **Shared `_fetch_all_pages` Helper Across Five Shift Tools**: `list_shifts`, `get_oncall_schedule_summary`, `check_responder_availability`, `create_override_recommendation`, and `check_oncall_health_risk` now all route through the same paginated, concurrency-capped helper instead of duplicating sequential pagination loops. Each tool saves 2–5s worst case under load
41
+
42
+ ### Fixed
43
+
44
+ - **`get_oncall_shift_metrics` Silent Data Loss**: The function previously fetched only page 1 of schedules and teams (no pagination loop), causing team-id filtering to silently drop schedules whose teams lived past page 1. Now uses the shared paginated, cached helper so all schedules are considered
45
+ - **OAuth Authorization Server Discovery**: Derived the OAuth authorization server URL from the API base URL so discovery works against staging and self-hosted Rootly instances
46
+ - **OAuth Protected Resource Metadata**: Removed `scopes_supported` from the protected resource metadata, advertised only the granular scopes the resource actually accepts, and included resource-specific scopes for clients that key off them
47
+ - **Pagination Resilience**: `asyncio.gather` callsites that fan out pages now use `return_exceptions=True` with an `isinstance(_, BaseException)` guard so a single transient httpx error on one page no longer aborts the entire handler
48
+ - **Missing `total_pages` Metadata Fallback**: When upstream omits `meta.total_pages`, the helper now falls back to fetching up to `max_pages` (preserving the legacy "keep going until a short page" semantics) instead of silently truncating to page 1
49
+
50
+ ### Dependencies
51
+
52
+ - **Routine Refresh**: Pulled in the latest minor and patch dependency updates from Dependabot
53
+ - **CI Action Bump**: Updated `actions/dependency-review-action` from 4.9.0 to 5.0.0
54
+
55
+ ### Repo
56
+
57
+ - **`.claude/` Ignored**: Stopped tracking transient `.claude/worktrees/` directories and added `.claude/` to `.gitignore` so local Claude Code state no longer pollutes diffs
58
+
59
+ ### Testing
60
+
61
+ - New unit tests for the parallelized fan-out paths, the missing-`total_pages` fallback, exception-tolerance in `asyncio.gather`, the `get_oncall_shift_metrics` pagination regression, and the direct-GET path for `get_alert_by_short_id`
62
+
8
63
  ## [2.3.7] - Released 2026-05-08
9
64
 
10
65
  ### Features
@@ -18,6 +18,13 @@ COPY . .
18
18
  # Install the package and its dependencies
19
19
  RUN uv pip install --system --no-cache-dir -e .
20
20
 
21
+ # Install MCPcat for hosted telemetry without changing the repo dependency graph.
22
+ # MCPcat's current package metadata pins an older Pydantic range, but the SDK
23
+ # imports successfully with our runtime pin, so we restore the server's pinned
24
+ # version after installation.
25
+ RUN uv pip install --system --no-cache-dir mcpcat==0.1.14 \
26
+ && uv pip install --system --no-cache-dir pydantic==2.13.4
27
+
21
28
  # Create non-root user
22
29
  RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
23
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rootly-mcp-server
3
- Version: 2.3.7
3
+ Version: 2.3.9
4
4
  Summary: Secure Model Context Protocol server for Rootly APIs with AI SRE capabilities, comprehensive error handling, and input validation
5
5
  Project-URL: Homepage, https://github.com/Rootly-AI-Labs/Rootly-MCP-server
6
6
  Project-URL: Issues, https://github.com/Rootly-AI-Labs/Rootly-MCP-server/issues
@@ -27,11 +27,11 @@ Requires-Dist: cryptography>=46.0.7
27
27
  Requires-Dist: fastmcp[code-mode]==3.2.4
28
28
  Requires-Dist: httpx==0.28.1
29
29
  Requires-Dist: numpy>=1.24.0
30
- Requires-Dist: pydantic==2.13.3
30
+ Requires-Dist: pydantic==2.13.4
31
31
  Requires-Dist: pygments>=2.20.0
32
32
  Requires-Dist: python-dotenv>=1.2.2
33
33
  Requires-Dist: python-multipart>=0.0.26
34
- Requires-Dist: requests==2.33.1
34
+ Requires-Dist: requests==2.34.0
35
35
  Requires-Dist: scikit-learn>=1.3.0
36
36
  Provides-Extra: dev
37
37
  Requires-Dist: bandit>=1.7.0; extra == 'dev'
@@ -65,7 +65,21 @@ Use the hosted MCP server. No local installation required.
65
65
 
66
66
  ### General Remote Setup
67
67
 
68
- Default remote config (HTTP streamable):
68
+ **With OAuth2 (recommended):**
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "rootly": {
74
+ "url": "https://mcp.rootly.com/mcp"
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ Your MCP client handles OAuth2 login automatically — a browser window opens for you to authenticate with Rootly. No API token needed.
81
+
82
+ **With API Token:**
69
83
 
70
84
  ```json
71
85
  {
@@ -86,10 +100,7 @@ SSE (alternative):
86
100
  {
87
101
  "mcpServers": {
88
102
  "rootly": {
89
- "url": "https://mcp.rootly.com/sse",
90
- "headers": {
91
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
92
- }
103
+ "url": "https://mcp.rootly.com/sse"
93
104
  }
94
105
  }
95
106
  }
@@ -101,10 +112,7 @@ Code Mode:
101
112
  {
102
113
  "mcpServers": {
103
114
  "rootly": {
104
- "url": "https://mcp.rootly.com/mcp-codemode",
105
- "headers": {
106
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
107
- }
115
+ "url": "https://mcp.rootly.com/mcp-codemode"
108
116
  }
109
117
  }
110
118
  }
@@ -117,47 +125,35 @@ Code Mode:
117
125
 
118
126
  <br>
119
127
 
120
- **Streamable HTTP**
128
+ **With OAuth2 (recommended):**
121
129
 
122
130
  ```bash
123
- claude mcp add --transport http rootly https://mcp.rootly.com/mcp \
124
- --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
125
- ```
126
-
127
- Code Mode:
131
+ claude mcp add --transport http rootly https://mcp.rootly.com/mcp
128
132
 
129
- ```bash
130
- claude mcp add rootly-codemode --transport http https://mcp.rootly.com/mcp-codemode \
131
- --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
133
+ # Code Mode:
134
+ claude mcp add --transport http rootly-codemode https://mcp.rootly.com/mcp-codemode
132
135
  ```
133
136
 
134
- SSE (alternative):
137
+ **With API Token:**
135
138
 
136
139
  ```bash
137
- claude mcp add --transport sse rootly-sse https://mcp.rootly.com/sse \
140
+ claude mcp add --transport http rootly https://mcp.rootly.com/mcp \
138
141
  --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
139
142
  ```
140
143
 
141
- **Manual Configuration**
142
-
143
- Create `.mcp.json` in your project root:
144
+ **Manual Configuration** — Create `.mcp.json` in your project root:
144
145
 
145
146
  ```json
146
147
  {
147
148
  "mcpServers": {
148
149
  "rootly": {
149
150
  "type": "http",
150
- "url": "https://mcp.rootly.com/mcp",
151
- "headers": {
152
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
153
- }
151
+ "url": "https://mcp.rootly.com/mcp"
154
152
  }
155
153
  }
156
154
  }
157
155
  ```
158
156
 
159
- Restart Claude Code after updating the config.
160
-
161
157
  </details>
162
158
 
163
159
  <details>
@@ -196,6 +192,20 @@ Or configure manually in `~/.gemini/settings.json`:
196
192
 
197
193
  Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
198
194
 
195
+ **With OAuth2 (recommended):**
196
+
197
+ ```json
198
+ {
199
+ "mcpServers": {
200
+ "rootly": {
201
+ "url": "https://mcp.rootly.com/mcp"
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ **With API Token:**
208
+
199
209
  ```json
200
210
  {
201
211
  "mcpServers": {
@@ -218,6 +228,20 @@ Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
218
228
 
219
229
  Add to `~/.codeium/windsurf/mcp_config.json`:
220
230
 
231
+ **With OAuth2 (recommended):**
232
+
233
+ ```json
234
+ {
235
+ "mcpServers": {
236
+ "rootly": {
237
+ "serverUrl": "https://mcp.rootly.com/mcp"
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ **With API Token:**
244
+
221
245
  ```json
222
246
  {
223
247
  "mcpServers": {
@@ -240,6 +264,15 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
240
264
 
241
265
  Add to `~/.codex/config.toml`:
242
266
 
267
+ **With OAuth2 (recommended):**
268
+
269
+ ```toml
270
+ [mcp_servers.rootly]
271
+ url = "https://mcp.rootly.com/mcp"
272
+ ```
273
+
274
+ **With API Token:**
275
+
243
276
  ```toml
244
277
  [mcp_servers.rootly]
245
278
  url = "https://mcp.rootly.com/mcp"
@@ -253,9 +286,23 @@ bearer_token_env_var = "ROOTLY_API_TOKEN"
253
286
 
254
287
  <br>
255
288
 
289
+ **With OAuth2 (recommended):**
290
+
256
291
  Add to `claude_desktop_config.json`:
257
292
 
258
- > **Note:** The `--transport http` flag ensures HTTP streamable transport is used instead of auto-falling back to SSE.
293
+ ```json
294
+ {
295
+ "mcpServers": {
296
+ "rootly": {
297
+ "url": "https://mcp.rootly.com/mcp"
298
+ }
299
+ }
300
+ }
301
+ ```
302
+
303
+ Claude Desktop handles OAuth2 login automatically.
304
+
305
+ **With API Token (via mcp-remote):**
259
306
 
260
307
  ```json
261
308
  {
@@ -350,7 +397,14 @@ Choose one transport per server process:
350
397
  - **SSE** endpoint path: `/sse`
351
398
  - **Code Mode (experimental)** endpoint path: `/mcp-codemode` in hosted dual-transport mode
352
399
 
353
- Both hosted and self-hosted deployments expose the same curated tool surface by default, including the default write-enabled tools. To restrict that surface to read-only tools, start the server with `--no-enable-write-tools` or set `ROOTLY_MCP_ENABLE_WRITE_TOOLS=false`.
400
+ Hosted and self-hosted deployments now have different defaults:
401
+
402
+ - Hosted defaults to a slim core profile of about 50-60 high-usage tools for better MCP client performance.
403
+ - Self-hosted keeps the full tool surface by default.
404
+
405
+ To restrict either deployment to read-only tools, start the server with `--no-enable-write-tools` or set `ROOTLY_MCP_ENABLE_WRITE_TOOLS=false`.
406
+
407
+ To override the hosted default core profile, set `ROOTLY_MCP_ENABLED_TOOLS` (or pass `--enabled-tools`) with a comma-separated allowlist of exact tool names. When that variable is set, it fully replaces the default hosted selection.
354
408
 
355
409
  To expose only a specific subset of MCP tools on a self-hosted deployment, set `ROOTLY_MCP_ENABLED_TOOLS` (or pass `--enabled-tools`) with a comma-separated allowlist of exact tool names, for example `list_incidents,getIncident,get_server_version`.
356
410
 
@@ -418,13 +472,13 @@ docker run -p 8000:8000 \
418
472
 
419
473
  ## Workflow-Focused Tool Subsets
420
474
 
421
- With 150+ tools available, you may want to configure focused subsets for optimal AI agent performance. Use `ROOTLY_MCP_ENABLED_TOOLS` to activate specific workflows:
475
+ The full self-hosted surface exposes 200+ tools, while hosted defaults to a slim core profile. If you want even tighter workflow-specific subsets, use `ROOTLY_MCP_ENABLED_TOOLS`:
422
476
 
423
477
  ### 🚨 Incident Response (25 tools)
424
478
  *Essential tools for emergency responders and incident commanders*
425
479
 
426
480
  ```bash
427
- ROOTLY_MCP_ENABLED_TOOLS="listIncidents,getIncident,createIncident,updateIncident,search_incidents,find_related_incidents,suggest_solutions,createIncidentActionItem,listIncidentActionItems,updateIncidentFormFieldSelection,listTeams,getCurrentUser,listServices,listSeverities,getAlert,listAlerts,updateAlert,listEscalationPolicies,getEscalationPolicy,listOnCallRoles,listSchedules,getScheduleShifts,get_oncall_handoff_summary,get_shift_incidents,list_endpoints"
481
+ ROOTLY_MCP_ENABLED_TOOLS="list_incidents,getIncident,createIncident,updateIncident,search_incidents,find_related_incidents,suggest_solutions,createIncidentActionItem,listIncidentActionItems,updateIncidentFormFieldSelection,listTeams,getCurrentUser,listServices,listSeverities,getAlert,listAlerts,updateAlert,listEscalationPolicies,getEscalationPolicy,listOnCallRoles,listSchedules,getScheduleShifts,get_oncall_handoff_summary,get_shift_incidents,list_endpoints"
428
482
  ```
429
483
 
430
484
  ### 📅 On-Call Management (35 tools)
@@ -452,7 +506,7 @@ ROOTLY_MCP_ENABLED_TOOLS="getIncident,updateIncident,find_related_incidents,sugg
452
506
  *For leadership and metrics teams (read-only focus)*
453
507
 
454
508
  ```bash
455
- ROOTLY_MCP_ENABLED_TOOLS="listIncidents,search_incidents,collect_incidents,listTeams,listServices,listSchedules,get_oncall_shift_metrics,get_shift_incidents,listDashboards,getDashboard,listAlerts,listHeartbeats,listPulses,getCurrentUser,list_endpoints"
509
+ ROOTLY_MCP_ENABLED_TOOLS="list_incidents,search_incidents,collect_incidents,listTeams,listServices,listSchedules,get_oncall_shift_metrics,get_shift_incidents,listDashboards,getDashboard,listAlerts,listHeartbeats,listPulses,getCurrentUser,list_endpoints"
456
510
  ```
457
511
 
458
512
  ### Multiple MCP Instances for Different Teams
@@ -466,7 +520,7 @@ You can run multiple MCP instances with different tool subsets:
466
520
  "command": "uvx", "args": ["--from", "rootly-mcp-server", "rootly-mcp-server"],
467
521
  "env": {
468
522
  "ROOTLY_API_TOKEN": "<token>",
469
- "ROOTLY_MCP_ENABLED_TOOLS": "listIncidents,getIncident,createIncident,find_related_incidents,suggest_solutions..."
523
+ "ROOTLY_MCP_ENABLED_TOOLS": "list_incidents,getIncident,createIncident,find_related_incidents,suggest_solutions..."
470
524
  }
471
525
  },
472
526
  "rootly-oncall-management": {
@@ -514,7 +568,10 @@ You can run multiple MCP instances with different tool subsets:
514
568
 
515
569
  ## Supported Tools
516
570
 
517
- The default server configuration exposes **150+ tools**.
571
+ The default tool surface depends on deployment mode:
572
+
573
+ - Hosted default: about **56 tools**
574
+ - Self-hosted default: about **218 tools**
518
575
 
519
576
  ### Custom Agentic Tools
520
577
 
@@ -610,7 +667,7 @@ listIncidentActionItems
610
667
  listIncidentAlerts
611
668
  listIncidentFormFieldSelections
612
669
  listIncident_Types
613
- listIncidents
670
+ listIncidents (deprecated alias — use `list_incidents`)
614
671
  listOnCallRoles
615
672
  listOnCallShadows
616
673
  listOverrideShifts
@@ -21,7 +21,21 @@ Use the hosted MCP server. No local installation required.
21
21
 
22
22
  ### General Remote Setup
23
23
 
24
- Default remote config (HTTP streamable):
24
+ **With OAuth2 (recommended):**
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "rootly": {
30
+ "url": "https://mcp.rootly.com/mcp"
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Your MCP client handles OAuth2 login automatically — a browser window opens for you to authenticate with Rootly. No API token needed.
37
+
38
+ **With API Token:**
25
39
 
26
40
  ```json
27
41
  {
@@ -42,10 +56,7 @@ SSE (alternative):
42
56
  {
43
57
  "mcpServers": {
44
58
  "rootly": {
45
- "url": "https://mcp.rootly.com/sse",
46
- "headers": {
47
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
48
- }
59
+ "url": "https://mcp.rootly.com/sse"
49
60
  }
50
61
  }
51
62
  }
@@ -57,10 +68,7 @@ Code Mode:
57
68
  {
58
69
  "mcpServers": {
59
70
  "rootly": {
60
- "url": "https://mcp.rootly.com/mcp-codemode",
61
- "headers": {
62
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
63
- }
71
+ "url": "https://mcp.rootly.com/mcp-codemode"
64
72
  }
65
73
  }
66
74
  }
@@ -73,47 +81,35 @@ Code Mode:
73
81
 
74
82
  <br>
75
83
 
76
- **Streamable HTTP**
84
+ **With OAuth2 (recommended):**
77
85
 
78
86
  ```bash
79
- claude mcp add --transport http rootly https://mcp.rootly.com/mcp \
80
- --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
81
- ```
82
-
83
- Code Mode:
87
+ claude mcp add --transport http rootly https://mcp.rootly.com/mcp
84
88
 
85
- ```bash
86
- claude mcp add rootly-codemode --transport http https://mcp.rootly.com/mcp-codemode \
87
- --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
89
+ # Code Mode:
90
+ claude mcp add --transport http rootly-codemode https://mcp.rootly.com/mcp-codemode
88
91
  ```
89
92
 
90
- SSE (alternative):
93
+ **With API Token:**
91
94
 
92
95
  ```bash
93
- claude mcp add --transport sse rootly-sse https://mcp.rootly.com/sse \
96
+ claude mcp add --transport http rootly https://mcp.rootly.com/mcp \
94
97
  --header "Authorization: Bearer YOUR_ROOTLY_API_TOKEN"
95
98
  ```
96
99
 
97
- **Manual Configuration**
98
-
99
- Create `.mcp.json` in your project root:
100
+ **Manual Configuration** — Create `.mcp.json` in your project root:
100
101
 
101
102
  ```json
102
103
  {
103
104
  "mcpServers": {
104
105
  "rootly": {
105
106
  "type": "http",
106
- "url": "https://mcp.rootly.com/mcp",
107
- "headers": {
108
- "Authorization": "Bearer YOUR_ROOTLY_API_TOKEN"
109
- }
107
+ "url": "https://mcp.rootly.com/mcp"
110
108
  }
111
109
  }
112
110
  }
113
111
  ```
114
112
 
115
- Restart Claude Code after updating the config.
116
-
117
113
  </details>
118
114
 
119
115
  <details>
@@ -152,6 +148,20 @@ Or configure manually in `~/.gemini/settings.json`:
152
148
 
153
149
  Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
154
150
 
151
+ **With OAuth2 (recommended):**
152
+
153
+ ```json
154
+ {
155
+ "mcpServers": {
156
+ "rootly": {
157
+ "url": "https://mcp.rootly.com/mcp"
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ **With API Token:**
164
+
155
165
  ```json
156
166
  {
157
167
  "mcpServers": {
@@ -174,6 +184,20 @@ Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
174
184
 
175
185
  Add to `~/.codeium/windsurf/mcp_config.json`:
176
186
 
187
+ **With OAuth2 (recommended):**
188
+
189
+ ```json
190
+ {
191
+ "mcpServers": {
192
+ "rootly": {
193
+ "serverUrl": "https://mcp.rootly.com/mcp"
194
+ }
195
+ }
196
+ }
197
+ ```
198
+
199
+ **With API Token:**
200
+
177
201
  ```json
178
202
  {
179
203
  "mcpServers": {
@@ -196,6 +220,15 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
196
220
 
197
221
  Add to `~/.codex/config.toml`:
198
222
 
223
+ **With OAuth2 (recommended):**
224
+
225
+ ```toml
226
+ [mcp_servers.rootly]
227
+ url = "https://mcp.rootly.com/mcp"
228
+ ```
229
+
230
+ **With API Token:**
231
+
199
232
  ```toml
200
233
  [mcp_servers.rootly]
201
234
  url = "https://mcp.rootly.com/mcp"
@@ -209,9 +242,23 @@ bearer_token_env_var = "ROOTLY_API_TOKEN"
209
242
 
210
243
  <br>
211
244
 
245
+ **With OAuth2 (recommended):**
246
+
212
247
  Add to `claude_desktop_config.json`:
213
248
 
214
- > **Note:** The `--transport http` flag ensures HTTP streamable transport is used instead of auto-falling back to SSE.
249
+ ```json
250
+ {
251
+ "mcpServers": {
252
+ "rootly": {
253
+ "url": "https://mcp.rootly.com/mcp"
254
+ }
255
+ }
256
+ }
257
+ ```
258
+
259
+ Claude Desktop handles OAuth2 login automatically.
260
+
261
+ **With API Token (via mcp-remote):**
215
262
 
216
263
  ```json
217
264
  {
@@ -306,7 +353,14 @@ Choose one transport per server process:
306
353
  - **SSE** endpoint path: `/sse`
307
354
  - **Code Mode (experimental)** endpoint path: `/mcp-codemode` in hosted dual-transport mode
308
355
 
309
- Both hosted and self-hosted deployments expose the same curated tool surface by default, including the default write-enabled tools. To restrict that surface to read-only tools, start the server with `--no-enable-write-tools` or set `ROOTLY_MCP_ENABLE_WRITE_TOOLS=false`.
356
+ Hosted and self-hosted deployments now have different defaults:
357
+
358
+ - Hosted defaults to a slim core profile of about 50-60 high-usage tools for better MCP client performance.
359
+ - Self-hosted keeps the full tool surface by default.
360
+
361
+ To restrict either deployment to read-only tools, start the server with `--no-enable-write-tools` or set `ROOTLY_MCP_ENABLE_WRITE_TOOLS=false`.
362
+
363
+ To override the hosted default core profile, set `ROOTLY_MCP_ENABLED_TOOLS` (or pass `--enabled-tools`) with a comma-separated allowlist of exact tool names. When that variable is set, it fully replaces the default hosted selection.
310
364
 
311
365
  To expose only a specific subset of MCP tools on a self-hosted deployment, set `ROOTLY_MCP_ENABLED_TOOLS` (or pass `--enabled-tools`) with a comma-separated allowlist of exact tool names, for example `list_incidents,getIncident,get_server_version`.
312
366
 
@@ -374,13 +428,13 @@ docker run -p 8000:8000 \
374
428
 
375
429
  ## Workflow-Focused Tool Subsets
376
430
 
377
- With 150+ tools available, you may want to configure focused subsets for optimal AI agent performance. Use `ROOTLY_MCP_ENABLED_TOOLS` to activate specific workflows:
431
+ The full self-hosted surface exposes 200+ tools, while hosted defaults to a slim core profile. If you want even tighter workflow-specific subsets, use `ROOTLY_MCP_ENABLED_TOOLS`:
378
432
 
379
433
  ### 🚨 Incident Response (25 tools)
380
434
  *Essential tools for emergency responders and incident commanders*
381
435
 
382
436
  ```bash
383
- ROOTLY_MCP_ENABLED_TOOLS="listIncidents,getIncident,createIncident,updateIncident,search_incidents,find_related_incidents,suggest_solutions,createIncidentActionItem,listIncidentActionItems,updateIncidentFormFieldSelection,listTeams,getCurrentUser,listServices,listSeverities,getAlert,listAlerts,updateAlert,listEscalationPolicies,getEscalationPolicy,listOnCallRoles,listSchedules,getScheduleShifts,get_oncall_handoff_summary,get_shift_incidents,list_endpoints"
437
+ ROOTLY_MCP_ENABLED_TOOLS="list_incidents,getIncident,createIncident,updateIncident,search_incidents,find_related_incidents,suggest_solutions,createIncidentActionItem,listIncidentActionItems,updateIncidentFormFieldSelection,listTeams,getCurrentUser,listServices,listSeverities,getAlert,listAlerts,updateAlert,listEscalationPolicies,getEscalationPolicy,listOnCallRoles,listSchedules,getScheduleShifts,get_oncall_handoff_summary,get_shift_incidents,list_endpoints"
384
438
  ```
385
439
 
386
440
  ### 📅 On-Call Management (35 tools)
@@ -408,7 +462,7 @@ ROOTLY_MCP_ENABLED_TOOLS="getIncident,updateIncident,find_related_incidents,sugg
408
462
  *For leadership and metrics teams (read-only focus)*
409
463
 
410
464
  ```bash
411
- ROOTLY_MCP_ENABLED_TOOLS="listIncidents,search_incidents,collect_incidents,listTeams,listServices,listSchedules,get_oncall_shift_metrics,get_shift_incidents,listDashboards,getDashboard,listAlerts,listHeartbeats,listPulses,getCurrentUser,list_endpoints"
465
+ ROOTLY_MCP_ENABLED_TOOLS="list_incidents,search_incidents,collect_incidents,listTeams,listServices,listSchedules,get_oncall_shift_metrics,get_shift_incidents,listDashboards,getDashboard,listAlerts,listHeartbeats,listPulses,getCurrentUser,list_endpoints"
412
466
  ```
413
467
 
414
468
  ### Multiple MCP Instances for Different Teams
@@ -422,7 +476,7 @@ You can run multiple MCP instances with different tool subsets:
422
476
  "command": "uvx", "args": ["--from", "rootly-mcp-server", "rootly-mcp-server"],
423
477
  "env": {
424
478
  "ROOTLY_API_TOKEN": "<token>",
425
- "ROOTLY_MCP_ENABLED_TOOLS": "listIncidents,getIncident,createIncident,find_related_incidents,suggest_solutions..."
479
+ "ROOTLY_MCP_ENABLED_TOOLS": "list_incidents,getIncident,createIncident,find_related_incidents,suggest_solutions..."
426
480
  }
427
481
  },
428
482
  "rootly-oncall-management": {
@@ -470,7 +524,10 @@ You can run multiple MCP instances with different tool subsets:
470
524
 
471
525
  ## Supported Tools
472
526
 
473
- The default server configuration exposes **150+ tools**.
527
+ The default tool surface depends on deployment mode:
528
+
529
+ - Hosted default: about **56 tools**
530
+ - Self-hosted default: about **218 tools**
474
531
 
475
532
  ### Custom Agentic Tools
476
533
 
@@ -566,7 +623,7 @@ listIncidentActionItems
566
623
  listIncidentAlerts
567
624
  listIncidentFormFieldSelections
568
625
  listIncident_Types
569
- listIncidents
626
+ listIncidents (deprecated alias — use `list_incidents`)
570
627
  listOnCallRoles
571
628
  listOnCallShadows
572
629
  listOverrideShifts
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "rootly-mcp-server"
3
- version = "2.3.7"
3
+ version = "2.3.9"
4
4
  description = "Secure Model Context Protocol server for Rootly APIs with AI SRE capabilities, comprehensive error handling, and input validation"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -42,9 +42,9 @@ dependencies = [
42
42
  "python-multipart>=0.0.26", # Override vulnerable transitive python-multipart (CVE-2026-40347)
43
43
  "cryptography>=46.0.7", # Override vulnerable transitive cryptography
44
44
  "Pygments>=2.20.0", # Override vulnerable transitive Pygments
45
- "requests==2.33.1", # Pin to patched version
45
+ "requests==2.34.0", # Pin to patched version
46
46
  "httpx==0.28.1", # Pin to specific version
47
- "pydantic==2.13.3", # Pin to specific version
47
+ "pydantic==2.13.4", # Pin to specific version
48
48
  "brotli>=1.2.0", # For Brotli compression support in httpx
49
49
  "scikit-learn>=1.3.0", # For text similarity and ML utilities
50
50
  "numpy>=1.24.0", # For numerical operations