@telecabin/mcp 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/dist/format.js +46 -0
- package/dist/format.js.map +1 -0
- package/dist/index.js +227 -0
- package/dist/index.js.map +1 -0
- package/dist/session.js +36 -0
- package/dist/session.js.map +1 -0
- package/package.json +38 -0
package/dist/format.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Render one event as a compact, agent-readable line. */
|
|
2
|
+
export function formatEvent(e, names) {
|
|
3
|
+
const who = e.authorName ??
|
|
4
|
+
(e.participantId ? names.get(e.participantId) : null) ??
|
|
5
|
+
(e.participantId ? `~${e.participantId.slice(0, 8)}` : "someone");
|
|
6
|
+
if (e.kind === "message") {
|
|
7
|
+
return `[#${e.id}] ${who}: ${e.content ?? ""}`;
|
|
8
|
+
}
|
|
9
|
+
const status = e.meta?.status ?? "?";
|
|
10
|
+
return `[#${e.id}] ${who} → status: ${status}`;
|
|
11
|
+
}
|
|
12
|
+
/** Render a session snapshot as a readable text block for an AI to consume. */
|
|
13
|
+
export function formatSnapshot(s) {
|
|
14
|
+
const names = new Map(s.participants.map((p) => [p.id, p.name]));
|
|
15
|
+
const lines = [];
|
|
16
|
+
lines.push(`Session "${s.session.name}" (slug: ${s.session.slug}) — ${s.session.status}`);
|
|
17
|
+
lines.push(`You are "${s.me.name}".`);
|
|
18
|
+
lines.push("");
|
|
19
|
+
lines.push(`Participants (${s.participants.length}):`);
|
|
20
|
+
for (const p of s.participants) {
|
|
21
|
+
const me = p.id === s.me.id ? " (you)" : "";
|
|
22
|
+
const revoked = p.revokedAt ? " [revoked]" : "";
|
|
23
|
+
lines.push(` - ${p.name}${me}: ${p.status}${revoked}`);
|
|
24
|
+
}
|
|
25
|
+
lines.push("");
|
|
26
|
+
lines.push("Recent messages:");
|
|
27
|
+
if (s.events.length === 0) {
|
|
28
|
+
lines.push(" (none yet)");
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
for (const e of s.events)
|
|
32
|
+
lines.push(` ${formatEvent(e, names)}`);
|
|
33
|
+
}
|
|
34
|
+
lines.push("");
|
|
35
|
+
lines.push(`Cursor: ${s.cursor} — pass this to telecabin_read / telecabin_wait to get newer events.`);
|
|
36
|
+
return lines.join("\n");
|
|
37
|
+
}
|
|
38
|
+
/** Render a list of polled events plus the new cursor. */
|
|
39
|
+
export function formatEvents(events, cursor, names) {
|
|
40
|
+
if (events.length === 0) {
|
|
41
|
+
return `No new events. Cursor: ${cursor}`;
|
|
42
|
+
}
|
|
43
|
+
const lines = events.map((e) => formatEvent(e, names));
|
|
44
|
+
return `${lines.join("\n")}\n\nCursor: ${cursor}`;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { addConnection, DEFAULT_BASE_URL, resolveConnection, TelecabinClient, TelecabinError, } from "@telecabin/core";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { formatEvents, formatSnapshot } from "./format.js";
|
|
7
|
+
import { getActive, preloadActive, setActive } from "./session.js";
|
|
8
|
+
/** A successful tool result carrying a single text block. */
|
|
9
|
+
function ok(text) {
|
|
10
|
+
return { content: [{ type: "text", text }] };
|
|
11
|
+
}
|
|
12
|
+
/** A failed tool result — `isError` tells the model the call did not succeed. */
|
|
13
|
+
function fail(err) {
|
|
14
|
+
const text = err instanceof TelecabinError
|
|
15
|
+
? `${err.code}: ${err.message}`
|
|
16
|
+
: `error: ${err.message}`;
|
|
17
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
18
|
+
}
|
|
19
|
+
const STATUS = z.enum(["idle", "thinking", "generating", "tool_call", "error"]);
|
|
20
|
+
const INSTRUCTIONS = `telecabin connects you to a shared chat session with other AIs and people.
|
|
21
|
+
|
|
22
|
+
Typical flow:
|
|
23
|
+
1. telecabin_join (invite code) — or telecabin_connect if a session is already configured.
|
|
24
|
+
2. telecabin_get_session — see who is here and what has been said.
|
|
25
|
+
3. telecabin_send — say something. telecabin_set_status — show what you are doing.
|
|
26
|
+
4. telecabin_wait — block until someone else replies, then continue.
|
|
27
|
+
|
|
28
|
+
Etiquette: keep messages short, take turns, set your status before long work, and
|
|
29
|
+
read recent context before replying.`;
|
|
30
|
+
async function main() {
|
|
31
|
+
const server = new McpServer({ name: "telecabin", version: "0.1.0" }, { instructions: INSTRUCTIONS });
|
|
32
|
+
// --- telecabin_join ----------------------------------------------------
|
|
33
|
+
server.registerTool("telecabin_join", {
|
|
34
|
+
title: "Join a session",
|
|
35
|
+
description: "Join a telecabin session with an invite code. Mints a participant token, makes the session active for this server, saves it for reuse, and returns the session snapshot. Usually the first thing to call.",
|
|
36
|
+
inputSchema: {
|
|
37
|
+
code: z.string().describe("Invite code shared by the session owner."),
|
|
38
|
+
name: z.string().describe("Your display name in the session."),
|
|
39
|
+
url: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(`Base URL of the deployment. Defaults to ${DEFAULT_BASE_URL}.`),
|
|
43
|
+
},
|
|
44
|
+
}, async ({ code, name, url }) => {
|
|
45
|
+
try {
|
|
46
|
+
const baseUrl = url ?? process.env.TELECABIN_BASE_URL ?? DEFAULT_BASE_URL;
|
|
47
|
+
const res = await TelecabinClient.join({ baseUrl, code, name });
|
|
48
|
+
const connection = {
|
|
49
|
+
baseUrl,
|
|
50
|
+
slug: res.slug,
|
|
51
|
+
token: res.token,
|
|
52
|
+
sessionName: res.sessionName,
|
|
53
|
+
participantName: res.participant.name,
|
|
54
|
+
};
|
|
55
|
+
setActive({ name: res.slug, ...connection });
|
|
56
|
+
await addConnection(res.slug, connection, { makeDefault: true });
|
|
57
|
+
const snap = await getActive().client.snapshot();
|
|
58
|
+
return ok(`Joined "${res.sessionName}" as ${res.participant.name}.\n\n${formatSnapshot(snap)}`);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
return fail(err);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
// --- telecabin_connect -------------------------------------------------
|
|
65
|
+
server.registerTool("telecabin_connect", {
|
|
66
|
+
title: "Connect to a known session",
|
|
67
|
+
description: "Attach to a session you already have credentials for — a saved connection by name, or an explicit url/slug/token. Use telecabin_join instead if you only have an invite code.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
connection: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe("Name of a saved connection to use."),
|
|
73
|
+
url: z.string().optional().describe("Base URL of the deployment."),
|
|
74
|
+
slug: z.string().optional().describe("Session slug."),
|
|
75
|
+
token: z.string().optional().describe("Participant bearer token."),
|
|
76
|
+
},
|
|
77
|
+
}, async ({ connection, url, slug, token }) => {
|
|
78
|
+
try {
|
|
79
|
+
const conn = await resolveConnection({
|
|
80
|
+
connection,
|
|
81
|
+
baseUrl: url,
|
|
82
|
+
slug,
|
|
83
|
+
token,
|
|
84
|
+
});
|
|
85
|
+
setActive(conn);
|
|
86
|
+
const snap = await getActive().client.snapshot();
|
|
87
|
+
return ok(`Connected to "${snap.session.name}".\n\n${formatSnapshot(snap)}`);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
return fail(err);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
// --- telecabin_get_session --------------------------------------------
|
|
94
|
+
server.registerTool("telecabin_get_session", {
|
|
95
|
+
title: "Get session snapshot",
|
|
96
|
+
description: "Get the current session state: status, participants with their presence, the most recent messages, and the cursor to poll from.",
|
|
97
|
+
}, async () => {
|
|
98
|
+
try {
|
|
99
|
+
const snap = await getActive().client.snapshot();
|
|
100
|
+
return ok(formatSnapshot(snap));
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
return fail(err);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// --- telecabin_read ----------------------------------------------------
|
|
107
|
+
server.registerTool("telecabin_read", {
|
|
108
|
+
title: "Read messages",
|
|
109
|
+
description: "Read session activity. With no cursor, returns the recent snapshot. With `after`, returns only events newer than that cursor (delta poll).",
|
|
110
|
+
inputSchema: {
|
|
111
|
+
after: z
|
|
112
|
+
.number()
|
|
113
|
+
.int()
|
|
114
|
+
.min(0)
|
|
115
|
+
.optional()
|
|
116
|
+
.describe("Cursor — return only events with a higher id."),
|
|
117
|
+
limit: z
|
|
118
|
+
.number()
|
|
119
|
+
.int()
|
|
120
|
+
.min(1)
|
|
121
|
+
.max(500)
|
|
122
|
+
.optional()
|
|
123
|
+
.describe("Maximum number of events to return (default 100)."),
|
|
124
|
+
},
|
|
125
|
+
}, async ({ after, limit }) => {
|
|
126
|
+
try {
|
|
127
|
+
const { client } = getActive();
|
|
128
|
+
const snap = await client.snapshot();
|
|
129
|
+
if (after === undefined)
|
|
130
|
+
return ok(formatSnapshot(snap));
|
|
131
|
+
const names = new Map(snap.participants.map((p) => [p.id, p.name]));
|
|
132
|
+
const res = await client.poll(after, limit);
|
|
133
|
+
return ok(formatEvents(res.events, res.cursor, names));
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
return fail(err);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// --- telecabin_wait ----------------------------------------------------
|
|
140
|
+
server.registerTool("telecabin_wait", {
|
|
141
|
+
title: "Wait for a reply",
|
|
142
|
+
description: "Block until another participant posts a message after the given cursor, or the timeout elapses. Use this for turn-taking. On timeout, call it again with the returned cursor to keep waiting.",
|
|
143
|
+
inputSchema: {
|
|
144
|
+
after: z
|
|
145
|
+
.number()
|
|
146
|
+
.int()
|
|
147
|
+
.min(0)
|
|
148
|
+
.describe("Cursor to wait past — events with a higher id."),
|
|
149
|
+
timeout_sec: z
|
|
150
|
+
.number()
|
|
151
|
+
.int()
|
|
152
|
+
.min(1)
|
|
153
|
+
.max(55)
|
|
154
|
+
.optional()
|
|
155
|
+
.describe("How long to wait before returning empty (default 45)."),
|
|
156
|
+
},
|
|
157
|
+
}, async ({ after, timeout_sec }) => {
|
|
158
|
+
try {
|
|
159
|
+
const { client } = getActive();
|
|
160
|
+
const snap = await client.snapshot();
|
|
161
|
+
const names = new Map(snap.participants.map((p) => [p.id, p.name]));
|
|
162
|
+
const seconds = timeout_sec ?? 45;
|
|
163
|
+
const res = await client.waitForEvent(after, {
|
|
164
|
+
timeoutSec: seconds,
|
|
165
|
+
filter: (e) => e.kind === "message" && e.participantId !== snap.me.id,
|
|
166
|
+
});
|
|
167
|
+
if (res.events.length === 0) {
|
|
168
|
+
return ok(`No new messages from others within ${seconds}s. Cursor: ${res.cursor}. Call telecabin_wait again with this cursor to keep waiting.`);
|
|
169
|
+
}
|
|
170
|
+
return ok(formatEvents(res.events, res.cursor, names));
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
return fail(err);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
// --- telecabin_send ----------------------------------------------------
|
|
177
|
+
server.registerTool("telecabin_send", {
|
|
178
|
+
title: "Send a message",
|
|
179
|
+
description: "Post a message to the session. This also resets your status to idle.",
|
|
180
|
+
inputSchema: {
|
|
181
|
+
content: z
|
|
182
|
+
.string()
|
|
183
|
+
.min(1)
|
|
184
|
+
.max(32_000)
|
|
185
|
+
.describe("The message text to post."),
|
|
186
|
+
},
|
|
187
|
+
}, async ({ content }) => {
|
|
188
|
+
try {
|
|
189
|
+
const event = await getActive().client.send(content);
|
|
190
|
+
return ok(`Sent (event #${event.id}).`);
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
return fail(err);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// --- telecabin_set_status ---------------------------------------------
|
|
197
|
+
server.registerTool("telecabin_set_status", {
|
|
198
|
+
title: "Set your status",
|
|
199
|
+
description: "Broadcast your presence so others know what you are doing: idle, thinking, generating, tool_call, or error.",
|
|
200
|
+
inputSchema: {
|
|
201
|
+
status: STATUS.describe("Your new presence status."),
|
|
202
|
+
meta: z
|
|
203
|
+
.record(z.string(), z.unknown())
|
|
204
|
+
.optional()
|
|
205
|
+
.describe("Optional structured detail attached to the status."),
|
|
206
|
+
},
|
|
207
|
+
}, async ({ status, meta }) => {
|
|
208
|
+
try {
|
|
209
|
+
await getActive().client.setStatus(status, meta);
|
|
210
|
+
return ok(`Status set to ${status}.`);
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return fail(err);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
const preloaded = await preloadActive();
|
|
217
|
+
const transport = new StdioServerTransport();
|
|
218
|
+
await server.connect(transport);
|
|
219
|
+
process.stderr.write(preloaded
|
|
220
|
+
? `[telecabin-mcp] ready — active session: ${preloaded.sessionName ?? preloaded.slug}\n`
|
|
221
|
+
: "[telecabin-mcp] ready — no active session; call telecabin_join or telecabin_connect\n");
|
|
222
|
+
}
|
|
223
|
+
main().catch((err) => {
|
|
224
|
+
process.stderr.write(`[telecabin-mcp] fatal: ${err.message}\n`);
|
|
225
|
+
process.exit(1);
|
|
226
|
+
});
|
|
227
|
+
//# 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/session.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { resolveConnection, TelecabinClient, TelecabinError, } from "@telecabin/core";
|
|
2
|
+
/** The session this MCP server process is currently attached to, if any. */
|
|
3
|
+
let active = null;
|
|
4
|
+
/** Attach to a session — replaces any previously active one. */
|
|
5
|
+
export function setActive(conn) {
|
|
6
|
+
active = {
|
|
7
|
+
client: new TelecabinClient({
|
|
8
|
+
baseUrl: conn.baseUrl,
|
|
9
|
+
slug: conn.slug,
|
|
10
|
+
token: conn.token,
|
|
11
|
+
}),
|
|
12
|
+
conn,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** Get the active session, or throw a clear `no_active_session` error. */
|
|
16
|
+
export function getActive() {
|
|
17
|
+
if (!active) {
|
|
18
|
+
throw new TelecabinError("no_active_session", "Not attached to a session. Call telecabin_join (with an invite code) or telecabin_connect first.");
|
|
19
|
+
}
|
|
20
|
+
return active;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Attempt to attach to a session from `TELECABIN_*` env vars or the saved
|
|
24
|
+
* default connection. Returns the connection on success, null otherwise.
|
|
25
|
+
*/
|
|
26
|
+
export async function preloadActive() {
|
|
27
|
+
try {
|
|
28
|
+
const conn = await resolveConnection();
|
|
29
|
+
setActive(conn);
|
|
30
|
+
return conn;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,GAEf,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAC5E,IAAI,MAAM,GAAiE,IAAI,CAAC;AAEhF,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,IAAwB;IAChD,MAAM,GAAG;QACP,MAAM,EAAE,IAAI,eAAe,CAAC;YAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;QACF,IAAI;KACL,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,cAAc,CACtB,mBAAmB,EACnB,kGAAkG,CACnG,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@telecabin/mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for telecabin — lets any MCP-capable AI join shared chat sessions",
|
|
5
|
+
"homepage": "https://telecabin.app",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/JMMonte/telecabin.git",
|
|
9
|
+
"directory": "packages/mcp"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"bin": {
|
|
16
|
+
"telecabin-mcp": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
26
|
+
"zod": "^4.4.3",
|
|
27
|
+
"@telecabin/core": "0.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.10.5",
|
|
31
|
+
"typescript": "^5.7.3"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.json",
|
|
35
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
36
|
+
"clean": "rm -rf dist"
|
|
37
|
+
}
|
|
38
|
+
}
|