@rockhopper-co/mcp-server 0.4.0 → 0.5.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 +36 -0
- package/dist/resources/changes.d.ts.map +1 -1
- package/dist/resources/changes.js +4 -12
- package/dist/resources/changes.js.map +1 -1
- package/dist/resources/comments.d.ts.map +1 -1
- package/dist/resources/comments.js +2 -10
- package/dist/resources/comments.js.map +1 -1
- package/dist/resources/files.d.ts.map +1 -1
- package/dist/resources/files.js +5 -11
- package/dist/resources/files.js.map +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +2 -0
- package/dist/resources/index.js.map +1 -1
- package/dist/resources/orchestration-guide.d.ts +3 -0
- package/dist/resources/orchestration-guide.d.ts.map +1 -0
- package/dist/resources/orchestration-guide.js +26 -0
- package/dist/resources/orchestration-guide.js.map +1 -0
- package/dist/resources/orchestration-guide.md +120 -0
- package/dist/resources/versions.d.ts.map +1 -1
- package/dist/resources/versions.js +2 -10
- package/dist/resources/versions.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,42 @@ All notable changes to this project are documented here. Follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.5.0] — 2026-05-12
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **`resources/list` no longer enumerates per-file instances.** The 4
|
|
11
|
+
per-file resource templates (`enrolled-file`, `file-versions`,
|
|
12
|
+
`file-comments`, `unattributed-changes`) previously expanded into one
|
|
13
|
+
concrete resource per enrolled file via their `list:` callbacks,
|
|
14
|
+
bloating the response to 44+ entries at single-digit file counts and
|
|
15
|
+
~400 at 100 files. They now appear in `resources/templates/list`
|
|
16
|
+
semantics instead — AI clients learn the URI pattern and construct
|
|
17
|
+
concrete URIs on demand. `resources/list` stays at a small static set
|
|
18
|
+
regardless of workspace size. Closes KI-078 / ENG-1381.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- **`rockhopper://orchestration-guide` resource.** Static markdown
|
|
22
|
+
resource that documents tool sequencing, identity disambiguation
|
|
23
|
+
(`fileMsId` vs `versionId` vs `versionInternalId`), the comment and
|
|
24
|
+
review lifecycles, versioning rules, and cross-cloud (Microsoft vs
|
|
25
|
+
Google Sheets) differences. AI clients can read it once at session
|
|
26
|
+
start to avoid common tool-sequencing errors. Backed by
|
|
27
|
+
`src/resources/orchestration-guide.md`. Closes KI-079 / ENG-1382.
|
|
28
|
+
|
|
29
|
+
### Internal
|
|
30
|
+
- Build step now copies `src/**/*.md` into `dist/` so non-`.ts` assets
|
|
31
|
+
ship with the package (`scripts/copy-non-ts-assets.mjs`).
|
|
32
|
+
- Unit and e2e test updates: assert `resources/list` returns exactly 2
|
|
33
|
+
static entries and `resources/templates/list` returns the 8 URI
|
|
34
|
+
templates; new test reads the orchestration-guide content.
|
|
35
|
+
- Regenerated Postman collection (16 tools, 10 resources, 4 prompts).
|
|
36
|
+
|
|
37
|
+
### Breaking changes
|
|
38
|
+
- Behavior change in `resources/list` response shape. Downstream
|
|
39
|
+
consumers that cached the previous per-file enumeration must refresh
|
|
40
|
+
their resource lists. No tool, prompt, or resource-read semantics
|
|
41
|
+
changed — only the `resources/list` response.
|
|
42
|
+
|
|
7
43
|
## [0.4.0] — 2026-05-03
|
|
8
44
|
|
|
9
45
|
### Added
|
|
@@ -1 +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,
|
|
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,CA4BN"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
export function registerChangeResources(server, api) {
|
|
3
|
+
// KI-078 (ENG-1381): template only, no per-file expansion into resources/list.
|
|
4
|
+
// Previously this enumerated only files with `hasUncommittedChanges === true` —
|
|
5
|
+
// a per-call API request that scaled linearly with file count.
|
|
3
6
|
server.registerResource('unattributed-changes', new ResourceTemplate('rockhopper://files/{fileMsId}/changes', {
|
|
4
|
-
list:
|
|
5
|
-
const files = await api.listEnrolledFiles();
|
|
6
|
-
return {
|
|
7
|
-
resources: files
|
|
8
|
-
.filter((f) => f.hasUncommittedChanges)
|
|
9
|
-
.map((f) => ({
|
|
10
|
-
uri: `rockhopper://files/${f.platformId}/changes`,
|
|
11
|
-
name: `Unattributed changes in ${f.name}`,
|
|
12
|
-
mimeType: 'application/json',
|
|
13
|
-
})),
|
|
14
|
-
};
|
|
15
|
-
},
|
|
7
|
+
list: undefined,
|
|
16
8
|
}), {
|
|
17
9
|
title: 'Unattributed Changes',
|
|
18
10
|
description: 'Pending cell-level changes not yet attributed to a version for a file',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,GAAc;IAEd,MAAM,CAAC,gBAAgB,CACrB,sBAAsB,EACtB,IAAI,gBAAgB,CAAC,uCAAuC,EAAE;QAC5D,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,GAAc;IAEd,+EAA+E;IAC/E,gFAAgF;IAChF,+DAA+D;IAC/D,MAAM,CAAC,gBAAgB,CACrB,sBAAsB,EACtB,IAAI,gBAAgB,CAAC,uCAAuC,EAAE;QAC5D,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,uEAAuE;QACzE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,sBAAsB,CAAC,QAAkB,CAAC,CAAC;QACrE,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/resources/comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/resources/comments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CA0BN"}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
export function registerCommentResources(server, api) {
|
|
3
|
+
// KI-078 (ENG-1381): template only, no per-file expansion into resources/list.
|
|
3
4
|
server.registerResource('file-comments', new ResourceTemplate('rockhopper://files/{fileMsId}/comments', {
|
|
4
|
-
list:
|
|
5
|
-
const files = await api.listEnrolledFiles();
|
|
6
|
-
return {
|
|
7
|
-
resources: files.map((f) => ({
|
|
8
|
-
uri: `rockhopper://files/${f.platformId}/comments`,
|
|
9
|
-
name: `Comments on ${f.name}`,
|
|
10
|
-
mimeType: 'application/json',
|
|
11
|
-
})),
|
|
12
|
-
};
|
|
13
|
-
},
|
|
5
|
+
list: undefined,
|
|
14
6
|
}), {
|
|
15
7
|
title: 'File Comments',
|
|
16
8
|
description: 'All comments and chat threads on a specific enrolled file',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/resources/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAc;IAEd,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,wCAAwC,EAAE;QAC7D,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/resources/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAc;IAEd,+EAA+E;IAC/E,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,wCAAwC,EAAE;QAC7D,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,2DAA2D;QAC7D,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,QAAkB,CAAC,CAAC;QAC/D,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/resources/files.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/resources/files.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAmDN"}
|
package/dist/resources/files.js
CHANGED
|
@@ -16,18 +16,12 @@ export function registerFileResources(server, api) {
|
|
|
16
16
|
],
|
|
17
17
|
};
|
|
18
18
|
});
|
|
19
|
+
// KI-078 (ENG-1381): the per-file template no longer enumerates `resources/list`.
|
|
20
|
+
// It is exposed via `resources/templates/list` so AI clients learn the URI pattern;
|
|
21
|
+
// concrete instances are read by URI on demand (e.g. `rockhopper://files/abc123`).
|
|
22
|
+
// The workspace-level `rockhopper://files` listing above is the discovery entry point.
|
|
19
23
|
server.registerResource('enrolled-file', new ResourceTemplate('rockhopper://files/{fileMsId}', {
|
|
20
|
-
list:
|
|
21
|
-
const files = await api.listEnrolledFiles();
|
|
22
|
-
return {
|
|
23
|
-
resources: files.map((f) => ({
|
|
24
|
-
uri: `rockhopper://files/${f.platformId}`,
|
|
25
|
-
name: f.name,
|
|
26
|
-
description: `${f.name} (${f.fileType})`,
|
|
27
|
-
mimeType: 'application/json',
|
|
28
|
-
})),
|
|
29
|
-
};
|
|
30
|
-
},
|
|
24
|
+
list: undefined,
|
|
31
25
|
}), {
|
|
32
26
|
title: 'Enrolled File Details',
|
|
33
27
|
description: 'Details for a specific enrolled file by its platform ID',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/resources/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,GAAc;IAEd,MAAM,CAAC,gBAAgB,CACrB,gBAAgB,EAChB,oBAAoB,EACpB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,sEAAsE;QACxE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC5C,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,+BAA+B,EAAE;QACpD,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/resources/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,GAAc;IAEd,MAAM,CAAC,gBAAgB,CACrB,gBAAgB,EAChB,oBAAoB,EACpB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,sEAAsE;QACxE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC5C,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,kFAAkF;IAClF,oFAAoF;IACpF,mFAAmF;IACnF,uFAAuF;IACvF,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,+BAA+B,EAAE;QACpD,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,yDAAyD;QACtE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,QAAkB,CAAC,CAAC;QAC3D,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBACpC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AASlD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAQN"}
|
package/dist/resources/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { registerCommentResources } from './comments.js';
|
|
|
4
4
|
import { registerReviewResources } from './reviews.js';
|
|
5
5
|
import { registerTeamResources } from './teams.js';
|
|
6
6
|
import { registerChangeResources } from './changes.js';
|
|
7
|
+
import { registerOrchestrationGuideResource } from './orchestration-guide.js';
|
|
7
8
|
export function registerResources(server, api) {
|
|
8
9
|
registerFileResources(server, api);
|
|
9
10
|
registerVersionResources(server, api);
|
|
@@ -11,5 +12,6 @@ export function registerResources(server, api) {
|
|
|
11
12
|
registerReviewResources(server, api);
|
|
12
13
|
registerTeamResources(server, api);
|
|
13
14
|
registerChangeResources(server, api);
|
|
15
|
+
registerOrchestrationGuideResource(server);
|
|
14
16
|
}
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,kCAAkC,EAAE,MAAM,0BAA0B,CAAC;AAE9E,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,GAAc;IAEd,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,kCAAkC,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestration-guide.d.ts","sourceRoot":"","sources":["../../src/resources/orchestration-guide.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoB1E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const ORCHESTRATION_GUIDE_URI = 'rockhopper://orchestration-guide';
|
|
5
|
+
// KI-079 (ENG-1382): static narrative resource that documents tool sequencing,
|
|
6
|
+
// identity disambiguation (`fileMsId` vs `versionId` vs `versionInternalId`),
|
|
7
|
+
// and lifecycle rules. Loaded once at module init from the sibling .md file;
|
|
8
|
+
// the build copies the .md into `dist/resources/` so it ships with the package.
|
|
9
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const guideContent = readFileSync(join(moduleDir, 'orchestration-guide.md'), 'utf8');
|
|
11
|
+
export function registerOrchestrationGuideResource(server) {
|
|
12
|
+
server.registerResource('orchestration-guide', ORCHESTRATION_GUIDE_URI, {
|
|
13
|
+
title: 'Orchestration Guide',
|
|
14
|
+
description: 'Narrative reference for sequencing Rockhopper MCP tools correctly — identity types, workflows, review lifecycle, versioning rules, cross-cloud differences.',
|
|
15
|
+
mimeType: 'text/markdown',
|
|
16
|
+
}, async (uri) => ({
|
|
17
|
+
contents: [
|
|
18
|
+
{
|
|
19
|
+
uri: uri.href,
|
|
20
|
+
mimeType: 'text/markdown',
|
|
21
|
+
text: guideContent,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=orchestration-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestration-guide.js","sourceRoot":"","sources":["../../src/resources/orchestration-guide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,uBAAuB,GAAG,kCAAkC,CAAC;AAEnE,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,gFAAgF;AAChF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,YAAY,GAAG,YAAY,CAC/B,IAAI,CAAC,SAAS,EAAE,wBAAwB,CAAC,EACzC,MAAM,CACP,CAAC;AAEF,MAAM,UAAU,kCAAkC,CAAC,MAAiB;IAClE,MAAM,CAAC,gBAAgB,CACrB,qBAAqB,EACrB,uBAAuB,EACvB;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,6JAA6J;QAC/J,QAAQ,EAAE,eAAe;KAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,eAAe;gBACzB,IAAI,EAAE,YAAY;aACnB;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Rockhopper MCP — orchestration guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to combine Rockhopper's MCP tools and resources correctly. Read it before sequencing multiple tool calls — it documents the prerequisites, identity types, and lifecycle rules that the individual tool descriptions cannot show in isolation.
|
|
4
|
+
|
|
5
|
+
## 1. Identity and IDs
|
|
6
|
+
|
|
7
|
+
Rockhopper uses three distinct identifiers. Mixing them is the most common cause of tool-call errors.
|
|
8
|
+
|
|
9
|
+
| ID | Type | Where it comes from | Where it goes |
|
|
10
|
+
|----|------|---------------------|---------------|
|
|
11
|
+
| `fileMsId` | string | `list_files` response, `rockhopper://files` resource | Tools that act on a file: `get_file_versions`, `get_file_comments`, `add_comment`, `create_version`, `discard_changes`, `get_cell_history`, `get_unattributed_changes`, `update_file_description` |
|
|
12
|
+
| `versionId` | number | `get_file_versions` response (`internalId` field), `create_version` response | Tools that act on a specific version snapshot: `get_reviews`, `create_review_request`, `approve_review`, `cancel_review` |
|
|
13
|
+
| `versionInternalId` | number | `get_file_comments` response (comments scope to a version) | Comment-thread tools: `add_comment`, `reply_to_comment`, `resolve_comment` |
|
|
14
|
+
|
|
15
|
+
Decision tree:
|
|
16
|
+
|
|
17
|
+
- **Reading file metadata** → `fileMsId`.
|
|
18
|
+
- **Writing a comment** → `fileMsId` (the server auto-resolves the latest version) OR `versionInternalId` if commenting on a historical version.
|
|
19
|
+
- **Acting on a review** → `versionId`.
|
|
20
|
+
|
|
21
|
+
If a tool returns an error like "expected versionId but received fileMsId", you used the wrong identifier — check the tool description for which type it accepts.
|
|
22
|
+
|
|
23
|
+
## 2. Reading workflow
|
|
24
|
+
|
|
25
|
+
Standard sequence to inspect a file:
|
|
26
|
+
|
|
27
|
+
1. `list_files` — discover enrolled files. Returns `fileMsId`, `name`, `fileType`, `hasUncommittedChanges`.
|
|
28
|
+
2. `get_file_versions(fileMsId)` — version history. Each entry has `internalId` (this is the `versionId`).
|
|
29
|
+
3. Branch:
|
|
30
|
+
- File contents at a specific version → `get_cell_history(fileMsId, sheet, cellAddress)`.
|
|
31
|
+
- Comments → `get_file_comments(fileMsId)`. Filters to the latest live version by default.
|
|
32
|
+
- Reviews → `get_reviews(versionId)`. Pass a `versionId` from step 2.
|
|
33
|
+
- Uncommitted changes → `get_unattributed_changes(fileMsId)` (only useful if `hasUncommittedChanges === true`).
|
|
34
|
+
|
|
35
|
+
## 3. Commenting workflow
|
|
36
|
+
|
|
37
|
+
Comments are scoped to a version. The default version is the latest **committed** one.
|
|
38
|
+
|
|
39
|
+
1. `add_comment({ fileMsId, message, cellReference })` — creates a top-level comment on the latest version.
|
|
40
|
+
2. `reply_to_comment({ parentCommentId, message })` — `parentCommentId` is the `internalId` from `get_file_comments`, **not** a substring or message match.
|
|
41
|
+
3. `resolve_comment({ commentId })` — closes a thread. Idempotent — calling on an already-resolved comment is a no-op (returns the existing record).
|
|
42
|
+
|
|
43
|
+
Comments on historical versions:
|
|
44
|
+
|
|
45
|
+
- Pass `versionInternalId` explicitly to `add_comment` to comment on a historical version snapshot.
|
|
46
|
+
- `get_file_comments` accepts `versionInternalId` if you want to read historical-version comments rather than the current set.
|
|
47
|
+
|
|
48
|
+
## 4. Review lifecycle
|
|
49
|
+
|
|
50
|
+
Reviews follow a strict state machine: **`pending` → `approved`** or **`pending` → `cancelled`**. No other transitions are valid.
|
|
51
|
+
|
|
52
|
+
1. `create_review_request({ versionId, reviewerEmails, subject, description? })` — creates a `pending` review. Only the file owner / workspace member with edit rights can create.
|
|
53
|
+
2. `approve_review({ reviewId })` — moves `pending` → `approved`. **Only** assigned reviewers can approve.
|
|
54
|
+
3. `cancel_review({ reviewId })` — moves `pending` → `cancelled`. **Only** the requester can cancel.
|
|
55
|
+
|
|
56
|
+
Calling `approve_review` before `create_review_request` returns a 404 — there is no review to approve. Calling `approve_review` on an already-approved or cancelled review returns a 409 conflict.
|
|
57
|
+
|
|
58
|
+
## 5. Versioning
|
|
59
|
+
|
|
60
|
+
`create_version` snapshots the file's current uncommitted state as a new version.
|
|
61
|
+
|
|
62
|
+
Rules:
|
|
63
|
+
|
|
64
|
+
- **Requires uncommitted changes.** If `get_unattributed_changes(fileMsId)` returns an empty list, `create_version` will fail with "no changes to commit".
|
|
65
|
+
- **Auto-bumps semver** from the latest committed version. Defaults to patch (`1.0.0` → `1.0.1`). Pass `bumpType: 'minor' | 'major'` to override.
|
|
66
|
+
- **Optional `description`** — a one-line changelog entry. Recommended for any non-trivial version.
|
|
67
|
+
|
|
68
|
+
`discard_changes(fileMsId)` is the **destructive** alternative: it wipes uncommitted edits without creating a snapshot. Use only when the user explicitly asks to throw away unsaved work — call `get_unattributed_changes(fileMsId)` first and confirm with the user before discarding anything substantive.
|
|
69
|
+
|
|
70
|
+
## 6. Uncommitted changes vs. committed history
|
|
71
|
+
|
|
72
|
+
Two distinct concepts. Tools work with one or the other; do not mix.
|
|
73
|
+
|
|
74
|
+
- **Committed history** — version snapshots created by `create_version`. Surfaced by `get_file_versions`, `get_cell_history`. Immutable.
|
|
75
|
+
- **Uncommitted changes** — cell edits the user has made since the last `create_version`. Surfaced by `get_unattributed_changes`. Mutable; consumed by the next `create_version` or `discard_changes` call.
|
|
76
|
+
|
|
77
|
+
Common mistake: calling `get_cell_history` to inspect a recent edit before it has been committed. `get_cell_history` only returns committed values — use `get_unattributed_changes` for pending edits.
|
|
78
|
+
|
|
79
|
+
## 7. Cross-cloud differences
|
|
80
|
+
|
|
81
|
+
Rockhopper supports both Microsoft Excel files (M365 / OneDrive) and Google Sheets. Tool calls work transparently across both, but the identifiers carry different meanings:
|
|
82
|
+
|
|
83
|
+
| Field | Microsoft Excel | Google Sheets |
|
|
84
|
+
|-------|------------------|----------------|
|
|
85
|
+
| `fileType` | `microsoft_xlsx` | `google_sheets` |
|
|
86
|
+
| `driveMsId` | OneDrive / SharePoint drive ID | Google Drive file ID (yes, the field name is misleading for the Google case) |
|
|
87
|
+
| `platformId` (= `fileMsId`) | Microsoft graph file ID | Google Drive file ID |
|
|
88
|
+
|
|
89
|
+
If a tool description references "drive ID" or "platform ID", it works identically across both clouds. If you need to know the platform, inspect `fileType`.
|
|
90
|
+
|
|
91
|
+
## 8. Error handling
|
|
92
|
+
|
|
93
|
+
Tool failures return structured responses with `isError: true` and a human-readable message in `content`. Common patterns:
|
|
94
|
+
|
|
95
|
+
- **404 / "not found"** — usually a wrong-identifier-type error. Re-check the IDs section above.
|
|
96
|
+
- **409 / "conflict"** — state-machine violation (e.g. approving an already-approved review).
|
|
97
|
+
- **403 / "forbidden"** — permission error (e.g. non-reviewer calling `approve_review`).
|
|
98
|
+
- **5xx** — server-side error. Retry once; if it persists, surface the error to the user — don't loop.
|
|
99
|
+
|
|
100
|
+
When a tool returns `isError: true`, do not silently retry with the same arguments. Either correct the arguments based on the error message or surface the failure.
|
|
101
|
+
|
|
102
|
+
## 9. Resources
|
|
103
|
+
|
|
104
|
+
The MCP server exposes two static resources via `resources/list`:
|
|
105
|
+
|
|
106
|
+
- `rockhopper://files` — workspace-level enrolled files listing. Same data as `list_files` tool.
|
|
107
|
+
- `rockhopper://orchestration-guide` — this document.
|
|
108
|
+
|
|
109
|
+
Eight URI templates via `resources/templates/list` — read these by constructing a concrete URI from the template pattern:
|
|
110
|
+
|
|
111
|
+
- `rockhopper://files/{fileMsId}` — file details
|
|
112
|
+
- `rockhopper://files/{fileMsId}/versions` — version history
|
|
113
|
+
- `rockhopper://files/{fileMsId}/comments` — all comments
|
|
114
|
+
- `rockhopper://files/{fileMsId}/changes` — uncommitted changes
|
|
115
|
+
- `rockhopper://versions/{versionId}` — version details
|
|
116
|
+
- `rockhopper://versions/{versionId}/reviews` — reviews on a version
|
|
117
|
+
- `rockhopper://reviews/{reviewId}` — review details
|
|
118
|
+
- `rockhopper://teams/{teamId}` — team details
|
|
119
|
+
|
|
120
|
+
Resources and tools return the same data for the same identifiers. Tools are preferable when you need argument shaping (filters, search); resources are preferable when you have a known URI and want the canonical representation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/resources/versions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,
|
|
1
|
+
{"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../src/resources/versions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAiDN"}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
export function registerVersionResources(server, api) {
|
|
3
|
+
// KI-078 (ENG-1381): template only, no per-file expansion into resources/list.
|
|
3
4
|
server.registerResource('file-versions', new ResourceTemplate('rockhopper://files/{fileMsId}/versions', {
|
|
4
|
-
list:
|
|
5
|
-
const files = await api.listEnrolledFiles();
|
|
6
|
-
return {
|
|
7
|
-
resources: files.map((f) => ({
|
|
8
|
-
uri: `rockhopper://files/${f.platformId}/versions`,
|
|
9
|
-
name: `Versions of ${f.name}`,
|
|
10
|
-
mimeType: 'application/json',
|
|
11
|
-
})),
|
|
12
|
-
};
|
|
13
|
-
},
|
|
5
|
+
list: undefined,
|
|
14
6
|
}), {
|
|
15
7
|
title: 'File Version History',
|
|
16
8
|
description: 'All version snapshots for a specific enrolled file',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/resources/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAc;IAEd,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,wCAAwC,EAAE;QAC7D,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../src/resources/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAI3E,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAc;IAEd,+EAA+E;IAC/E,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,IAAI,gBAAgB,CAAC,wCAAwC,EAAE;QAC7D,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,oDAAoD;QACjE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,QAAkB,CAAC,CAAC;QAC/D,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACxC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,IAAI,gBAAgB,CAAC,mCAAmC,EAAE;QACxD,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,oDAAoD;QACjE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rockhopper-co/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Rockhopper MCP server — expose file metadata, versions, reviews, and comments to AI tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"CHANGELOG.md"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
|
-
"build": "tsc -p tsconfig.build.json",
|
|
25
|
+
"build": "tsc -p tsconfig.build.json && node scripts/copy-non-ts-assets.mjs",
|
|
26
26
|
"start": "node dist/cli.js",
|
|
27
27
|
"dev": "tsx watch src/cli.ts",
|
|
28
28
|
"lint": "eslint src/",
|