@roamcode.ai/server 1.0.0 → 1.0.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/dist/index.d.ts +2406 -82
- package/dist/index.js +8314 -44
- package/dist/managed-update-helper.js +621 -26
- package/dist/mcp-send.js +76 -90
- package/dist/start.d.ts +591 -9
- package/dist/start.js +7629 -353
- package/package.json +3 -3
- package/dist/auth.d.ts +0 -63
- package/dist/auth.js +0 -133
- package/dist/claude-auth-service.d.ts +0 -76
- package/dist/claude-auth-service.js +0 -217
- package/dist/claude-latest-service.d.ts +0 -34
- package/dist/claude-latest-service.js +0 -61
- package/dist/config.d.ts +0 -78
- package/dist/config.js +0 -59
- package/dist/data-dir.d.ts +0 -42
- package/dist/data-dir.js +0 -70
- package/dist/diag.d.ts +0 -43
- package/dist/diag.js +0 -83
- package/dist/fs-service.d.ts +0 -90
- package/dist/fs-service.js +0 -290
- package/dist/managed-runtime.d.ts +0 -51
- package/dist/managed-runtime.js +0 -411
- package/dist/managed-update-helper.d.ts +0 -2
- package/dist/mcp-send.d.ts +0 -33
- package/dist/origin-check.d.ts +0 -37
- package/dist/origin-check.js +0 -101
- package/dist/pane-status.d.ts +0 -61
- package/dist/pane-status.js +0 -145
- package/dist/providers/claude-metadata-service.d.ts +0 -58
- package/dist/providers/claude-metadata-service.js +0 -352
- package/dist/providers/claude-provider.d.ts +0 -11
- package/dist/providers/claude-provider.js +0 -166
- package/dist/providers/codex-activity.d.ts +0 -21
- package/dist/providers/codex-activity.js +0 -122
- package/dist/providers/codex-app-server-client.d.ts +0 -90
- package/dist/providers/codex-app-server-client.js +0 -485
- package/dist/providers/codex-latest-service.d.ts +0 -50
- package/dist/providers/codex-latest-service.js +0 -174
- package/dist/providers/codex-metadata-service.d.ts +0 -161
- package/dist/providers/codex-metadata-service.js +0 -686
- package/dist/providers/codex-profile-client.d.ts +0 -16
- package/dist/providers/codex-profile-client.js +0 -52
- package/dist/providers/codex-profile-security.d.ts +0 -23
- package/dist/providers/codex-profile-security.js +0 -161
- package/dist/providers/codex-provider.d.ts +0 -15
- package/dist/providers/codex-provider.js +0 -174
- package/dist/providers/codex-thread-coordinator.d.ts +0 -18
- package/dist/providers/codex-thread-coordinator.js +0 -93
- package/dist/providers/codex-thread-persistence.d.ts +0 -9
- package/dist/providers/codex-thread-persistence.js +0 -45
- package/dist/providers/codex-thread-resolver.d.ts +0 -59
- package/dist/providers/codex-thread-resolver.js +0 -322
- package/dist/providers/options.d.ts +0 -7
- package/dist/providers/options.js +0 -155
- package/dist/providers/provider-artifacts.d.ts +0 -3
- package/dist/providers/provider-artifacts.js +0 -30
- package/dist/providers/registry.d.ts +0 -7
- package/dist/providers/registry.js +0 -23
- package/dist/providers/types.d.ts +0 -95
- package/dist/providers/types.js +0 -8
- package/dist/push-dispatch.d.ts +0 -81
- package/dist/push-dispatch.js +0 -100
- package/dist/push-store.d.ts +0 -25
- package/dist/push-store.js +0 -79
- package/dist/rate-limit.d.ts +0 -52
- package/dist/rate-limit.js +0 -72
- package/dist/server-config.d.ts +0 -60
- package/dist/server-config.js +0 -77
- package/dist/service-install.d.ts +0 -60
- package/dist/service-install.js +0 -221
- package/dist/session-defaults.d.ts +0 -26
- package/dist/session-defaults.js +0 -60
- package/dist/session-store.d.ts +0 -81
- package/dist/session-store.js +0 -654
- package/dist/static-routes.d.ts +0 -101
- package/dist/static-routes.js +0 -188
- package/dist/terminal-capability.d.ts +0 -5
- package/dist/terminal-capability.js +0 -27
- package/dist/terminal-manager.d.ts +0 -224
- package/dist/terminal-manager.js +0 -917
- package/dist/terminal-process.d.ts +0 -85
- package/dist/terminal-process.js +0 -238
- package/dist/terminal-shared.d.ts +0 -36
- package/dist/terminal-shared.js +0 -43
- package/dist/tmux-list.d.ts +0 -11
- package/dist/tmux-list.js +0 -39
- package/dist/transport.d.ts +0 -123
- package/dist/transport.js +0 -1559
- package/dist/updater.d.ts +0 -161
- package/dist/updater.js +0 -451
- package/dist/usage-service.d.ts +0 -118
- package/dist/usage-service.js +0 -173
- package/dist/vapid.d.ts +0 -17
- package/dist/vapid.js +0 -31
- package/dist/web-push-send.d.ts +0 -20
- package/dist/web-push-send.js +0 -21
- package/dist/ws-ticket.d.ts +0 -47
- package/dist/ws-ticket.js +0 -62
package/dist/mcp-send.js
CHANGED
|
@@ -1,107 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* `POST /sessions/:id/attach`, which validates the path (fsRoot+realpath) and pushes an `attachment`
|
|
7
|
-
* frame over the session's WebSocket so the web renders it (image inline, file as a download).
|
|
8
|
-
*
|
|
9
|
-
* The connection params arrive via env, with Claude supplying RC_TOKEN directly and Codex supplying a
|
|
10
|
-
* provider-owned RC_TOKEN_FILE. No ANTHROPIC_API_KEY, no @anthropic-ai dependency — only the MCP SDK + zod.
|
|
11
|
-
*/
|
|
12
|
-
import { lstatSync, readFileSync } from "node:fs";
|
|
13
|
-
import { basename, isAbsolute } from "node:path";
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/mcp-send.ts
|
|
4
|
+
import { lstatSync, readFileSync } from "fs";
|
|
5
|
+
import { basename, isAbsolute } from "path";
|
|
14
6
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
15
7
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
16
8
|
import { z } from "zod";
|
|
17
9
|
function readTokenFile(path) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return undefined;
|
|
24
|
-
}
|
|
25
|
-
if (typeof process.getuid === "function" && info.uid !== process.getuid())
|
|
26
|
-
return undefined;
|
|
27
|
-
const token = readFileSync(path, "utf8");
|
|
28
|
-
return token.length <= 4096 && !/[\p{Cc}\p{Zl}\p{Zp}]/u.test(token) ? token : undefined;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return undefined;
|
|
10
|
+
try {
|
|
11
|
+
if (!isAbsolute(path)) return void 0;
|
|
12
|
+
const info = lstatSync(path);
|
|
13
|
+
if (!info.isFile() || info.isSymbolicLink() || (info.mode & 63) !== 0 || info.size < 1 || info.size > 4096) {
|
|
14
|
+
return void 0;
|
|
32
15
|
}
|
|
16
|
+
if (typeof process.getuid === "function" && info.uid !== process.getuid()) return void 0;
|
|
17
|
+
const token = readFileSync(path, "utf8");
|
|
18
|
+
return token.length <= 4096 && !/[\p{Cc}\p{Zl}\p{Zp}]/u.test(token) ? token : void 0;
|
|
19
|
+
} catch {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
33
22
|
}
|
|
34
23
|
function textResult(text, isError = false) {
|
|
35
|
-
|
|
24
|
+
return isError ? { content: [{ type: "text", text }], isError: true } : { content: [{ type: "text", text }] };
|
|
36
25
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
26
|
+
async function deliver(env, args, fetchImpl = fetch) {
|
|
27
|
+
const { RC_BASE_URL, RC_SESSION_ID } = env;
|
|
28
|
+
const token = env.RC_TOKEN || (env.RC_TOKEN_FILE ? readTokenFile(env.RC_TOKEN_FILE) : void 0);
|
|
29
|
+
if (!RC_BASE_URL || !RC_SESSION_ID || !token) {
|
|
30
|
+
return textResult("Attachment delivery is not configured (RC_BASE_URL / RC_SESSION_ID / RC_TOKEN missing).", true);
|
|
31
|
+
}
|
|
32
|
+
const url = `${RC_BASE_URL}/sessions/${RC_SESSION_ID}/attach`;
|
|
33
|
+
let res;
|
|
34
|
+
try {
|
|
35
|
+
res = await fetchImpl(url, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
38
|
+
body: JSON.stringify({ path: args.path, caption: args.caption, kind: args.kind })
|
|
39
|
+
});
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return textResult(`Could not reach roamcode to send the file: ${err.message}`, true);
|
|
42
|
+
}
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
let detail = `HTTP ${res.status}`;
|
|
50
45
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
body: JSON.stringify({ path: args.path, caption: args.caption, kind: args.kind }),
|
|
55
|
-
});
|
|
46
|
+
const body = await res.json();
|
|
47
|
+
if (typeof body.error === "string") detail = body.error;
|
|
48
|
+
} catch {
|
|
56
49
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (!res.ok) {
|
|
61
|
-
// Surface the server's error body (e.g. "path is outside the allowed root") so Claude can explain it.
|
|
62
|
-
let detail = `HTTP ${res.status}`;
|
|
63
|
-
try {
|
|
64
|
-
const body = (await res.json());
|
|
65
|
-
if (typeof body.error === "string")
|
|
66
|
-
detail = body.error;
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
// non-JSON error body — keep the status code detail
|
|
70
|
-
}
|
|
71
|
-
return textResult(`Failed to send ${basename(args.path)}: ${detail}`, true);
|
|
72
|
-
}
|
|
73
|
-
return textResult(`Sent ${basename(args.path)} to the user.`);
|
|
50
|
+
return textResult(`Failed to send ${basename(args.path)}: ${detail}`, true);
|
|
51
|
+
}
|
|
52
|
+
return textResult(`Sent ${basename(args.path)} to the user.`);
|
|
74
53
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
var SEND_PARAMS = {
|
|
55
|
+
path: z.string().describe("Absolute path to the file to send."),
|
|
56
|
+
caption: z.string().optional().describe("Optional caption shown with the file in the chat.")
|
|
78
57
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
58
|
+
function createMcpSendServer(env = process.env) {
|
|
59
|
+
const server = new McpServer({ name: "roamcode-send", version: "0.0.0" });
|
|
60
|
+
server.registerTool(
|
|
61
|
+
"send_image",
|
|
62
|
+
{
|
|
63
|
+
description: "Send an IMAGE to the user's chat so they can see it inline. Use when the user asks you to show/send an image, or to deliver a generated image. `path` must be an absolute path to the file.",
|
|
64
|
+
inputSchema: SEND_PARAMS
|
|
65
|
+
},
|
|
66
|
+
async ({ path, caption }) => deliver(env, { path, caption, kind: "image" })
|
|
67
|
+
);
|
|
68
|
+
server.registerTool(
|
|
69
|
+
"send_file",
|
|
70
|
+
{
|
|
71
|
+
description: "Send a FILE to the user's chat as a download. Use when the user asks you to send/deliver a file. `path` must be an absolute path.",
|
|
72
|
+
inputSchema: SEND_PARAMS
|
|
73
|
+
},
|
|
74
|
+
async ({ path, caption }) => deliver(env, { path, caption, kind: "file" })
|
|
75
|
+
);
|
|
76
|
+
return server;
|
|
93
77
|
}
|
|
94
|
-
/** Run the stdio server when executed directly (node dist/mcp-send.js). */
|
|
95
78
|
async function main() {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
79
|
+
const server = createMcpSendServer();
|
|
80
|
+
const transport = new StdioServerTransport();
|
|
81
|
+
await server.connect(transport);
|
|
99
82
|
}
|
|
100
|
-
// Only run when invoked as the entry script, not when imported by a test.
|
|
101
83
|
if (process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
main().catch((err) => {
|
|
85
|
+
process.stderr.write(`mcp-send failed to start: ${err.message}
|
|
86
|
+
`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
107
89
|
}
|
|
90
|
+
export {
|
|
91
|
+
createMcpSendServer,
|
|
92
|
+
deliver
|
|
93
|
+
};
|