castor-mcp 0.6.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/LICENSE +21 -0
- package/README.md +77 -0
- package/build/api-catalog.d.ts +27 -0
- package/build/api-catalog.js +76 -0
- package/build/api-catalog.js.map +1 -0
- package/build/confluence-client.d.ts +33 -0
- package/build/confluence-client.js +65 -0
- package/build/confluence-client.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +137 -0
- package/build/index.js.map +1 -0
- package/build/resource-definitions.d.ts +10 -0
- package/build/resource-definitions.js +75 -0
- package/build/resource-definitions.js.map +1 -0
- package/build/tool-definitions.d.ts +19 -0
- package/build/tool-definitions.js +1811 -0
- package/build/tool-definitions.js.map +1 -0
- package/build/tools/admin-users-groups.d.ts +114 -0
- package/build/tools/admin-users-groups.js +150 -0
- package/build/tools/admin-users-groups.js.map +1 -0
- package/build/tools/admin.d.ts +12 -0
- package/build/tools/admin.js +30 -0
- package/build/tools/admin.js.map +1 -0
- package/build/tools/args.d.ts +2 -0
- package/build/tools/args.js +12 -0
- package/build/tools/args.js.map +1 -0
- package/build/tools/attachments.d.ts +138 -0
- package/build/tools/attachments.js +170 -0
- package/build/tools/attachments.js.map +1 -0
- package/build/tools/backup-restore.d.ts +144 -0
- package/build/tools/backup-restore.js +223 -0
- package/build/tools/backup-restore.js.map +1 -0
- package/build/tools/bulk-pages.d.ts +103 -0
- package/build/tools/bulk-pages.js +111 -0
- package/build/tools/bulk-pages.js.map +1 -0
- package/build/tools/color-schemes.d.ts +72 -0
- package/build/tools/color-schemes.js +121 -0
- package/build/tools/color-schemes.js.map +1 -0
- package/build/tools/content-structure.d.ts +164 -0
- package/build/tools/content-structure.js +220 -0
- package/build/tools/content-structure.js.map +1 -0
- package/build/tools/content.d.ts +194 -0
- package/build/tools/content.js +246 -0
- package/build/tools/content.js.map +1 -0
- package/build/tools/errors.d.ts +3 -0
- package/build/tools/errors.js +55 -0
- package/build/tools/errors.js.map +1 -0
- package/build/tools/index-management.d.ts +30 -0
- package/build/tools/index-management.js +64 -0
- package/build/tools/index-management.js.map +1 -0
- package/build/tools/labels.d.ts +108 -0
- package/build/tools/labels.js +160 -0
- package/build/tools/labels.js.map +1 -0
- package/build/tools/permissions.d.ts +554 -0
- package/build/tools/permissions.js +194 -0
- package/build/tools/permissions.js.map +1 -0
- package/build/tools/spaces-admin.d.ts +225 -0
- package/build/tools/spaces-admin.js +288 -0
- package/build/tools/spaces-admin.js.map +1 -0
- package/build/tools/spaces-pages.d.ts +103 -0
- package/build/tools/spaces-pages.js +150 -0
- package/build/tools/spaces-pages.js.map +1 -0
- package/build/tools/system.d.ts +42 -0
- package/build/tools/system.js +101 -0
- package/build/tools/system.js.map +1 -0
- package/build/tools/users-groups.d.ts +216 -0
- package/build/tools/users-groups.js +274 -0
- package/build/tools/users-groups.js.map +1 -0
- package/build/tools/webhooks.d.ts +105 -0
- package/build/tools/webhooks.js +124 -0
- package/build/tools/webhooks.js.map +1 -0
- package/build/version.d.ts +7 -0
- package/build/version.js +17 -0
- package/build/version.js.map +1 -0
- package/docs/api-catalog.yaml +2388 -0
- package/package.json +59 -0
- package/skills/content.md +85 -0
- package/skills/instance-maintenance.md +59 -0
- package/skills/permissions.md +47 -0
- package/skills/spaces-admin.md +59 -0
- package/skills/spaces-pages.md +24 -0
- package/skills/system.md +34 -0
- package/skills/users-groups.md +55 -0
- package/skills/webhooks.md +25 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Chuck
|
|
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,77 @@
|
|
|
1
|
+
# Castor for Confluence Data Center
|
|
2
|
+
|
|
3
|
+
Docs: https://castor.moosejudge.com/docs
|
|
4
|
+
|
|
5
|
+
A secure MCP server that bridges Atlassian Confluence Data Center (9.2 and 10.2, the two current
|
|
6
|
+
LTS lines) with AI agents like Claude.
|
|
7
|
+
|
|
8
|
+
> Castor is an independent, community-built tool. It is not affiliated with, endorsed by, or
|
|
9
|
+
> sponsored by Atlassian. Confluence® is a registered trademark of Atlassian Pty Ltd.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
As Atlassian sunsets Data Center support, this server ensures organizations can still leverage AI
|
|
14
|
+
safely within their on-premise Confluence infrastructure. It follows open standards, the MCP
|
|
15
|
+
specification, and a "secure by default" model — see `alces-mcp` (the sibling Jira DC server this
|
|
16
|
+
project mirrors) for the shared design lineage.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **7 domain tools** covering spaces, pages, and CQL search, plus `get_api_references` for
|
|
21
|
+
querying the generated API catalog — `docs/api-catalog.md` tracks the full set of cataloged
|
|
22
|
+
Confluence DC operations and which are implemented.
|
|
23
|
+
- **Dual-token security**: `CONFLUENCE_USER_TOKEN` for standard operations,
|
|
24
|
+
`CONFLUENCE_ADMIN_TOKEN` for elevated ones (e.g. `admin_get_space_permissions`) — admin tools are
|
|
25
|
+
invisible to the agent without the admin token configured.
|
|
26
|
+
- **Skills as MCP Resources**: agent-facing operational guidance via `skill://spaces-pages`.
|
|
27
|
+
|
|
28
|
+
## Install to use
|
|
29
|
+
|
|
30
|
+
Just want to talk to your Confluence DC instance through Claude Desktop, without cloning or
|
|
31
|
+
building anything? Install the pre-built bundle:
|
|
32
|
+
|
|
33
|
+
1. Download the latest `castor-mcp-<version>.mcpb` from the
|
|
34
|
+
[GitLab Releases page](https://gitlab.com/moosejudge/castor-mcp/-/releases).
|
|
35
|
+
2. In Claude Desktop: **Settings → Extensions → Advanced settings → Extension Developer →
|
|
36
|
+
"Install Extension…"**, then select the downloaded file.
|
|
37
|
+
3. Enter your Confluence URL and PAT(s) when prompted — these are stored via your OS keychain,
|
|
38
|
+
never as plaintext.
|
|
39
|
+
|
|
40
|
+
Once connected, see [docs/user/](./docs/user/spaces-pages.md) for what you can do and how to ask
|
|
41
|
+
for it.
|
|
42
|
+
|
|
43
|
+
If you're integrating Castor into a coding agent instead of Claude Desktop, it's also published on
|
|
44
|
+
npm as [`castor-mcp`](https://www.npmjs.com/package/castor-mcp) — point your agent's MCP config at
|
|
45
|
+
`command: "npx"`, `args: ["-y", "castor-mcp"]` instead of cloning or building anything. See
|
|
46
|
+
[Setup to develop](#setup-to-develop) below only if you're contributing or need to run from an
|
|
47
|
+
unreleased commit.
|
|
48
|
+
|
|
49
|
+
## Setup to develop
|
|
50
|
+
|
|
51
|
+
1. Clone the repository.
|
|
52
|
+
2. Install dependencies:
|
|
53
|
+
```bash
|
|
54
|
+
npm install
|
|
55
|
+
```
|
|
56
|
+
3. Copy `.env.example` to `.env` and fill in `CONFLUENCE_URL` and `CONFLUENCE_USER_TOKEN`
|
|
57
|
+
(optionally `CONFLUENCE_ADMIN_TOKEN`).
|
|
58
|
+
4. Build the project:
|
|
59
|
+
```bash
|
|
60
|
+
npm run build
|
|
61
|
+
```
|
|
62
|
+
5. Run tests:
|
|
63
|
+
```bash
|
|
64
|
+
npm test
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
There is no running local Confluence instance yet — `docker-compose.yml` defines one (see
|
|
68
|
+
`docs/developer/testing-environment.md`), but it requires a Confluence developer license this
|
|
69
|
+
project does not currently have, and has never been started.
|
|
70
|
+
|
|
71
|
+
## Documentation
|
|
72
|
+
|
|
73
|
+
- `docs/user/` — task-oriented guide to what the agent can do.
|
|
74
|
+
- `docs/developer/` — codebase notes for contributors.
|
|
75
|
+
- `docs/api-catalog.md` — generated reference of every cataloged Confluence DC operation and its
|
|
76
|
+
implementation status.
|
|
77
|
+
- `docs/specs/`, `docs/plans/` — design specs and implementation plans.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ApiOperation {
|
|
2
|
+
api: string;
|
|
3
|
+
path: string;
|
|
4
|
+
method: string;
|
|
5
|
+
tag: string;
|
|
6
|
+
operation_id: string | null;
|
|
7
|
+
summary: string;
|
|
8
|
+
deprecated: boolean;
|
|
9
|
+
auth_tier: "user" | "admin";
|
|
10
|
+
destructiveness: string;
|
|
11
|
+
min_version: string;
|
|
12
|
+
max_version: string;
|
|
13
|
+
implementation_status: string;
|
|
14
|
+
implemented_by: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface ApiCatalog {
|
|
17
|
+
generated_from: string[];
|
|
18
|
+
generated_note: string;
|
|
19
|
+
operations: ApiOperation[];
|
|
20
|
+
}
|
|
21
|
+
export type ApiReferenceCategory = "user" | "admin";
|
|
22
|
+
export interface ApiReferenceArgs {
|
|
23
|
+
category?: ApiReferenceCategory;
|
|
24
|
+
tag?: string;
|
|
25
|
+
search?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildApiReferenceText(catalog: ApiCatalog, args: ApiReferenceArgs): string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const ROW_DUMP_THRESHOLD = 80;
|
|
2
|
+
const MAX_ROWS = 150;
|
|
3
|
+
function opsForCategory(catalog, category) {
|
|
4
|
+
return catalog.operations.filter((o) => o.auth_tier === category);
|
|
5
|
+
}
|
|
6
|
+
function applyFilters(ops, args) {
|
|
7
|
+
let out = ops;
|
|
8
|
+
if (args.tag) {
|
|
9
|
+
const needle = args.tag.toLowerCase();
|
|
10
|
+
out = out.filter((o) => o.tag.toLowerCase().includes(needle));
|
|
11
|
+
}
|
|
12
|
+
if (args.search) {
|
|
13
|
+
const needle = args.search.toLowerCase();
|
|
14
|
+
out = out.filter((o) => o.path.toLowerCase().includes(needle) ||
|
|
15
|
+
o.summary.toLowerCase().includes(needle) ||
|
|
16
|
+
(o.operation_id ?? "").toLowerCase().includes(needle));
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function tagBreakdown(ops) {
|
|
21
|
+
const counts = new Map();
|
|
22
|
+
for (const op of ops)
|
|
23
|
+
counts.set(op.tag, (counts.get(op.tag) ?? 0) + 1);
|
|
24
|
+
return [...counts.entries()]
|
|
25
|
+
.sort((a, b) => b[1] - a[1])
|
|
26
|
+
.map(([tag, count]) => `- \`${tag}\` (${count})`)
|
|
27
|
+
.join("\n");
|
|
28
|
+
}
|
|
29
|
+
function renderRows(ops) {
|
|
30
|
+
const truncated = ops.length > MAX_ROWS;
|
|
31
|
+
const rows = ops.slice(0, MAX_ROWS);
|
|
32
|
+
let md = `| Status | Method | Path | Summary | Kind |\n|---|---|---|---|---|\n`;
|
|
33
|
+
for (const op of rows) {
|
|
34
|
+
md += `| ${op.implementation_status} | ${op.method} | \`${op.path}\` | ${op.summary} | ${op.destructiveness} |\n`;
|
|
35
|
+
}
|
|
36
|
+
if (truncated) {
|
|
37
|
+
md += `\n_...${ops.length - MAX_ROWS} more rows omitted — narrow with \`tag\` or \`search\`._\n`;
|
|
38
|
+
}
|
|
39
|
+
return md;
|
|
40
|
+
}
|
|
41
|
+
function renderOverview(catalog) {
|
|
42
|
+
const counts = {
|
|
43
|
+
user: opsForCategory(catalog, "user").length,
|
|
44
|
+
admin: opsForCategory(catalog, "admin").length,
|
|
45
|
+
};
|
|
46
|
+
return [
|
|
47
|
+
`Confluence DC API catalog — ${catalog.operations.length} cataloged operations.`,
|
|
48
|
+
``,
|
|
49
|
+
`Call again with a \`category\` to see entries:`,
|
|
50
|
+
`- \`user\` (${counts.user}) — user-tier`,
|
|
51
|
+
`- \`admin\` (${counts.admin}) — admin-tier`,
|
|
52
|
+
``,
|
|
53
|
+
`Add \`tag\` or \`search\` to narrow within a category.`,
|
|
54
|
+
``,
|
|
55
|
+
catalog.generated_note,
|
|
56
|
+
].join("\n");
|
|
57
|
+
}
|
|
58
|
+
export function buildApiReferenceText(catalog, args) {
|
|
59
|
+
if (!args.category)
|
|
60
|
+
return renderOverview(catalog);
|
|
61
|
+
const base = opsForCategory(catalog, args.category);
|
|
62
|
+
const filtered = applyFilters(base, args);
|
|
63
|
+
if (filtered.length === 0) {
|
|
64
|
+
return `No operations found in category \`${args.category}\` matching the given filters.`;
|
|
65
|
+
}
|
|
66
|
+
if (filtered.length > ROW_DUMP_THRESHOLD && !args.tag && !args.search) {
|
|
67
|
+
return [
|
|
68
|
+
`Category \`${args.category}\` has ${filtered.length} operations — too many to list at once.`,
|
|
69
|
+
`Narrow with \`tag\` (or \`search\`). Tags in this category:`,
|
|
70
|
+
``,
|
|
71
|
+
tagBreakdown(filtered),
|
|
72
|
+
].join("\n");
|
|
73
|
+
}
|
|
74
|
+
return `${filtered.length} operation(s) in \`${args.category}\`${args.tag ? ` / tag "${args.tag}"` : ""}${args.search ? ` matching "${args.search}"` : ""}:\n\n${renderRows(filtered)}`;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=api-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-catalog.js","sourceRoot":"","sources":["../src/api-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
export interface ConfluenceConfig {
|
|
3
|
+
url: string;
|
|
4
|
+
token: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class ConfluenceClient {
|
|
7
|
+
private axiosInstance;
|
|
8
|
+
constructor(config: ConfluenceConfig, axiosInstance?: AxiosInstance);
|
|
9
|
+
get(path: string, params?: Record<string, unknown>, responseType?: "json" | "arraybuffer"): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
10
|
+
post(path: string, body?: unknown, headers?: Record<string, string | undefined>): Promise<import("axios").AxiosResponse<any, unknown, {}, any>>;
|
|
11
|
+
put(path: string, body?: unknown): Promise<import("axios").AxiosResponse<any, unknown, {}, any>>;
|
|
12
|
+
delete(path: string, params?: Record<string, unknown>): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
13
|
+
/** GET /rest/api/space — list spaces, optionally filtered by type ("global"|"personal"). */
|
|
14
|
+
listSpaces(params?: {
|
|
15
|
+
type?: string;
|
|
16
|
+
limit?: number;
|
|
17
|
+
}): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
18
|
+
/** GET /rest/api/space/{spaceKey} */
|
|
19
|
+
getSpace(spaceKey: string): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
20
|
+
/**
|
|
21
|
+
* GET /rest/api/content/{id} — expands body.storage/version/space so callers get a page's
|
|
22
|
+
* content, version number, and owning space in one round trip.
|
|
23
|
+
*/
|
|
24
|
+
getContent(id: string): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
25
|
+
/** POST /rest/api/content */
|
|
26
|
+
createContent(body: unknown): Promise<import("axios").AxiosResponse<any, unknown, {}, any>>;
|
|
27
|
+
/** PUT /rest/api/content/{contentId} */
|
|
28
|
+
updateContent(contentId: string, body: unknown): Promise<import("axios").AxiosResponse<any, unknown, {}, any>>;
|
|
29
|
+
/** GET /rest/api/content/search — Confluence Query Language (CQL). */
|
|
30
|
+
searchContent(cql: string, limit?: number): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
31
|
+
/** GET /rest/api/space/{spaceKey}/permissions — requires space-admin permission. */
|
|
32
|
+
getSpacePermissions(spaceKey: string): Promise<import("axios").AxiosResponse<any, any, {}, Record<string, unknown>>>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
export class ConfluenceClient {
|
|
3
|
+
axiosInstance;
|
|
4
|
+
constructor(config, axiosInstance) {
|
|
5
|
+
if (axiosInstance) {
|
|
6
|
+
this.axiosInstance = axiosInstance;
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const baseUrl = config.url.endsWith("/") ? config.url.slice(0, -1) : config.url;
|
|
10
|
+
this.axiosInstance = axios.create({
|
|
11
|
+
baseURL: baseUrl,
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: `Bearer ${config.token}`,
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
Accept: "application/json",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async get(path, params, responseType) {
|
|
20
|
+
return this.axiosInstance.get(path, { params, responseType });
|
|
21
|
+
}
|
|
22
|
+
async post(path, body, headers) {
|
|
23
|
+
if (headers)
|
|
24
|
+
return this.axiosInstance.post(path, body, { headers });
|
|
25
|
+
return this.axiosInstance.post(path, body);
|
|
26
|
+
}
|
|
27
|
+
async put(path, body) {
|
|
28
|
+
return this.axiosInstance.put(path, body);
|
|
29
|
+
}
|
|
30
|
+
async delete(path, params) {
|
|
31
|
+
return this.axiosInstance.delete(path, { params });
|
|
32
|
+
}
|
|
33
|
+
/** GET /rest/api/space — list spaces, optionally filtered by type ("global"|"personal"). */
|
|
34
|
+
async listSpaces(params) {
|
|
35
|
+
return this.get("/rest/api/space", params);
|
|
36
|
+
}
|
|
37
|
+
/** GET /rest/api/space/{spaceKey} */
|
|
38
|
+
async getSpace(spaceKey) {
|
|
39
|
+
return this.get(`/rest/api/space/${encodeURIComponent(spaceKey)}`);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* GET /rest/api/content/{id} — expands body.storage/version/space so callers get a page's
|
|
43
|
+
* content, version number, and owning space in one round trip.
|
|
44
|
+
*/
|
|
45
|
+
async getContent(id) {
|
|
46
|
+
return this.get(`/rest/api/content/${encodeURIComponent(id)}`, { expand: "body.storage,version,space" });
|
|
47
|
+
}
|
|
48
|
+
/** POST /rest/api/content */
|
|
49
|
+
async createContent(body) {
|
|
50
|
+
return this.post("/rest/api/content", body);
|
|
51
|
+
}
|
|
52
|
+
/** PUT /rest/api/content/{contentId} */
|
|
53
|
+
async updateContent(contentId, body) {
|
|
54
|
+
return this.put(`/rest/api/content/${encodeURIComponent(contentId)}`, body);
|
|
55
|
+
}
|
|
56
|
+
/** GET /rest/api/content/search — Confluence Query Language (CQL). */
|
|
57
|
+
async searchContent(cql, limit) {
|
|
58
|
+
return this.get("/rest/api/content/search", { cql, limit });
|
|
59
|
+
}
|
|
60
|
+
/** GET /rest/api/space/{spaceKey}/permissions — requires space-admin permission. */
|
|
61
|
+
async getSpacePermissions(spaceKey) {
|
|
62
|
+
return this.get(`/rest/api/space/${encodeURIComponent(spaceKey)}/permissions`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=confluence-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence-client.js","sourceRoot":"","sources":["../src/confluence-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAO7C,MAAM,OAAO,gBAAgB;IACnB,aAAa,CAAgB;IAErC,YAAY,MAAwB,EAAE,aAA6B;QACjE,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;YACnC,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;QAChF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;YAChC,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;gBACvC,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;aAC3B;SACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,MAAgC,EAAE,YAAqC;QAC7F,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAc,EAAE,OAA4C;QACnF,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,IAAc;QACpC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,MAAgC;QACzD,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,4FAA4F;IAC5F,KAAK,CAAC,UAAU,CAAC,MAA0C;QACzD,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,qCAAqC;IACrC,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,qBAAqB,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAC3G,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,aAAa,CAAC,IAAa;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,IAAa;QAClD,OAAO,IAAI,CAAC,GAAG,CAAC,qBAAqB,kBAAkB,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,aAAa,CAAC,GAAW,EAAE,KAAc;QAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,mBAAmB,CAAC,QAAgB;QACxC,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,kBAAkB,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACjF,CAAC;CACF"}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ReadResourceRequestSchema, ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { readFile } from "fs/promises";
|
|
6
|
+
import { join, dirname } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import dotenv from "dotenv";
|
|
9
|
+
import { load as loadYaml } from "js-yaml";
|
|
10
|
+
import { ConfluenceClient } from "./confluence-client.js";
|
|
11
|
+
import { TOOL_DEFINITIONS, listableToolEntries } from "./tool-definitions.js";
|
|
12
|
+
import { RESOURCE_DEFINITIONS, getResourceDefinition } from "./resource-definitions.js";
|
|
13
|
+
import { buildApiReferenceText } from "./api-catalog.js";
|
|
14
|
+
import { readPackageVersion } from "./version.js";
|
|
15
|
+
dotenv.config();
|
|
16
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
+
const __dirname = dirname(__filename);
|
|
18
|
+
class CastorMcpServer {
|
|
19
|
+
server;
|
|
20
|
+
userClient = null;
|
|
21
|
+
adminClient = null;
|
|
22
|
+
skillContentCache = new Map();
|
|
23
|
+
apiCatalogCache = null;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.server = new Server({ name: "castor-mcp", version: readPackageVersion() }, {
|
|
26
|
+
capabilities: { tools: {}, resources: {} },
|
|
27
|
+
instructions: "Category-specific operational guidance is available as MCP Resources " +
|
|
28
|
+
"(skill://spaces-pages) — fetch it via resources/read before constructing complex " +
|
|
29
|
+
"CQL or working through a create/update page workflow.",
|
|
30
|
+
});
|
|
31
|
+
this.initializeClients();
|
|
32
|
+
this.setupHandlers();
|
|
33
|
+
this.server.onerror = (error) => console.error("[MCP Error]", error);
|
|
34
|
+
process.on("SIGINT", async () => {
|
|
35
|
+
await this.server.close();
|
|
36
|
+
process.exit(0);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
initializeClients() {
|
|
40
|
+
const url = process.env.CONFLUENCE_URL;
|
|
41
|
+
const userToken = process.env.CONFLUENCE_USER_TOKEN;
|
|
42
|
+
const adminToken = process.env.CONFLUENCE_ADMIN_TOKEN;
|
|
43
|
+
if (!url) {
|
|
44
|
+
console.error("CONFLUENCE_URL is not set");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (userToken) {
|
|
48
|
+
this.userClient = new ConfluenceClient({ url, token: userToken });
|
|
49
|
+
}
|
|
50
|
+
if (adminToken) {
|
|
51
|
+
this.adminClient = new ConfluenceClient({ url, token: adminToken });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
requireUserClient() {
|
|
55
|
+
if (!this.userClient) {
|
|
56
|
+
throw new McpError(ErrorCode.InvalidRequest, "No Confluence user client configured — set CONFLUENCE_URL and CONFLUENCE_USER_TOKEN.");
|
|
57
|
+
}
|
|
58
|
+
return this.userClient;
|
|
59
|
+
}
|
|
60
|
+
requireAdminClient() {
|
|
61
|
+
if (!this.adminClient) {
|
|
62
|
+
throw new McpError(ErrorCode.InvalidRequest, "No Confluence admin client configured — set CONFLUENCE_ADMIN_TOKEN to enable admin tools.");
|
|
63
|
+
}
|
|
64
|
+
return this.adminClient;
|
|
65
|
+
}
|
|
66
|
+
setupHandlers() {
|
|
67
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
68
|
+
tools: listableToolEntries(this.adminClient !== null).map(([name, def]) => ({
|
|
69
|
+
name,
|
|
70
|
+
description: def.description,
|
|
71
|
+
inputSchema: def.inputSchema,
|
|
72
|
+
})),
|
|
73
|
+
}));
|
|
74
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
75
|
+
const definition = TOOL_DEFINITIONS[request.params.name];
|
|
76
|
+
if (!definition) {
|
|
77
|
+
throw new McpError(ErrorCode.MethodNotFound, `Tool not found: ${request.params.name}`);
|
|
78
|
+
}
|
|
79
|
+
return definition.handler(this, request.params.arguments);
|
|
80
|
+
});
|
|
81
|
+
this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
82
|
+
resources: Object.values(RESOURCE_DEFINITIONS).map(({ uri, name, description, mimeType }) => ({
|
|
83
|
+
uri,
|
|
84
|
+
name,
|
|
85
|
+
description,
|
|
86
|
+
mimeType,
|
|
87
|
+
})),
|
|
88
|
+
}));
|
|
89
|
+
this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({ resourceTemplates: [] }));
|
|
90
|
+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
91
|
+
const def = getResourceDefinition(request.params.uri);
|
|
92
|
+
let text;
|
|
93
|
+
try {
|
|
94
|
+
text = await this.loadSkillContent(def.filePath);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
throw new McpError(ErrorCode.InternalError, `Error reading skill resource ${def.uri}`);
|
|
98
|
+
}
|
|
99
|
+
return { contents: [{ uri: def.uri, mimeType: def.mimeType, text }] };
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async loadSkillContent(filePath) {
|
|
103
|
+
const cached = this.skillContentCache.get(filePath);
|
|
104
|
+
if (cached !== undefined)
|
|
105
|
+
return cached;
|
|
106
|
+
const fullPath = join(__dirname, "..", "skills", filePath);
|
|
107
|
+
const text = await readFile(fullPath, "utf-8");
|
|
108
|
+
this.skillContentCache.set(filePath, text);
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
111
|
+
async loadApiCatalog() {
|
|
112
|
+
if (this.apiCatalogCache)
|
|
113
|
+
return this.apiCatalogCache;
|
|
114
|
+
const catalogPath = join(__dirname, "..", "docs", "api-catalog.yaml");
|
|
115
|
+
const raw = await readFile(catalogPath, "utf-8");
|
|
116
|
+
this.apiCatalogCache = loadYaml(raw);
|
|
117
|
+
return this.apiCatalogCache;
|
|
118
|
+
}
|
|
119
|
+
async handleGetApiReferences(args) {
|
|
120
|
+
try {
|
|
121
|
+
const catalog = await this.loadApiCatalog();
|
|
122
|
+
const text = buildApiReferenceText(catalog, (args ?? {}));
|
|
123
|
+
return { content: [{ type: "text", text }] };
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw new McpError(ErrorCode.InternalError, `Error reading API catalog: ${error instanceof Error ? error.message : String(error)}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async run() {
|
|
130
|
+
const transport = new StdioServerTransport();
|
|
131
|
+
await this.server.connect(transport);
|
|
132
|
+
console.error("Castor MCP server running on stdio");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const server = new CastorMcpServer();
|
|
136
|
+
server.run().catch(console.error);
|
|
137
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ResourceDefinition {
|
|
2
|
+
uri: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
/** Relative to the skills/ directory at the repo root. */
|
|
7
|
+
filePath: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const RESOURCE_DEFINITIONS: Record<string, ResourceDefinition>;
|
|
10
|
+
export declare function getResourceDefinition(uri: string): ResourceDefinition;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export const RESOURCE_DEFINITIONS = {
|
|
3
|
+
"skill://spaces-pages": {
|
|
4
|
+
uri: "skill://spaces-pages",
|
|
5
|
+
name: "Confluence Spaces & Pages",
|
|
6
|
+
description: "CQL construction and page-versioning guidance for the spaces/pages tools.",
|
|
7
|
+
mimeType: "text/markdown",
|
|
8
|
+
filePath: "spaces-pages.md",
|
|
9
|
+
},
|
|
10
|
+
"skill://content": {
|
|
11
|
+
uri: "skill://content",
|
|
12
|
+
name: "Confluence Content",
|
|
13
|
+
description: "Content properties, structure, labels, bulk operations, and attachments — real gotchas " +
|
|
14
|
+
"found live-verifying content.ts, content-structure.ts, labels.ts, bulk-pages.ts, and " +
|
|
15
|
+
"attachments.ts.",
|
|
16
|
+
mimeType: "text/markdown",
|
|
17
|
+
filePath: "content.md",
|
|
18
|
+
},
|
|
19
|
+
"skill://spaces-admin": {
|
|
20
|
+
uri: "skill://spaces-admin",
|
|
21
|
+
name: "Confluence Space Administration",
|
|
22
|
+
description: "Space lifecycle (create/update/archive/delete/trash) and color scheme management — real " +
|
|
23
|
+
"gotchas found live-verifying spaces-admin.ts and color-schemes.ts.",
|
|
24
|
+
mimeType: "text/markdown",
|
|
25
|
+
filePath: "spaces-admin.md",
|
|
26
|
+
},
|
|
27
|
+
"skill://permissions": {
|
|
28
|
+
uri: "skill://permissions",
|
|
29
|
+
name: "Confluence Permissions",
|
|
30
|
+
description: "Global and space-scoped permission read/grant/revoke/set — real gotchas found " +
|
|
31
|
+
"live-verifying permissions.ts.",
|
|
32
|
+
mimeType: "text/markdown",
|
|
33
|
+
filePath: "permissions.md",
|
|
34
|
+
},
|
|
35
|
+
"skill://users-groups": {
|
|
36
|
+
uri: "skill://users-groups",
|
|
37
|
+
name: "Confluence Users & Groups",
|
|
38
|
+
description: "User/group lookup, membership, watching, and admin account management — real gotchas " +
|
|
39
|
+
"found live-verifying users-groups.ts and admin-users-groups.ts.",
|
|
40
|
+
mimeType: "text/markdown",
|
|
41
|
+
filePath: "users-groups.md",
|
|
42
|
+
},
|
|
43
|
+
"skill://webhooks": {
|
|
44
|
+
uri: "skill://webhooks",
|
|
45
|
+
name: "Confluence Webhooks",
|
|
46
|
+
description: "Webhook lifecycle and testing — real gotchas found live-verifying webhooks.ts.",
|
|
47
|
+
mimeType: "text/markdown",
|
|
48
|
+
filePath: "webhooks.md",
|
|
49
|
+
},
|
|
50
|
+
"skill://instance-maintenance": {
|
|
51
|
+
uri: "skill://instance-maintenance",
|
|
52
|
+
name: "Confluence Backup, Restore & Search Index",
|
|
53
|
+
description: "Backup/restore jobs and search index management, including which operations are " +
|
|
54
|
+
"genuinely irreversible — real gotchas found live-verifying backup-restore.ts and " +
|
|
55
|
+
"index-management.ts.",
|
|
56
|
+
mimeType: "text/markdown",
|
|
57
|
+
filePath: "instance-maintenance.md",
|
|
58
|
+
},
|
|
59
|
+
"skill://system": {
|
|
60
|
+
uri: "skill://system",
|
|
61
|
+
name: "Confluence System Info & Search",
|
|
62
|
+
description: "Audit records, cluster status, instance metrics, long-running tasks, cross-entity search, " +
|
|
63
|
+
"and server information — real gotchas found live-verifying system.ts.",
|
|
64
|
+
mimeType: "text/markdown",
|
|
65
|
+
filePath: "system.md",
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export function getResourceDefinition(uri) {
|
|
69
|
+
const def = RESOURCE_DEFINITIONS[uri];
|
|
70
|
+
if (!def) {
|
|
71
|
+
throw new McpError(ErrorCode.InvalidParams, `Unknown resource: ${uri}`);
|
|
72
|
+
}
|
|
73
|
+
return def;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=resource-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-definitions.js","sourceRoot":"","sources":["../src/resource-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAWzE,MAAM,CAAC,MAAM,oBAAoB,GAAuC;IACtE,sBAAsB,EAAE;QACtB,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,2EAA2E;QACxF,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,iBAAiB;KAC5B;IACD,iBAAiB,EAAE;QACjB,GAAG,EAAE,iBAAiB;QACtB,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,yFAAyF;YACzF,uFAAuF;YACvF,iBAAiB;QACnB,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,YAAY;KACvB;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACT,0FAA0F;YAC1F,oEAAoE;QACtE,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,iBAAiB;KAC5B;IACD,qBAAqB,EAAE;QACrB,GAAG,EAAE,qBAAqB;QAC1B,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EACT,gFAAgF;YAChF,gCAAgC;QAClC,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,gBAAgB;KAC3B;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,sBAAsB;QAC3B,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,uFAAuF;YACvF,iEAAiE;QACnE,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,iBAAiB;KAC5B;IACD,kBAAkB,EAAE;QAClB,GAAG,EAAE,kBAAkB;QACvB,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,gFAAgF;QAC7F,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,aAAa;KACxB;IACD,8BAA8B,EAAE;QAC9B,GAAG,EAAE,8BAA8B;QACnC,IAAI,EAAE,2CAA2C;QACjD,WAAW,EACT,kFAAkF;YAClF,mFAAmF;YACnF,sBAAsB;QACxB,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,yBAAyB;KACpC;IACD,gBAAgB,EAAE;QAChB,GAAG,EAAE,gBAAgB;QACrB,IAAI,EAAE,iCAAiC;QACvC,WAAW,EACT,4FAA4F;YAC5F,uEAAuE;QACzE,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,WAAW;KACtB;CACF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ConfluenceClient } from "./confluence-client.js";
|
|
2
|
+
import { type ToolResult } from "./tools/spaces-pages.js";
|
|
3
|
+
export interface ToolDefinitionServer {
|
|
4
|
+
requireUserClient(): ConfluenceClient;
|
|
5
|
+
requireAdminClient(): ConfluenceClient;
|
|
6
|
+
handleGetApiReferences(args: Record<string, unknown> | undefined): Promise<ToolResult>;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolDefinition {
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: Record<string, unknown>;
|
|
11
|
+
requiresAdmin?: boolean;
|
|
12
|
+
handler: (server: ToolDefinitionServer, args: unknown) => Promise<ToolResult>;
|
|
13
|
+
}
|
|
14
|
+
export declare const TOOL_DEFINITIONS: Record<string, ToolDefinition>;
|
|
15
|
+
/**
|
|
16
|
+
* Pure filter used by the ListTools handler — admin-flagged tools are dropped entirely from the
|
|
17
|
+
* advertised tool list when no admin client is configured, not just rejected at call time.
|
|
18
|
+
*/
|
|
19
|
+
export declare function listableToolEntries(adminAvailable: boolean): Array<[string, ToolDefinition]>;
|