@rockhopper-co/mcp-server 0.2.1 → 0.3.1

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 CHANGED
@@ -4,6 +4,45 @@ 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.3.0] — 2026-04-24
8
+
9
+ Adds a **library entry point** so `@rockhopper-co/mcp-server` can be
10
+ consumed programmatically — most notably by the remote MCP gateway
11
+ ([`mcp-gateway`](https://github.com/Rockhopper-Co/mcp-gateway)) which
12
+ needs `createServer` and `ApiClient` to wire the Streamable HTTP
13
+ transport. The stdio CLI continues to work exactly as before.
14
+
15
+ ### Added
16
+ - **Library exports.** `import { createServer, ApiClient } from
17
+ '@rockhopper-co/mcp-server'` now works. The library entry is
18
+ side-effect free — importing it does NOT read `ROCKHOPPER_TOKEN`,
19
+ call `process.exit`, or open any transport. Stable surface:
20
+ - `createServer(apiClient: ApiClient): McpServer`
21
+ - `ApiClient` (class), `ApiClientConfig` (interface)
22
+ - All entity types (`Team`, `EnrolledFile`, `FileVersion`, ...)
23
+ - `package.json` `exports` field with explicit subpath conditions for
24
+ `.` (library) and `./package.json` (so consumers can read the
25
+ package version). Anything else is intentionally not part of the
26
+ public API.
27
+
28
+ ### Changed
29
+ - **CLI moved** from `src/index.ts` → `src/cli.ts` so the default
30
+ entrypoint can be a side-effect-free re-export. The `rockhopper-mcp`
31
+ bin still works the same; `npx -y @rockhopper-co/mcp-server` still
32
+ spawns the stdio server. Only difference: `dist/cli.js` is the
33
+ shebang file now (was `dist/index.js`).
34
+ - `package.json` `bin`, `start`, and `dev` scripts now reference
35
+ `cli.js` / `cli.ts`.
36
+ - Publish workflow's "Verify bin is executable" step now checks
37
+ `dist/cli.js`.
38
+
39
+ ### Internal
40
+ - New unit test `lib.exports.test.ts` enforces the side-effect-freedom
41
+ invariant — fails loud if anyone re-introduces top-level CLI
42
+ bootstrap into `index.ts` or `lib.ts`.
43
+ - Old `index.bootstrap.test.ts` renamed to `cli.bootstrap.test.ts`
44
+ with imports adjusted.
45
+
7
46
  ## [0.2.1] — 2026-04-24
8
47
 
9
48
  Publishing-pipeline hardening release. **No runtime or API changes** — the
package/README.md CHANGED
@@ -75,6 +75,18 @@ Add to `.cursor/mcp.json` in your project:
75
75
  | `ROCKHOPPER_TOKEN` | Yes | — | Personal Access Token (starts with `rh_pat_`) |
76
76
  | `ROCKHOPPER_API_URL` | No | `https://api.rockhopper.co` | Rockhopper API base URL |
77
77
 
78
+ ## Postman
79
+
80
+ A starter Postman collection + environment files are available in
81
+ `postman/` for gateway smoke testing (`/healthz`, `/mcp initialize`,
82
+ `/mcp tools/list`) across local/dev/staging/production.
83
+
84
+ Regenerate artifacts with:
85
+
86
+ ```bash
87
+ npm run generate:postman
88
+ ```
89
+
78
90
  ## Available Tools
79
91
 
80
92
  | Tool | Description |
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,39 @@
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
+ if (!ROCKHOPPER_TOKEN.startsWith('rh_pat_')) {
13
+ console.error('Error: ROCKHOPPER_TOKEN does not look like a valid Personal Access Token.\n' +
14
+ 'Tokens start with "rh_pat_". Check that the full token was copied correctly.');
15
+ process.exit(1);
16
+ }
17
+ const apiClient = new ApiClient({
18
+ baseUrl: ROCKHOPPER_API_URL,
19
+ token: ROCKHOPPER_TOKEN,
20
+ });
21
+ try {
22
+ await apiClient.getMe();
23
+ }
24
+ catch (err) {
25
+ const msg = err instanceof Error ? err.message : String(err);
26
+ if (msg.includes('401') || msg.includes('403')) {
27
+ console.error('Error: ROCKHOPPER_TOKEN is invalid or expired.\n' +
28
+ 'Create a new Personal Access Token in Rockhopper Settings and set it as ROCKHOPPER_TOKEN.');
29
+ }
30
+ else {
31
+ console.error(`Error: Could not reach Rockhopper API at ${ROCKHOPPER_API_URL}.\n` +
32
+ `Details: ${msg}`);
33
+ }
34
+ process.exit(1);
35
+ }
36
+ const server = createServer(apiClient);
37
+ const transport = new StdioServerTransport();
38
+ await server.connect(transport);
39
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.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,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;IAC5C,OAAO,CAAC,KAAK,CACX,6EAA6E;QAC3E,8EAA8E,CACjF,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,IAAI,CAAC;IACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,KAAK,CACX,kDAAkD;YAChD,2FAA2F,CAC9F,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CACX,4CAA4C,kBAAkB,KAAK;YACjE,YAAY,GAAG,EAAE,CACpB,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,11 @@
1
- #!/usr/bin/env node
2
- export {};
1
+ /**
2
+ * Default entry point. Re-exports the public library API from `./lib`.
3
+ *
4
+ * The CLI lives at `./cli.js` (the `rockhopper-mcp` bin). Importing
5
+ * this module is side-effect free; it does NOT start a stdio server.
6
+ *
7
+ * @see ./lib.ts for the canonical export list.
8
+ * @see ./cli.ts for the stdio CLI entrypoint.
9
+ */
10
+ export * from './lib.js';
3
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,19 +1,11 @@
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);
1
+ /**
2
+ * Default entry point. Re-exports the public library API from `./lib`.
3
+ *
4
+ * The CLI lives at `./cli.js` (the `rockhopper-mcp` bin). Importing
5
+ * this module is side-effect free; it does NOT start a stdio server.
6
+ *
7
+ * @see ./lib.ts for the canonical export list.
8
+ * @see ./cli.ts for the stdio CLI entrypoint.
9
+ */
10
+ export * from './lib.js';
19
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,UAAU,CAAC"}
package/dist/lib.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Library entry point for `@rockhopper-co/mcp-server`.
3
+ *
4
+ * This file is **side-effect free** — importing the package as a library
5
+ * (e.g. from the remote MCP gateway) gives you the building blocks
6
+ * (`createServer`, `ApiClient`, types) without spawning a stdio server
7
+ * or reading `ROCKHOPPER_TOKEN` from the environment.
8
+ *
9
+ * The CLI entry (the `rockhopper-mcp` bin) is `./cli.js` — running it
10
+ * directly is what spins up the stdio transport. Library consumers
11
+ * should never import `./cli.js`; they should compose `createServer`
12
+ * with their own transport (HTTP, in-memory, etc.).
13
+ *
14
+ * Stable API surface (semver-bound):
15
+ * - `createServer(apiClient): McpServer`
16
+ * - `ApiClient` (class) and `ApiClientConfig` (interface)
17
+ * - All `types` (Team, EnrolledFile, FileVersion, ...)
18
+ */
19
+ export { createServer } from './server.js';
20
+ export { type RegisterToolsOptions } from './tools/index.js';
21
+ export { ApiClient, type ApiClientConfig } from './api-client.js';
22
+ export * from './types.js';
23
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,cAAc,YAAY,CAAC"}
package/dist/lib.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Library entry point for `@rockhopper-co/mcp-server`.
3
+ *
4
+ * This file is **side-effect free** — importing the package as a library
5
+ * (e.g. from the remote MCP gateway) gives you the building blocks
6
+ * (`createServer`, `ApiClient`, types) without spawning a stdio server
7
+ * or reading `ROCKHOPPER_TOKEN` from the environment.
8
+ *
9
+ * The CLI entry (the `rockhopper-mcp` bin) is `./cli.js` — running it
10
+ * directly is what spins up the stdio transport. Library consumers
11
+ * should never import `./cli.js`; they should compose `createServer`
12
+ * with their own transport (HTTP, in-memory, etc.).
13
+ *
14
+ * Stable API surface (semver-bound):
15
+ * - `createServer(apiClient): McpServer`
16
+ * - `ApiClient` (class) and `ApiClientConfig` (interface)
17
+ * - All `types` (Team, EnrolledFile, FileVersion, ...)
18
+ */
19
+ export { createServer } from './server.js';
20
+ export { ApiClient } from './api-client.js';
21
+ export * from './types.js';
22
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,cAAc,YAAY,CAAC"}
package/dist/server.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { ApiClient } from './api-client.js';
3
- export declare function createServer(apiClient: ApiClient): McpServer;
3
+ import { type RegisterToolsOptions } from './tools/index.js';
4
+ export declare function createServer(apiClient: ApiClient, options?: RegisterToolsOptions): McpServer;
4
5
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAsB5D"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,SAAS,CA6BX"}
package/dist/server.js CHANGED
@@ -2,20 +2,27 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { registerPrompts } from './prompts/index.js';
3
3
  import { registerResources } from './resources/index.js';
4
4
  import { registerTools } from './tools/index.js';
5
- export function createServer(apiClient) {
5
+ export function createServer(apiClient, options) {
6
+ const readOnly = options?.scope === 'read-only';
6
7
  const server = new McpServer({
7
8
  name: 'rockhopper',
8
9
  version: '0.1.0',
9
10
  }, {
10
- instructions: 'Rockhopper MCP server for managing Excel file metadata. ' +
11
- 'Use list_files first to discover available files, then drill into ' +
12
- 'versions, comments, reviews, or cell history. Write operations ' +
13
- '(add_comment, reply_to_comment, resolve_comment, create_review_request, ' +
14
- 'approve_review, update_file_description) require a read-write scoped token. ' +
15
- 'File IDs use the platformId field (e.g. from list_files output).',
11
+ instructions: readOnly
12
+ ? 'Rockhopper MCP server for reading Excel file metadata. ' +
13
+ 'Use list_files first to discover available files, then drill into ' +
14
+ 'versions, comments, reviews, or cell history. ' +
15
+ 'This token is read-only — write operations are not available. ' +
16
+ 'File IDs use the platformId field (e.g. from list_files output).'
17
+ : 'Rockhopper MCP server for managing Excel file metadata. ' +
18
+ 'Use list_files first to discover available files, then drill into ' +
19
+ 'versions, comments, reviews, or cell history. Write operations ' +
20
+ '(add_comment, reply_to_comment, resolve_comment, create_review_request, ' +
21
+ 'approve_review, update_file_description) require a read-write scoped token. ' +
22
+ 'File IDs use the platformId field (e.g. from list_files output).',
16
23
  });
17
24
  registerResources(server, apiClient);
18
- registerTools(server, apiClient);
25
+ registerTools(server, apiClient, options);
19
26
  registerPrompts(server, apiClient);
20
27
  return server;
21
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,SAAoB;IAC/C,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EACV,0DAA0D;YAC1D,oEAAoE;YACpE,iEAAiE;YACjE,0EAA0E;YAC1E,8EAA8E;YAC9E,kEAAkE;KACrE,CACF,CAAC;IAEF,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrC,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAEnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAA6B,MAAM,kBAAkB,CAAC;AAE5E,MAAM,UAAU,YAAY,CAC1B,SAAoB,EACpB,OAA8B;IAE9B,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,KAAK,WAAW,CAAC;IAEhD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE,QAAQ;YACpB,CAAC,CAAC,yDAAyD;gBACzD,oEAAoE;gBACpE,gDAAgD;gBAChD,gEAAgE;gBAChE,kEAAkE;YACpE,CAAC,CAAC,0DAA0D;gBAC1D,oEAAoE;gBACpE,iEAAiE;gBACjE,0EAA0E;gBAC1E,8EAA8E;gBAC9E,kEAAkE;KACvE,CACF,CAAC;IAEF,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrC,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1C,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAEnC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,4 +1,7 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ApiClient } from '../api-client.js';
3
- export declare function registerTools(server: McpServer, api: ApiClient): void;
3
+ export interface RegisterToolsOptions {
4
+ scope?: 'read-only' | 'read-write';
5
+ }
6
+ export declare function registerTools(server: McpServer, api: ApiClient, options?: RegisterToolsOptions): void;
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAWlD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAarE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAWlD,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,WAAW,GAAG,YAAY,CAAC;CACpC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,oBAAoB,GAC7B,IAAI,CAeN"}
@@ -7,7 +7,7 @@ import { registerSearchTool } from './search.js';
7
7
  import { registerWriteCommentTools } from './write-comments.js';
8
8
  import { registerWriteReviewTools } from './write-reviews.js';
9
9
  import { registerWriteFileTool } from './write-files.js';
10
- export function registerTools(server, api) {
10
+ export function registerTools(server, api, options) {
11
11
  // Read-only tools (available to all scopes)
12
12
  registerListFilesTool(server, api);
13
13
  registerGetVersionsTool(server, api);
@@ -16,8 +16,10 @@ export function registerTools(server, api) {
16
16
  registerGetCellHistoryTool(server, api);
17
17
  registerSearchTool(server, api);
18
18
  // Write tools (require read-write scope on PAT)
19
- registerWriteCommentTools(server, api);
20
- registerWriteReviewTools(server, api);
21
- registerWriteFileTool(server, api);
19
+ if (options?.scope !== 'read-only') {
20
+ registerWriteCommentTools(server, api);
21
+ registerWriteReviewTools(server, api);
22
+ registerWriteFileTool(server, api);
23
+ }
22
24
  }
23
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,GAAc;IAC7D,4CAA4C;IAC5C,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEhC,gDAAgD;IAChD,yBAAyB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAMzD,MAAM,UAAU,aAAa,CAC3B,MAAiB,EACjB,GAAc,EACd,OAA8B;IAE9B,4CAA4C;IAC5C,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEhC,gDAAgD;IAChD,IAAI,OAAO,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;QACnC,yBAAyB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACvC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "@rockhopper-co/mcp-server",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
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",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
8
15
  "bin": {
9
- "rockhopper-mcp": "dist/index.js"
16
+ "rockhopper-mcp": "dist/cli.js"
10
17
  },
11
18
  "files": [
12
19
  "dist",
@@ -16,8 +23,8 @@
16
23
  ],
17
24
  "scripts": {
18
25
  "build": "tsc -p tsconfig.build.json",
19
- "start": "node dist/index.js",
20
- "dev": "tsx watch src/index.ts",
26
+ "start": "node dist/cli.js",
27
+ "dev": "tsx watch src/cli.ts",
21
28
  "lint": "eslint src/",
22
29
  "typecheck": "tsc --noEmit",
23
30
  "test": "vitest run",
@@ -26,6 +33,8 @@
26
33
  "test:e2e:cov": "vitest run --config vitest.e2e.config.ts --coverage",
27
34
  "test:cov": "vitest run --coverage",
28
35
  "test:watch": "vitest",
36
+ "generate:postman": "tsx scripts/generate-postman-collection.ts && tsx scripts/generate-postman-environments.ts",
37
+ "generate:postman:check": "npm run generate:postman && git diff --exit-code -- postman/",
29
38
  "prepublishOnly": "npm run build",
30
39
  "release:patch": "npm version patch -m 'release: v%s' && git push && git push --tags",
31
40
  "release:minor": "npm version minor -m 'release: v%s' && git push && git push --tags",
@@ -43,7 +52,8 @@
43
52
  "@vitest/coverage-v8": "^3.2.4",
44
53
  "tsx": "^4.19.4",
45
54
  "typescript": "^5.8.3",
46
- "vitest": "^3.1.2"
55
+ "vitest": "^3.1.2",
56
+ "zod-to-json-schema": "^3.24.6"
47
57
  },
48
58
  "keywords": [
49
59
  "mcp",