@rockhopper-co/mcp-server 0.2.0
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.
- package/CHANGELOG.md +41 -0
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/api-client.d.ts +54 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +120 -0
- package/dist/api-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +156 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/resources/changes.d.ts +4 -0
- package/dist/resources/changes.d.ts.map +1 -0
- package/dist/resources/changes.js +33 -0
- package/dist/resources/changes.js.map +1 -0
- package/dist/resources/comments.d.ts +4 -0
- package/dist/resources/comments.d.ts.map +1 -0
- package/dist/resources/comments.js +31 -0
- package/dist/resources/comments.js.map +1 -0
- package/dist/resources/files.d.ts +4 -0
- package/dist/resources/files.d.ts.map +1 -0
- package/dist/resources/files.js +48 -0
- package/dist/resources/files.js.map +1 -0
- package/dist/resources/index.d.ts +4 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +15 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/reviews.d.ts +4 -0
- package/dist/resources/reviews.d.ts.map +1 -0
- package/dist/resources/reviews.js +40 -0
- package/dist/resources/reviews.js.map +1 -0
- package/dist/resources/teams.d.ts +4 -0
- package/dist/resources/teams.d.ts.map +1 -0
- package/dist/resources/teams.js +22 -0
- package/dist/resources/teams.js.map +1 -0
- package/dist/resources/versions.d.ts +4 -0
- package/dist/resources/versions.d.ts.map +1 -0
- package/dist/resources/versions.js +49 -0
- package/dist/resources/versions.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +22 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get-cell-history.d.ts +4 -0
- package/dist/tools/get-cell-history.d.ts.map +1 -0
- package/dist/tools/get-cell-history.js +50 -0
- package/dist/tools/get-cell-history.js.map +1 -0
- package/dist/tools/get-comments.d.ts +4 -0
- package/dist/tools/get-comments.d.ts.map +1 -0
- package/dist/tools/get-comments.js +53 -0
- package/dist/tools/get-comments.js.map +1 -0
- package/dist/tools/get-reviews.d.ts +4 -0
- package/dist/tools/get-reviews.d.ts.map +1 -0
- package/dist/tools/get-reviews.js +71 -0
- package/dist/tools/get-reviews.js.map +1 -0
- package/dist/tools/get-versions.d.ts +4 -0
- package/dist/tools/get-versions.d.ts.map +1 -0
- package/dist/tools/get-versions.js +56 -0
- package/dist/tools/get-versions.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +23 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-files.d.ts +4 -0
- package/dist/tools/list-files.d.ts.map +1 -0
- package/dist/tools/list-files.js +45 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/search.d.ts +4 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +94 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/write-comments.d.ts +4 -0
- package/dist/tools/write-comments.d.ts.map +1 -0
- package/dist/tools/write-comments.js +142 -0
- package/dist/tools/write-comments.js.map +1 -0
- package/dist/tools/write-files.d.ts +4 -0
- package/dist/tools/write-files.d.ts.map +1 -0
- package/dist/tools/write-files.js +40 -0
- package/dist/tools/write-files.js.map +1 -0
- package/dist/tools/write-reviews.d.ts +4 -0
- package/dist/tools/write-reviews.d.ts.map +1 -0
- package/dist/tools/write-reviews.js +107 -0
- package/dist/tools/write-reviews.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. Follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.2.0] — 2026-04-23
|
|
8
|
+
|
|
9
|
+
First public release on npm as `@rockhopper-co/mcp-server`.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Public npm publishing under `@rockhopper-co/mcp-server`.
|
|
13
|
+
- MIT license.
|
|
14
|
+
- GitHub Actions `ci.yml` and `publish.yml` workflows.
|
|
15
|
+
- `prepublishOnly` build hook and `release:*` version scripts.
|
|
16
|
+
- `files` whitelist so only `dist/`, `README.md`, and `LICENSE` ship.
|
|
17
|
+
- npm provenance via OIDC in the publish workflow.
|
|
18
|
+
- `tsconfig.build.json` to exclude test files from the published
|
|
19
|
+
tarball; production build now ships ~22 kB packed (vs ~80 kB before).
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Required `versionInternalId` on `add_comment` and `reply_to_comment`
|
|
23
|
+
to match backend DTO contracts.
|
|
24
|
+
- `create_review_request` now takes `versionId: number` and
|
|
25
|
+
`reviewerIds: number[]` (was `fileVersionInternalId` / `reviewerMsIds`).
|
|
26
|
+
- Removed trailing slash from sheet-scoped unattributed-changes URL to
|
|
27
|
+
match the backend route.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- Backend gap G1: `/file-versions/file/version/:versionInternalId` now
|
|
31
|
+
requires JWT/PAT auth and file-access authorization.
|
|
32
|
+
- Backend gap G5: `search` query on `/enrolled-files` now filters by
|
|
33
|
+
file name (ILIKE).
|
|
34
|
+
- Backend gap G8: PAT-authenticated file-chat requests now log a
|
|
35
|
+
warning when Excel-native OBO sync is skipped.
|
|
36
|
+
- Backend gap G9/G12: PAT traffic is now throttled via a dedicated
|
|
37
|
+
`PatThrottlerGuard` (120 req/min per user+scope).
|
|
38
|
+
|
|
39
|
+
## [0.1.0] — 2026-04-20
|
|
40
|
+
|
|
41
|
+
Internal prototype. Private package.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rockhopper Technologies, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Rockhopper MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for Rockhopper. Lets AI tools like Claude, Cursor, and Copilot interact with your Rockhopper workspace — enrolled files, version history, reviews, comments, and cell-level change tracking.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18+
|
|
8
|
+
- A Rockhopper account with at least one enrolled file
|
|
9
|
+
- A Personal Access Token (PAT) from Rockhopper
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
### 1. Create a Personal Access Token
|
|
14
|
+
|
|
15
|
+
In the Rockhopper web app, go to **Settings > Personal Access Tokens** and create a new token. Choose `read-only` scope for read access or `read-write` if you also want to add comments/reviews.
|
|
16
|
+
|
|
17
|
+
Copy the token — it's shown only once.
|
|
18
|
+
|
|
19
|
+
### 2. Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @rockhopper-co/mcp-server
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or run directly with npx:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @rockhopper-co/mcp-server
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 3. Configure your AI tool
|
|
32
|
+
|
|
33
|
+
#### Claude Desktop / Claude Code
|
|
34
|
+
|
|
35
|
+
Add to your MCP config (`~/.claude/mcp.json` or Claude Desktop settings):
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"rockhopper": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["-y", "@rockhopper-co/mcp-server"],
|
|
43
|
+
"env": {
|
|
44
|
+
"ROCKHOPPER_TOKEN": "rh_pat_your_token_here",
|
|
45
|
+
"ROCKHOPPER_API_URL": "https://api.rockhopper.co"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### Cursor
|
|
53
|
+
|
|
54
|
+
Add to `.cursor/mcp.json` in your project:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"rockhopper": {
|
|
60
|
+
"command": "npx",
|
|
61
|
+
"args": ["-y", "@rockhopper-co/mcp-server"],
|
|
62
|
+
"env": {
|
|
63
|
+
"ROCKHOPPER_TOKEN": "rh_pat_your_token_here",
|
|
64
|
+
"ROCKHOPPER_API_URL": "https://api.rockhopper.co"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Environment Variables
|
|
72
|
+
|
|
73
|
+
| Variable | Required | Default | Description |
|
|
74
|
+
|----------|----------|---------|-------------|
|
|
75
|
+
| `ROCKHOPPER_TOKEN` | Yes | — | Personal Access Token (starts with `rh_pat_`) |
|
|
76
|
+
| `ROCKHOPPER_API_URL` | No | `https://api.rockhopper.co` | Rockhopper API base URL |
|
|
77
|
+
|
|
78
|
+
## Available Tools
|
|
79
|
+
|
|
80
|
+
| Tool | Description |
|
|
81
|
+
|------|-------------|
|
|
82
|
+
| `list_files` | List enrolled Excel files with optional search filter |
|
|
83
|
+
| `get_file_versions` | Get version history for a specific file |
|
|
84
|
+
| `get_file_comments` | Get comments and threaded discussions on a file |
|
|
85
|
+
| `get_reviews` | Get review requests for a version or file |
|
|
86
|
+
| `get_cell_history` | Get change history for a specific cell across versions |
|
|
87
|
+
| `search_files` | Search enrolled files by name |
|
|
88
|
+
| `get_unattributed_changes` | Get pending cell changes not yet committed to a version |
|
|
89
|
+
|
|
90
|
+
## Available Resources
|
|
91
|
+
|
|
92
|
+
| Resource | URI | Description |
|
|
93
|
+
|----------|-----|-------------|
|
|
94
|
+
| Enrolled Files | `rockhopper://files` | All enrolled files in workspace |
|
|
95
|
+
| File Detail | `rockhopper://files/{fileMsId}` | Details for a specific file |
|
|
96
|
+
| File Versions | `rockhopper://files/{fileMsId}/versions` | Version history for a file |
|
|
97
|
+
| Version Detail | `rockhopper://versions/{versionId}` | Single version details |
|
|
98
|
+
| File Comments | `rockhopper://files/{fileMsId}/comments` | Comments on a file |
|
|
99
|
+
| Version Reviews | `rockhopper://versions/{versionId}/reviews` | Reviews for a version |
|
|
100
|
+
| Review Detail | `rockhopper://reviews/{reviewId}` | Single review details |
|
|
101
|
+
| Team Detail | `rockhopper://teams/{teamId}` | Team details with members |
|
|
102
|
+
| Unattributed Changes | `rockhopper://files/{fileMsId}/changes` | Pending changes |
|
|
103
|
+
|
|
104
|
+
## Available Prompts
|
|
105
|
+
|
|
106
|
+
| Prompt | Description |
|
|
107
|
+
|--------|-------------|
|
|
108
|
+
| `summarize-file-changes` | Summarize recent version changes and unattributed edits for a file |
|
|
109
|
+
| `pending-reviews` | Show all pending review requests for the latest version of a file |
|
|
110
|
+
| `unresolved-comments` | List all unresolved comments on a file for follow-up |
|
|
111
|
+
| `file-overview` | Comprehensive overview: versions, comments, reviews, and changes |
|
|
112
|
+
|
|
113
|
+
## Write Tools (requires `read-write` scope)
|
|
114
|
+
|
|
115
|
+
| Tool | Description |
|
|
116
|
+
|------|-------------|
|
|
117
|
+
| `add_comment` | Add a comment to an enrolled file (optionally at a cell) |
|
|
118
|
+
| `reply_to_comment` | Reply to an existing comment thread |
|
|
119
|
+
| `resolve_comment` | Mark a comment as resolved (author only) |
|
|
120
|
+
| `create_review_request` | Request a review on a file version |
|
|
121
|
+
| `approve_review` | Approve a review request (assigned reviewer only) |
|
|
122
|
+
| `update_file_description` | Update the display name of an enrolled file |
|
|
123
|
+
|
|
124
|
+
## Development
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Install dependencies
|
|
128
|
+
npm install
|
|
129
|
+
|
|
130
|
+
# Run in dev mode (auto-restart on changes)
|
|
131
|
+
npm run dev
|
|
132
|
+
|
|
133
|
+
# Build
|
|
134
|
+
npm run build
|
|
135
|
+
|
|
136
|
+
# Run tests
|
|
137
|
+
npm test
|
|
138
|
+
|
|
139
|
+
# Type check
|
|
140
|
+
npm run typecheck
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Security
|
|
144
|
+
|
|
145
|
+
- Tokens are scoped to the creating user — the MCP server can only access data the user has permission to see
|
|
146
|
+
- `read-only` tokens cannot perform write operations (comments, reviews)
|
|
147
|
+
- All API calls go through Rockhopper's existing authorization guards
|
|
148
|
+
- Tokens can be revoked instantly from the Settings page
|
|
149
|
+
- The MCP server runs locally and communicates with the API over HTTPS
|
|
150
|
+
|
|
151
|
+
## Architecture
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
AI Tool (Claude/Cursor) <--stdio--> mcp-server <--HTTPS--> Rockhopper API <--> PostgreSQL
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The MCP server is a thin adapter. It translates MCP tool/resource requests into Rockhopper REST API calls, authenticated with the user's PAT. All authorization is enforced server-side — the MCP server has no direct database access.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { CellHistoryEntry, EnrolledFile, FileChat, FileVersion, ReviewActivity, ReviewRequest, Team, UnattributedChange, UserSummary } from './types.js';
|
|
2
|
+
export interface ApiClientConfig {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
token: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class ApiClient {
|
|
7
|
+
private readonly baseUrl;
|
|
8
|
+
private readonly token;
|
|
9
|
+
constructor(config: ApiClientConfig);
|
|
10
|
+
private request;
|
|
11
|
+
getMe(): Promise<UserSummary>;
|
|
12
|
+
getTeam(teamId: number): Promise<Team>;
|
|
13
|
+
listEnrolledFiles(params?: {
|
|
14
|
+
search?: string;
|
|
15
|
+
}): Promise<EnrolledFile[]>;
|
|
16
|
+
getEnrolledFile(fileMsId: string): Promise<EnrolledFile>;
|
|
17
|
+
getFileVersions(fileMsId: string): Promise<FileVersion[]>;
|
|
18
|
+
getFileVersion(versionInternalId: number): Promise<FileVersion>;
|
|
19
|
+
getCellHistory(fileMsId: string, sheetName: string, cellAddress: string): Promise<CellHistoryEntry[]>;
|
|
20
|
+
getFileComments(fileMsId: string): Promise<FileChat[]>;
|
|
21
|
+
getComment(chatId: number): Promise<FileChat>;
|
|
22
|
+
createComment(body: {
|
|
23
|
+
fileMsId: string;
|
|
24
|
+
message: string;
|
|
25
|
+
cellReference?: string;
|
|
26
|
+
versionInternalId: number;
|
|
27
|
+
}): Promise<FileChat>;
|
|
28
|
+
replyToComment(chatId: number, body: {
|
|
29
|
+
message: string;
|
|
30
|
+
versionInternalId: number;
|
|
31
|
+
}): Promise<FileChat>;
|
|
32
|
+
resolveComment(chatId: number): Promise<FileChat>;
|
|
33
|
+
getReviewsForVersion(versionId: number): Promise<ReviewRequest[]>;
|
|
34
|
+
getReviewsForLatestVersion(fileMsId: string): Promise<ReviewRequest[]>;
|
|
35
|
+
getReview(reviewId: number): Promise<ReviewRequest>;
|
|
36
|
+
getReviewActivities(reviewId: number): Promise<ReviewActivity[]>;
|
|
37
|
+
createReviewRequest(body: {
|
|
38
|
+
versionId: number;
|
|
39
|
+
subject: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
reviewerIds: number[];
|
|
42
|
+
}): Promise<ReviewRequest>;
|
|
43
|
+
approveReview(reviewId: number, body: {
|
|
44
|
+
notes?: string;
|
|
45
|
+
}): Promise<ReviewRequest>;
|
|
46
|
+
getUnattributedChanges(fileMsId: string, params?: {
|
|
47
|
+
sheetName?: string;
|
|
48
|
+
status?: string;
|
|
49
|
+
}): Promise<UnattributedChange[]>;
|
|
50
|
+
updateEnrolledFile(fileMsId: string, body: {
|
|
51
|
+
name?: string;
|
|
52
|
+
}): Promise<EnrolledFile>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export class ApiClient {
|
|
2
|
+
baseUrl;
|
|
3
|
+
token;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
6
|
+
this.token = config.token;
|
|
7
|
+
}
|
|
8
|
+
async request(path, init) {
|
|
9
|
+
const url = `${this.baseUrl}${path}`;
|
|
10
|
+
const response = await fetch(url, {
|
|
11
|
+
...init,
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: `Bearer ${this.token}`,
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
...init?.headers,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
const body = await response.text().catch(() => '');
|
|
20
|
+
throw new Error(`Rockhopper API ${response.status}: ${response.statusText} — ${body}`);
|
|
21
|
+
}
|
|
22
|
+
return response.json();
|
|
23
|
+
}
|
|
24
|
+
// --- Users ---
|
|
25
|
+
async getMe() {
|
|
26
|
+
return this.request('/users/me');
|
|
27
|
+
}
|
|
28
|
+
// --- Teams ---
|
|
29
|
+
async getTeam(teamId) {
|
|
30
|
+
return this.request(`/teams/${teamId}`);
|
|
31
|
+
}
|
|
32
|
+
// --- Enrolled Files ---
|
|
33
|
+
async listEnrolledFiles(params) {
|
|
34
|
+
const query = new URLSearchParams();
|
|
35
|
+
if (params?.search)
|
|
36
|
+
query.set('search', params.search);
|
|
37
|
+
const qs = query.toString();
|
|
38
|
+
return this.request(`/enrolled-files${qs ? `?${qs}` : ''}`);
|
|
39
|
+
}
|
|
40
|
+
async getEnrolledFile(fileMsId) {
|
|
41
|
+
return this.request(`/enrolled-files/${fileMsId}`);
|
|
42
|
+
}
|
|
43
|
+
// --- File Versions ---
|
|
44
|
+
async getFileVersions(fileMsId) {
|
|
45
|
+
return this.request(`/file-versions/file/${fileMsId}`);
|
|
46
|
+
}
|
|
47
|
+
async getFileVersion(versionInternalId) {
|
|
48
|
+
return this.request(`/file-versions/file/version/${versionInternalId}`);
|
|
49
|
+
}
|
|
50
|
+
async getCellHistory(fileMsId, sheetName, cellAddress) {
|
|
51
|
+
const query = new URLSearchParams({ cell: cellAddress, sheetName });
|
|
52
|
+
return this.request(`/file-versions/file/${fileMsId}/cell-history?${query}`);
|
|
53
|
+
}
|
|
54
|
+
// --- File Chat (Comments) ---
|
|
55
|
+
async getFileComments(fileMsId) {
|
|
56
|
+
return this.request(`/file-chat/${fileMsId}`);
|
|
57
|
+
}
|
|
58
|
+
async getComment(chatId) {
|
|
59
|
+
return this.request(`/file-chat/single/${chatId}`);
|
|
60
|
+
}
|
|
61
|
+
async createComment(body) {
|
|
62
|
+
return this.request('/file-chat', {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async replyToComment(chatId, body) {
|
|
68
|
+
return this.request(`/file-chat/${chatId}/replies`, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
body: JSON.stringify(body),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async resolveComment(chatId) {
|
|
74
|
+
return this.request(`/file-chat/${chatId}`, {
|
|
75
|
+
method: 'PATCH',
|
|
76
|
+
body: JSON.stringify({ resolved: true }),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// --- Reviews ---
|
|
80
|
+
async getReviewsForVersion(versionId) {
|
|
81
|
+
return this.request(`/reviews/versions/${versionId}/requests`);
|
|
82
|
+
}
|
|
83
|
+
async getReviewsForLatestVersion(fileMsId) {
|
|
84
|
+
return this.request(`/reviews/files/${fileMsId}/latest-version/requests`);
|
|
85
|
+
}
|
|
86
|
+
async getReview(reviewId) {
|
|
87
|
+
return this.request(`/reviews/requests/${reviewId}`);
|
|
88
|
+
}
|
|
89
|
+
async getReviewActivities(reviewId) {
|
|
90
|
+
return this.request(`/reviews/requests/${reviewId}/activities`);
|
|
91
|
+
}
|
|
92
|
+
async createReviewRequest(body) {
|
|
93
|
+
return this.request('/reviews/requests', {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
body: JSON.stringify(body),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async approveReview(reviewId, body) {
|
|
99
|
+
return this.request(`/reviews/requests/${reviewId}/approve`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
body: JSON.stringify(body),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
// --- Unattributed Changes ---
|
|
105
|
+
async getUnattributedChanges(fileMsId, params) {
|
|
106
|
+
let path = `/unattributed-changes/${fileMsId}`;
|
|
107
|
+
if (params?.sheetName) {
|
|
108
|
+
path += `/${params.sheetName}`;
|
|
109
|
+
}
|
|
110
|
+
return this.request(path);
|
|
111
|
+
}
|
|
112
|
+
// --- File metadata update ---
|
|
113
|
+
async updateEnrolledFile(fileMsId, body) {
|
|
114
|
+
return this.request(`/enrolled-files/${fileMsId}`, {
|
|
115
|
+
method: 'PATCH',
|
|
116
|
+
body: JSON.stringify(body),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ApiClient } from './api-client.js';
|
|
4
|
+
import { createServer } from './server.js';
|
|
5
|
+
const ROCKHOPPER_API_URL = process.env.ROCKHOPPER_API_URL || 'https://api.rockhopper.co';
|
|
6
|
+
const ROCKHOPPER_TOKEN = process.env.ROCKHOPPER_TOKEN;
|
|
7
|
+
if (!ROCKHOPPER_TOKEN) {
|
|
8
|
+
console.error('Error: ROCKHOPPER_TOKEN environment variable is required.\n' +
|
|
9
|
+
'Create a Personal Access Token in Rockhopper Settings and set it as ROCKHOPPER_TOKEN.');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const apiClient = new ApiClient({
|
|
13
|
+
baseUrl: ROCKHOPPER_API_URL,
|
|
14
|
+
token: ROCKHOPPER_TOKEN,
|
|
15
|
+
});
|
|
16
|
+
const server = createServer(apiClient);
|
|
17
|
+
const transport = new StdioServerTransport();
|
|
18
|
+
await server.connect(transport);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,kBAAkB,GACtB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,2BAA2B,CAAC;AAChE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;AAEtD,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACtB,OAAO,CAAC,KAAK,CACX,6DAA6D;QAC3D,uFAAuF,CAC1F,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC;IAC9B,OAAO,EAAE,kBAAkB;IAC3B,KAAK,EAAE,gBAAgB;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AAEvC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CA4MvE"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerPrompts(server, api) {
|
|
3
|
+
server.registerPrompt('summarize-file-changes', {
|
|
4
|
+
title: 'Summarize Recent Changes',
|
|
5
|
+
description: 'Summarize recent version changes and unattributed edits for an enrolled file.',
|
|
6
|
+
argsSchema: {
|
|
7
|
+
fileMsId: z.string().describe('Platform ID of the enrolled file'),
|
|
8
|
+
},
|
|
9
|
+
}, async ({ fileMsId }) => {
|
|
10
|
+
const [file, versions, changes] = await Promise.all([
|
|
11
|
+
api.getEnrolledFile(fileMsId),
|
|
12
|
+
api.getFileVersions(fileMsId),
|
|
13
|
+
api.getUnattributedChanges(fileMsId),
|
|
14
|
+
]);
|
|
15
|
+
const recentVersions = versions.slice(0, 5);
|
|
16
|
+
const versionSummary = recentVersions
|
|
17
|
+
.map((v) => `- v${v.majorVersion}.${v.minorVersion}.${v.patchVersion}: ${v.description || 'No description'} (${v.createdAt})`)
|
|
18
|
+
.join('\n');
|
|
19
|
+
const changeSummary = changes.length
|
|
20
|
+
? changes
|
|
21
|
+
.slice(0, 20)
|
|
22
|
+
.map((c) => `- ${c.sheetName}!${c.cellAddress}: ${JSON.stringify(c.oldValue)} → ${JSON.stringify(c.newValue)}`)
|
|
23
|
+
.join('\n')
|
|
24
|
+
: 'None';
|
|
25
|
+
return {
|
|
26
|
+
messages: [
|
|
27
|
+
{
|
|
28
|
+
role: 'user',
|
|
29
|
+
content: {
|
|
30
|
+
type: 'text',
|
|
31
|
+
text: `Summarize the recent activity on the file "${file.name}".\n\n` +
|
|
32
|
+
`## Recent Versions (last ${recentVersions.length} of ${versions.length})\n${versionSummary}\n\n` +
|
|
33
|
+
`## Unattributed Changes (${changes.length} total)\n${changeSummary}\n\n` +
|
|
34
|
+
`Provide a concise summary of what has changed recently, who made changes, and any notable patterns.`,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
server.registerPrompt('pending-reviews', {
|
|
41
|
+
title: 'Pending Reviews',
|
|
42
|
+
description: 'Show all pending review requests for the latest version of a file.',
|
|
43
|
+
argsSchema: {
|
|
44
|
+
fileMsId: z.string().describe('Platform ID of the enrolled file'),
|
|
45
|
+
},
|
|
46
|
+
}, async ({ fileMsId }) => {
|
|
47
|
+
const [file, reviews] = await Promise.all([
|
|
48
|
+
api.getEnrolledFile(fileMsId),
|
|
49
|
+
api.getReviewsForLatestVersion(fileMsId),
|
|
50
|
+
]);
|
|
51
|
+
const reviewSummary = reviews.length
|
|
52
|
+
? reviews
|
|
53
|
+
.map((r) => `- "${r.subject}" (status: ${r.status}, id: ${r.id})` +
|
|
54
|
+
(r.requester
|
|
55
|
+
? ` — requested by ${r.requester.firstName} ${r.requester.lastName}`
|
|
56
|
+
: '') +
|
|
57
|
+
(r.description ? `\n Description: ${r.description}` : ''))
|
|
58
|
+
.join('\n')
|
|
59
|
+
: 'No reviews found for the latest version.';
|
|
60
|
+
return {
|
|
61
|
+
messages: [
|
|
62
|
+
{
|
|
63
|
+
role: 'user',
|
|
64
|
+
content: {
|
|
65
|
+
type: 'text',
|
|
66
|
+
text: `Show me the status of all review requests for "${file.name}".\n\n` +
|
|
67
|
+
`## Reviews on Latest Version\n${reviewSummary}\n\n` +
|
|
68
|
+
`Summarize the review status: how many are pending, approved, or need attention?`,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
server.registerPrompt('unresolved-comments', {
|
|
75
|
+
title: 'Unresolved Comments',
|
|
76
|
+
description: 'List all unresolved comments on a file for follow-up.',
|
|
77
|
+
argsSchema: {
|
|
78
|
+
fileMsId: z.string().describe('Platform ID of the enrolled file'),
|
|
79
|
+
},
|
|
80
|
+
}, async ({ fileMsId }) => {
|
|
81
|
+
const [file, comments] = await Promise.all([
|
|
82
|
+
api.getEnrolledFile(fileMsId),
|
|
83
|
+
api.getFileComments(fileMsId),
|
|
84
|
+
]);
|
|
85
|
+
const unresolved = comments.filter((c) => !c.resolved);
|
|
86
|
+
const commentSummary = unresolved.length
|
|
87
|
+
? unresolved
|
|
88
|
+
.map((c) => {
|
|
89
|
+
const author = c.authorName || c.authorEmail || 'Unknown';
|
|
90
|
+
const cell = c.cellReference ? ` [${c.cellReference}]` : '';
|
|
91
|
+
const replyCount = c.replies?.length || 0;
|
|
92
|
+
return (`- **${author}**${cell}: "${c.message}" (${c.createdAt})` +
|
|
93
|
+
(replyCount ? ` — ${replyCount} replies` : ''));
|
|
94
|
+
})
|
|
95
|
+
.join('\n')
|
|
96
|
+
: 'All comments are resolved!';
|
|
97
|
+
return {
|
|
98
|
+
messages: [
|
|
99
|
+
{
|
|
100
|
+
role: 'user',
|
|
101
|
+
content: {
|
|
102
|
+
type: 'text',
|
|
103
|
+
text: `List all unresolved comments on "${file.name}" that need follow-up.\n\n` +
|
|
104
|
+
`## Unresolved Comments (${unresolved.length} of ${comments.length} total)\n${commentSummary}\n\n` +
|
|
105
|
+
`Prioritize these comments by urgency and suggest next steps for each.`,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
server.registerPrompt('file-overview', {
|
|
112
|
+
title: 'File Overview',
|
|
113
|
+
description: 'Get a comprehensive overview of an enrolled file — versions, comments, reviews, and changes.',
|
|
114
|
+
argsSchema: {
|
|
115
|
+
fileMsId: z.string().describe('Platform ID of the enrolled file'),
|
|
116
|
+
},
|
|
117
|
+
}, async ({ fileMsId }) => {
|
|
118
|
+
const [file, versions, comments, changes] = await Promise.all([
|
|
119
|
+
api.getEnrolledFile(fileMsId),
|
|
120
|
+
api.getFileVersions(fileMsId),
|
|
121
|
+
api.getFileComments(fileMsId),
|
|
122
|
+
api.getUnattributedChanges(fileMsId),
|
|
123
|
+
]);
|
|
124
|
+
const latestVersion = versions[0];
|
|
125
|
+
let reviews = [];
|
|
126
|
+
if (latestVersion) {
|
|
127
|
+
reviews = await api.getReviewsForVersion(latestVersion.internalId);
|
|
128
|
+
}
|
|
129
|
+
const unresolvedComments = comments.filter((c) => !c.resolved);
|
|
130
|
+
const pendingReviews = reviews.filter((r) => r.status !== 'approved' && r.status !== 'rejected');
|
|
131
|
+
return {
|
|
132
|
+
messages: [
|
|
133
|
+
{
|
|
134
|
+
role: 'user',
|
|
135
|
+
content: {
|
|
136
|
+
type: 'text',
|
|
137
|
+
text: `Give me a comprehensive overview of "${file.name}".\n\n` +
|
|
138
|
+
`## File Info\n` +
|
|
139
|
+
`- Type: ${file.fileType}\n` +
|
|
140
|
+
`- Platform ID: ${file.platformId}\n` +
|
|
141
|
+
`- Uncommitted changes: ${file.hasUncommittedChanges ? 'Yes' : 'No'}\n\n` +
|
|
142
|
+
`## Versions: ${versions.length} total\n` +
|
|
143
|
+
(latestVersion
|
|
144
|
+
? `Latest: v${latestVersion.majorVersion}.${latestVersion.minorVersion}.${latestVersion.patchVersion} (${latestVersion.createdAt})\n`
|
|
145
|
+
: 'No versions yet.\n') +
|
|
146
|
+
`\n## Comments: ${comments.length} total, ${unresolvedComments.length} unresolved\n` +
|
|
147
|
+
`## Reviews: ${reviews.length} total, ${pendingReviews.length} pending\n` +
|
|
148
|
+
`## Unattributed Changes: ${changes.length}\n\n` +
|
|
149
|
+
`Provide a status report highlighting anything that needs attention.`,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAoCN"}
|