rubien-mcp-server 0.1.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 +202 -0
- package/README.md +180 -0
- package/dist/auth.js +36 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas.js +166 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.js +33 -0
- package/dist/server.js.map +1 -0
- package/dist/toolHelpers.js +48 -0
- package/dist/toolHelpers.js.map +1 -0
- package/dist/tools/annotations.js +13 -0
- package/dist/tools/annotations.js.map +1 -0
- package/dist/tools/citations.js +44 -0
- package/dist/tools/citations.js.map +1 -0
- package/dist/tools/io.js +50 -0
- package/dist/tools/io.js.map +1 -0
- package/dist/tools/pdf.js +147 -0
- package/dist/tools/pdf.js.map +1 -0
- package/dist/tools/properties.js +247 -0
- package/dist/tools/properties.js.map +1 -0
- package/dist/tools/references.js +207 -0
- package/dist/tools/references.js.map +1 -0
- package/dist/tools/sync.js +10 -0
- package/dist/tools/sync.js.map +1 -0
- package/dist/tools/views.js +78 -0
- package/dist/tools/views.js.map +1 -0
- package/dist/tools/web.js +40 -0
- package/dist/tools/web.js.map +1 -0
- package/dist/versionGuard.js +30 -0
- package/dist/versionGuard.js.map +1 -0
- package/package.json +41 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
7
|
+
import { buildServer } from "./server.js";
|
|
8
|
+
import { requireBearer } from "./auth.js";
|
|
9
|
+
import { getCliVersion } from "./cli.js";
|
|
10
|
+
import { MIN_CLI_BUILD, evaluateCliVersion } from "./versionGuard.js";
|
|
11
|
+
const USAGE = `Usage:
|
|
12
|
+
rubien-mcp-server [--stdio]
|
|
13
|
+
rubien-mcp-server --http --port <port> --bearer-token <token>
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--stdio Start in stdio mode (default; use from Claude Code via \`claude mcp add\`).
|
|
17
|
+
--http Start an HTTP server (use with Cloudflare Tunnel for claude.ai).
|
|
18
|
+
--port <n> Port for HTTP mode (default 4000). Env: RUBIEN_MCP_PORT.
|
|
19
|
+
--bearer-token <t> Required bearer token for HTTP mode. Env: RUBIEN_MCP_BEARER.
|
|
20
|
+
--help Show this message.
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
# Claude Code
|
|
24
|
+
claude mcp add rubien node /path/to/mcp-server/dist/index.js
|
|
25
|
+
|
|
26
|
+
# claude.ai (remote MCP)
|
|
27
|
+
RUBIEN_MCP_BEARER=$(openssl rand -hex 32) \\
|
|
28
|
+
node dist/index.js --http --port 4000 --bearer-token "$RUBIEN_MCP_BEARER"
|
|
29
|
+
# then: cloudflared tunnel --url http://localhost:4000
|
|
30
|
+
`;
|
|
31
|
+
function parseCliArgs(argv) {
|
|
32
|
+
const { values } = parseArgs({
|
|
33
|
+
args: argv,
|
|
34
|
+
options: {
|
|
35
|
+
stdio: { type: "boolean" },
|
|
36
|
+
http: { type: "boolean" },
|
|
37
|
+
port: { type: "string" },
|
|
38
|
+
"bearer-token": { type: "string" },
|
|
39
|
+
help: { type: "boolean" },
|
|
40
|
+
},
|
|
41
|
+
allowPositionals: false,
|
|
42
|
+
});
|
|
43
|
+
if (values.help) {
|
|
44
|
+
process.stdout.write(USAGE);
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
const mode = values.http ? "http" : "stdio";
|
|
48
|
+
const port = Number(values.port ?? process.env.RUBIEN_MCP_PORT ?? "4000");
|
|
49
|
+
const bearerToken = values["bearer-token"] ??
|
|
50
|
+
process.env.RUBIEN_MCP_BEARER;
|
|
51
|
+
if (mode === "http") {
|
|
52
|
+
if (!bearerToken) {
|
|
53
|
+
process.stderr.write("--bearer-token (or RUBIEN_MCP_BEARER env) is required in --http mode\n");
|
|
54
|
+
process.exit(2);
|
|
55
|
+
}
|
|
56
|
+
if (!Number.isFinite(port) || port <= 0 || port > 65535) {
|
|
57
|
+
process.stderr.write(`invalid --port: ${port}\n`);
|
|
58
|
+
process.exit(2);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { mode, port, bearerToken };
|
|
62
|
+
}
|
|
63
|
+
async function runStdio() {
|
|
64
|
+
const server = buildServer();
|
|
65
|
+
const transport = new StdioServerTransport();
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
// MCP stdio transport keeps the process alive via stdin.
|
|
68
|
+
}
|
|
69
|
+
async function runHttp(port, bearerToken) {
|
|
70
|
+
const server = buildServer();
|
|
71
|
+
// Stateful single-session transport. We generate a new session ID per
|
|
72
|
+
// connection — single-user personal use doesn't need stateless.
|
|
73
|
+
const transport = new StreamableHTTPServerTransport({
|
|
74
|
+
sessionIdGenerator: () => randomUUID(),
|
|
75
|
+
});
|
|
76
|
+
await server.connect(transport);
|
|
77
|
+
const httpServer = createServer(async (req, res) => {
|
|
78
|
+
// Public unauthenticated paths: nothing.
|
|
79
|
+
if (!requireBearer(req, res, bearerToken))
|
|
80
|
+
return;
|
|
81
|
+
try {
|
|
82
|
+
await transport.handleRequest(req, res);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
process.stderr.write(`handleRequest failed: ${err.message}\n`);
|
|
86
|
+
if (!res.writableEnded) {
|
|
87
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
88
|
+
res.end('{"error":"internal transport error"}');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
await new Promise((resolve) => httpServer.listen(port, resolve));
|
|
93
|
+
process.stderr.write(`rubien-mcp-server listening on http://127.0.0.1:${port}\n`);
|
|
94
|
+
}
|
|
95
|
+
async function main() {
|
|
96
|
+
const args = parseCliArgs(process.argv.slice(2));
|
|
97
|
+
// Version guard: probe the resolved CLI once, before connecting any
|
|
98
|
+
// transport. `--help` already exited inside parseCliArgs, so help works
|
|
99
|
+
// even with no CLI installed.
|
|
100
|
+
const guard = evaluateCliVersion(await getCliVersion(), MIN_CLI_BUILD);
|
|
101
|
+
if (!guard.ok) {
|
|
102
|
+
// Set exitCode + return rather than process.exit(1): the async stderr
|
|
103
|
+
// write to a pipe can truncate if we exit immediately. No transport is
|
|
104
|
+
// connected and the probe child has finished, so the event loop drains
|
|
105
|
+
// and the process exits with code 1 after stderr flushes.
|
|
106
|
+
process.stderr.write((guard.message ?? "rubien-cli version check failed") + "\n");
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (args.mode === "stdio") {
|
|
111
|
+
await runStdio();
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
await runHttp(args.port, args.bearerToken);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
main().catch((err) => {
|
|
118
|
+
process.stderr.write(`fatal: ${err.stack ?? err.message}\n`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// -----------------------------------------------------------------------------
|
|
3
|
+
// Zod schemas mirroring the DTO structs in Sources/RubienCLI/RubienCLI.swift.
|
|
4
|
+
//
|
|
5
|
+
// Convention (load-bearing — a drift here silently breaks tool parsing):
|
|
6
|
+
// - Swift `let x: T?` (regular Optional) → `.optional()` in zod.
|
|
7
|
+
// Swift's JSONEncoder *omits* nil-valued optionals from output entirely,
|
|
8
|
+
// so `.nullable()` would fail to parse real CLI output.
|
|
9
|
+
// - `AlwaysEncodedOptional<T>` (e.g. DatabaseViewDTO.groupBy) → `.nullable()`.
|
|
10
|
+
// That wrapper forces an explicit `null` emission when nil.
|
|
11
|
+
// -----------------------------------------------------------------------------
|
|
12
|
+
const isoDateString = z
|
|
13
|
+
.string()
|
|
14
|
+
.describe("ISO-8601 timestamp with millisecond precision, e.g. 2026-04-24T12:00:00.000Z");
|
|
15
|
+
export const CustomPropertyValueDTO = z.object({
|
|
16
|
+
propertyId: z.string(),
|
|
17
|
+
name: z.string(),
|
|
18
|
+
type: z.string(),
|
|
19
|
+
value: z.string(),
|
|
20
|
+
});
|
|
21
|
+
export const ReferenceDTO = z.object({
|
|
22
|
+
id: z.number().int().optional(),
|
|
23
|
+
title: z.string(),
|
|
24
|
+
authors: z.string(),
|
|
25
|
+
year: z.number().int().optional(),
|
|
26
|
+
journal: z.string().optional(),
|
|
27
|
+
volume: z.string().optional(),
|
|
28
|
+
issue: z.string().optional(),
|
|
29
|
+
pages: z.string().optional(),
|
|
30
|
+
doi: z.string().optional(),
|
|
31
|
+
url: z.string().optional(),
|
|
32
|
+
siteName: z.string().optional(),
|
|
33
|
+
abstract: z.string().optional(),
|
|
34
|
+
referenceType: z.string(),
|
|
35
|
+
dateAdded: isoDateString,
|
|
36
|
+
dateModified: isoDateString,
|
|
37
|
+
pdfPath: z.string().optional(),
|
|
38
|
+
notes: z.string().optional(),
|
|
39
|
+
isbn: z.string().optional(),
|
|
40
|
+
issn: z.string().optional(),
|
|
41
|
+
publisher: z.string().optional(),
|
|
42
|
+
language: z.string().optional(),
|
|
43
|
+
edition: z.string().optional(),
|
|
44
|
+
readingStatus: z.string(),
|
|
45
|
+
// Reader activity (v4). `lastReadAt` is a Swift `Date?` and is omitted from
|
|
46
|
+
// CLI output when the reference has never been opened — `.optional()`, not
|
|
47
|
+
// `.nullable()` (see header comment). `readCount` is non-optional and
|
|
48
|
+
// always present, defaulting to 0.
|
|
49
|
+
lastReadAt: isoDateString.optional(),
|
|
50
|
+
readCount: z.number().int(),
|
|
51
|
+
customProperties: z.array(CustomPropertyValueDTO),
|
|
52
|
+
});
|
|
53
|
+
/// Mirror of `PropertyOptionDTO` in RubienCLI.swift. `value` is the canonical
|
|
54
|
+
/// identity (option string for custom selects; stringified tag id for the
|
|
55
|
+
/// built-in Tags property). `label` is the display text — equal to `value`
|
|
56
|
+
/// for custom options, and the Tag's name for Tags-routed options.
|
|
57
|
+
export const PropertyOptionDTO = z.object({
|
|
58
|
+
value: z.string(),
|
|
59
|
+
label: z.string(),
|
|
60
|
+
color: z.string(),
|
|
61
|
+
});
|
|
62
|
+
export const PropertyDefinitionDTO = z.object({
|
|
63
|
+
id: z.string(),
|
|
64
|
+
name: z.string(),
|
|
65
|
+
type: z.string(),
|
|
66
|
+
options: z.array(PropertyOptionDTO),
|
|
67
|
+
sortOrder: z.number().int(),
|
|
68
|
+
isDefault: z.boolean(),
|
|
69
|
+
defaultFieldKey: z.string().optional(),
|
|
70
|
+
isVisible: z.boolean(),
|
|
71
|
+
});
|
|
72
|
+
// PDF-download status DTO emitted by `add --identifier --download-pdf` and by
|
|
73
|
+
// `pdf download <id>`. Mirrors PDFDownloadStatusDTO in RubienCLI.swift.
|
|
74
|
+
// `action` is the raw value of PDFDownloadAction (downloaded | already-attached
|
|
75
|
+
// | already-pending | skipped). All fields except `ok` use plain `Optional` in
|
|
76
|
+
// Swift → key omitted when nil → `.optional()` here.
|
|
77
|
+
export const PDFDownloadStatusDTO = z.object({
|
|
78
|
+
ok: z.boolean(),
|
|
79
|
+
action: z.string().optional(),
|
|
80
|
+
filename: z.string().optional(),
|
|
81
|
+
error: z.string().optional(),
|
|
82
|
+
});
|
|
83
|
+
// Envelope returned by `add` (single object) or `add --bibtex` (array of these).
|
|
84
|
+
// `status` mirrors AppDatabase.ReferenceSaveResult.
|
|
85
|
+
// `pdfDownload` is an AlwaysEncodedOptional in Swift, so it's always present
|
|
86
|
+
// in the JSON — explicit `null` when --download-pdf wasn't set.
|
|
87
|
+
export const AddStatusOutput = z.object({
|
|
88
|
+
reference: ReferenceDTO,
|
|
89
|
+
status: z.enum(["created", "existing"]),
|
|
90
|
+
pdfDownload: PDFDownloadStatusDTO.nullable(),
|
|
91
|
+
});
|
|
92
|
+
// TagDTO retired alongside the rubien_tags_* MCP tool family. Tag rows now
|
|
93
|
+
// surface as inline options on the built-in Tags PropertyDefinition (see
|
|
94
|
+
// PropertyOptionDTO above): `value` is the stringified tag id, `label` is
|
|
95
|
+
// the tag name, `color` is the tag color.
|
|
96
|
+
// Citation outputs (three formats: text, bibliography, docx-cc).
|
|
97
|
+
export const CitationTextOutput = z.object({
|
|
98
|
+
style: z.string(),
|
|
99
|
+
inline: z.string(),
|
|
100
|
+
bibliography: z.array(z.string()),
|
|
101
|
+
});
|
|
102
|
+
export const CitationBibliographyOutput = z.object({
|
|
103
|
+
style: z.string(),
|
|
104
|
+
entries: z.array(z.string()),
|
|
105
|
+
});
|
|
106
|
+
export const CitationDocxCCOutput = z.object({
|
|
107
|
+
tag: z.string(),
|
|
108
|
+
text: z.string(),
|
|
109
|
+
style: z.string(),
|
|
110
|
+
isShortTag: z.boolean().optional(),
|
|
111
|
+
fallbackPayload: z.string().optional(),
|
|
112
|
+
});
|
|
113
|
+
// View DTO: groupBy uses AlwaysEncodedOptional → nullable in JSON.
|
|
114
|
+
export const ViewFilter = z.object({}).passthrough(); // structural detail varies; accept any shape
|
|
115
|
+
export const ViewSort = z.object({}).passthrough();
|
|
116
|
+
export const ColumnConfig = z.object({}).passthrough();
|
|
117
|
+
export const GroupConfig = z.object({}).passthrough();
|
|
118
|
+
export const ViewScope = z.object({}).passthrough();
|
|
119
|
+
export const DatabaseViewDTO = z.object({
|
|
120
|
+
id: z.number().int().optional(),
|
|
121
|
+
name: z.string(),
|
|
122
|
+
icon: z.string(),
|
|
123
|
+
isDefault: z.boolean(),
|
|
124
|
+
displayOrder: z.number().int(),
|
|
125
|
+
scope: ViewScope,
|
|
126
|
+
columns: z.array(ColumnConfig),
|
|
127
|
+
filters: z.array(ViewFilter),
|
|
128
|
+
sorts: z.array(ViewSort),
|
|
129
|
+
groupBy: GroupConfig.nullable(), // AlwaysEncodedOptional → explicit null
|
|
130
|
+
dateCreated: isoDateString,
|
|
131
|
+
dateModified: isoDateString,
|
|
132
|
+
});
|
|
133
|
+
export const AnnotationDTO = z.object({
|
|
134
|
+
id: z.number().int(),
|
|
135
|
+
type: z.string(),
|
|
136
|
+
color: z.string().optional(),
|
|
137
|
+
pageIndex: z.number().int().optional(),
|
|
138
|
+
selectedText: z.string().optional(),
|
|
139
|
+
noteText: z.string().optional(),
|
|
140
|
+
});
|
|
141
|
+
export const StyleDTO = z.object({
|
|
142
|
+
id: z.string(),
|
|
143
|
+
title: z.string(),
|
|
144
|
+
isBuiltin: z.boolean(),
|
|
145
|
+
citationKind: z.string(),
|
|
146
|
+
});
|
|
147
|
+
export const SyncStatusDTO = z
|
|
148
|
+
.object({
|
|
149
|
+
enabled: z.boolean(),
|
|
150
|
+
containerIdentifier: z.string().optional(),
|
|
151
|
+
entitlementPresent: z.boolean(),
|
|
152
|
+
iCloudAccountAvailable: z.boolean(),
|
|
153
|
+
appLockHeld: z.boolean().optional(),
|
|
154
|
+
baselineState: z.string(),
|
|
155
|
+
dirtyByEntityType: z.record(z.number()).optional(),
|
|
156
|
+
tombstoneCount: z.number().optional(),
|
|
157
|
+
syncEngineState: z.unknown().optional(),
|
|
158
|
+
schemaVersion: z.number().int().optional(),
|
|
159
|
+
})
|
|
160
|
+
.passthrough(); // sync status is relatively fluid; keep forward-compat
|
|
161
|
+
export const DeleteResultDTO = z.object({ deleted: z.string() });
|
|
162
|
+
export const ImportResultDTO = z
|
|
163
|
+
.object({ imported: z.number().int(), file: z.string() })
|
|
164
|
+
.passthrough();
|
|
165
|
+
export const CliErrorDTO = z.object({ error: z.string() });
|
|
166
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { registerReferenceTools } from "./tools/references.js";
|
|
3
|
+
import { registerCitationTools } from "./tools/citations.js";
|
|
4
|
+
import { registerIOTools } from "./tools/io.js";
|
|
5
|
+
import { registerPropertyTools } from "./tools/properties.js";
|
|
6
|
+
import { registerViewTools } from "./tools/views.js";
|
|
7
|
+
import { registerAnnotationTools } from "./tools/annotations.js";
|
|
8
|
+
import { registerSyncTools } from "./tools/sync.js";
|
|
9
|
+
import { registerPdfTools } from "./tools/pdf.js";
|
|
10
|
+
import { registerWebTools } from "./tools/web.js";
|
|
11
|
+
export const SERVER_INFO = {
|
|
12
|
+
name: "rubien-mcp-server",
|
|
13
|
+
version: "0.1.0",
|
|
14
|
+
};
|
|
15
|
+
export function buildServer() {
|
|
16
|
+
const server = new McpServer(SERVER_INFO, {
|
|
17
|
+
capabilities: { tools: {} },
|
|
18
|
+
});
|
|
19
|
+
registerReferenceTools(server);
|
|
20
|
+
registerCitationTools(server);
|
|
21
|
+
registerIOTools(server);
|
|
22
|
+
// Tags are exposed through the `properties` family against the built-in
|
|
23
|
+
// Tags PropertyDefinition (defaultFieldKey == "tags"). The standalone
|
|
24
|
+
// rubien_tags_* tool family was retired — see properties.ts.
|
|
25
|
+
registerPropertyTools(server);
|
|
26
|
+
registerViewTools(server);
|
|
27
|
+
registerAnnotationTools(server);
|
|
28
|
+
registerPdfTools(server);
|
|
29
|
+
registerWebTools(server);
|
|
30
|
+
registerSyncTools(server);
|
|
31
|
+
return server;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,OAAO;CACR,CAAC;AAEX,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,WAAW,EAAE;QACxC,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;KAC5B,CAAC,CAAC;IAEH,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,wEAAwE;IACxE,sEAAsE;IACtE,6DAA6D;IAC7D,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE1B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { CliError, invokeCli } from "./cli.js";
|
|
2
|
+
/**
|
|
3
|
+
* Invoke rubien-cli and wrap the result as a CallToolResult. Errors from the
|
|
4
|
+
* CLI are mapped to `isError: true` with the stderr message. Any other error
|
|
5
|
+
* (missing binary, timeout) propagates as an exception which the MCP SDK
|
|
6
|
+
* converts into a protocol-level error.
|
|
7
|
+
*
|
|
8
|
+
* We only return text content (pretty-printed JSON). MCP's `structuredContent`
|
|
9
|
+
* expects an object-shape, but many CLI responses are arrays — returning them
|
|
10
|
+
* as plain text keeps the Claude-facing contract simple and lossless.
|
|
11
|
+
*/
|
|
12
|
+
export async function runCliAsTool(args, options = {}) {
|
|
13
|
+
try {
|
|
14
|
+
const result = await invokeCli(args, options);
|
|
15
|
+
const asText = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: asText }],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err instanceof CliError) {
|
|
22
|
+
return {
|
|
23
|
+
content: [{ type: "text", text: err.message }],
|
|
24
|
+
isError: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Filter undefined values out of an optional-argument map and render them as
|
|
32
|
+
* `--flag value` / `--flag` pairs. Undefined/null skip the flag entirely.
|
|
33
|
+
*/
|
|
34
|
+
export function flagsFromOptions(opts) {
|
|
35
|
+
const out = [];
|
|
36
|
+
for (const [key, value] of Object.entries(opts)) {
|
|
37
|
+
if (value === undefined || value === null)
|
|
38
|
+
continue;
|
|
39
|
+
if (typeof value === "boolean") {
|
|
40
|
+
if (value)
|
|
41
|
+
out.push(key);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
out.push(key, String(value));
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=toolHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolHelpers.js","sourceRoot":"","sources":["../src/toolHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc,EAAE,UAAsB,EAAE;IACzE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GACV,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;gBACvD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAkE;IAElE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { runCliAsTool } from "../toolHelpers.js";
|
|
3
|
+
export function registerAnnotationTools(server) {
|
|
4
|
+
server.registerTool("rubien_annotations_list", {
|
|
5
|
+
title: "List PDF annotations for a reference",
|
|
6
|
+
description: "Return all PDF annotations (highlights, underlines, anchored notes) on a single reference's attached PDF. PDF references only — for clipped web pages, use `rubien_web_annotations` instead. Returns [{ id, type, color, pageIndex, selectedText, noteText }].",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
referenceId: z.number().int(),
|
|
9
|
+
},
|
|
10
|
+
annotations: { readOnlyHint: true },
|
|
11
|
+
}, async ({ referenceId }) => runCliAsTool(["annotations", String(referenceId)]));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=annotations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/tools/annotations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EACT,gQAAgQ;QAClQ,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;SAC9B;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CACxB,YAAY,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CACrD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { runCliAsTool } from "../toolHelpers.js";
|
|
3
|
+
const BUILTIN_STYLES = [
|
|
4
|
+
"apa",
|
|
5
|
+
"mla",
|
|
6
|
+
"chicago",
|
|
7
|
+
"ieee",
|
|
8
|
+
"harvard",
|
|
9
|
+
"vancouver",
|
|
10
|
+
"nature",
|
|
11
|
+
];
|
|
12
|
+
const CITE_FORMATS = ["text", "bibliography", "docx-cc"];
|
|
13
|
+
export function registerCitationTools(server) {
|
|
14
|
+
server.registerTool("rubien_cite", {
|
|
15
|
+
title: "Format citations",
|
|
16
|
+
description: "Generate formatted citations for one or more references. Output shape varies by format: `text` → { style, inline, bibliography }, `bibliography` → { style, entries }, `docx-cc` → { tag, text, style, isShortTag?, fallbackPayload? }. Use arbitrary CSL style IDs from `rubien_styles_list` if needed.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
ids: z.array(z.number().int()).min(1).describe("Reference IDs to cite"),
|
|
19
|
+
style: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe(`Citation style (default apa). Built-ins: ${BUILTIN_STYLES.join(", ")}. Any CSL ID from rubien_styles_list also works.`),
|
|
23
|
+
format: z
|
|
24
|
+
.enum(CITE_FORMATS)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Output format (default text). 'bibliography' for reference-list entries only; 'docx-cc' for Word content-control tags."),
|
|
27
|
+
},
|
|
28
|
+
annotations: { readOnlyHint: true },
|
|
29
|
+
}, async ({ ids, style, format }) => {
|
|
30
|
+
const args = ["cite", ...ids.map((n) => String(n))];
|
|
31
|
+
if (style)
|
|
32
|
+
args.push("--style", style);
|
|
33
|
+
if (format)
|
|
34
|
+
args.push("--format", format);
|
|
35
|
+
return runCliAsTool(args);
|
|
36
|
+
});
|
|
37
|
+
server.registerTool("rubien_styles_list", {
|
|
38
|
+
title: "List citation styles",
|
|
39
|
+
description: "List all available citation styles (built-in + installed CSL). Use the returned `id` as the `style` argument to rubien_cite.",
|
|
40
|
+
inputSchema: {},
|
|
41
|
+
annotations: { readOnlyHint: true },
|
|
42
|
+
}, async () => runCliAsTool(["styles"]));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=citations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citations.js","sourceRoot":"","sources":["../../src/tools/citations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,cAAc,GAAG;IACrB,KAAK;IACL,KAAK;IACL,SAAS;IACT,MAAM;IACN,SAAS;IACT,WAAW;IACX,QAAQ;CACA,CAAC;AAEX,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,CAAU,CAAC;AAElE,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,0SAA0S;QAC5S,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YACvE,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,4CAA4C,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,kDAAkD,CACxH;YACH,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,YAAY,CAAC;iBAClB,QAAQ,EAAE;iBACV,QAAQ,CACP,wHAAwH,CACzH;SACJ;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAa,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACvC,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,8HAA8H;QAChI,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CACrC,CAAC;AACJ,CAAC"}
|
package/dist/tools/io.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { flagsFromOptions, runCliAsTool } from "../toolHelpers.js";
|
|
3
|
+
export function registerIOTools(server) {
|
|
4
|
+
server.registerTool("rubien_import", {
|
|
5
|
+
title: "Import from BibTeX/RIS/Zotero folder",
|
|
6
|
+
description: "Import references from a file (BibTeX .bib / RIS .ris) or a Zotero-exported folder. For folder imports you can stamp a single-/multi-select property value on every imported reference via property + value.",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
file: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe("Absolute path on the host. Stdin piping ('-') is not supported through the MCP wrapper; if you need it, invoke rubien-cli directly."),
|
|
11
|
+
format: z
|
|
12
|
+
.enum(["bib", "ris"])
|
|
13
|
+
.optional()
|
|
14
|
+
.describe("Override the format inferred from the file extension."),
|
|
15
|
+
property: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("(Zotero folder only) Property name to stamp on imported refs"),
|
|
19
|
+
value: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("(Zotero folder only) Value for --property on imported refs"),
|
|
23
|
+
},
|
|
24
|
+
annotations: { destructiveHint: true },
|
|
25
|
+
}, async ({ file, format, property, value }) => runCliAsTool([
|
|
26
|
+
"import",
|
|
27
|
+
file,
|
|
28
|
+
...flagsFromOptions({
|
|
29
|
+
"--format": format,
|
|
30
|
+
"--property": property,
|
|
31
|
+
"--value": value,
|
|
32
|
+
}),
|
|
33
|
+
], { timeoutMs: 180_000 }));
|
|
34
|
+
server.registerTool("rubien_export", {
|
|
35
|
+
title: "Export references",
|
|
36
|
+
description: "Export the library (or a subset) as JSON, BibTeX, or RIS. BibTeX/RIS output is plain text; JSON is a ReferenceDTO[] array.",
|
|
37
|
+
inputSchema: {
|
|
38
|
+
format: z.enum(["json", "bibtex", "ris"]).optional()
|
|
39
|
+
.describe("Default is json"),
|
|
40
|
+
},
|
|
41
|
+
annotations: { readOnlyHint: true },
|
|
42
|
+
}, async ({ format }) => {
|
|
43
|
+
const args = ["export"];
|
|
44
|
+
if (format)
|
|
45
|
+
args.push("--format", format);
|
|
46
|
+
const textMode = format === "bibtex" || format === "ris";
|
|
47
|
+
return runCliAsTool(args, { textMode });
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/tools/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EACT,8MAA8M;QAChN,WAAW,EAAE;YACX,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,CACP,qIAAqI,CACtI;YACH,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;iBACpB,QAAQ,EAAE;iBACV,QAAQ,CAAC,uDAAuD,CAAC;YACpE,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,8DAA8D,CAAC;YAC3E,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,4DAA4D,CAAC;SAC1E;QACD,WAAW,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;KACvC,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CAC1C,YAAY,CACV;QACE,QAAQ;QACR,IAAI;QACJ,GAAG,gBAAgB,CAAC;YAClB,UAAU,EAAE,MAAM;YAClB,YAAY,EAAE,QAAQ;YACtB,SAAS,EAAE,KAAK;SACjB,CAAC;KACH,EACD,EAAE,SAAS,EAAE,OAAO,EAAE,CACvB,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EACT,4HAA4H;QAC9H,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;iBACjD,QAAQ,CAAC,iBAAiB,CAAC;SAC/B;QACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,KAAK,CAAC;QACzD,OAAO,YAAY,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1C,CAAC,CACF,CAAC;AACJ,CAAC"}
|