@relaymessenger/mcp 0.1.0-staging.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Relay Messenger, Inc.
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,100 @@
1
+ # Relay MCP
2
+
3
+ `@relaymessenger/mcp` is a local MCP v2 stdio server for current Relay v1
4
+ Agent tools. It uses `@modelcontextprotocol/server@2` and delegates every
5
+ Relay request and response type to `@relaymessenger/sdk`.
6
+
7
+ ## Transport and security status
8
+
9
+ **Implemented:** local process-spawned stdio, including MCP v2 modern-era
10
+ negotiation and legacy client compatibility.
11
+
12
+ **Not implemented:** remote HTTP transport and remote OAuth. The package does
13
+ not open a port, advertise a remote endpoint, or claim remote authentication.
14
+ Those stay out until Relay has a secure authorization, audience, scope,
15
+ session, origin, revocation, and deployment design with hosted tests.
16
+
17
+ The stdio host is the security boundary. Only configure this server in a
18
+ trusted local MCP client.
19
+
20
+ ## Install and configure
21
+
22
+ ```sh
23
+ npm install --global @relaymessenger/mcp
24
+ relay-mcp --version
25
+ ```
26
+
27
+ The server resolves an Agent Token locally; it never exposes a token as an MCP
28
+ tool argument.
29
+
30
+ Resolution order:
31
+
32
+ 1. `RELAY_AGENT_TOKEN`, `RELAY_API_URL`, and `RELAY_PROFILE`;
33
+ 2. `${XDG_CONFIG_HOME:-~/.config}/relay/config.json`, shared with
34
+ `@relaymessenger/cli`;
35
+ 3. `https://api.relayapp.im` as the default API URL.
36
+
37
+ Example client configuration:
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "relay": {
43
+ "command": "relay-mcp",
44
+ "env": {
45
+ "RELAY_PROFILE": "default"
46
+ }
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ For automation, inject `RELAY_AGENT_TOKEN` from the host's secret manager.
53
+ Do not put the token in MCP config checked into source control.
54
+
55
+ Optional non-secret process flags:
56
+
57
+ ```sh
58
+ relay-mcp --profile staging
59
+ relay-mcp --profile local --api-url http://127.0.0.1:8787
60
+ ```
61
+
62
+ There is deliberately no token flag.
63
+
64
+ ## Tools
65
+
66
+ The server exposes explicit tools rather than a generic HTTP or operation
67
+ proxy:
68
+
69
+ | Capability | Tools |
70
+ | --- | --- |
71
+ | Read | `relay_list_chats`, `relay_get_chat`, `relay_list_messages`, `relay_get_message`, `relay_get_message_thread` |
72
+ | Send | `relay_send_message`, `relay_send_message_to_chat` |
73
+ | Reactions | `relay_react_to_message` |
74
+ | Typing/read state | `relay_start_typing`, `relay_stop_typing`, `relay_mark_chat_read` |
75
+ | Contact Card | `relay_get_contact_card`, `relay_set_contact_card`, `relay_update_contact_card`, `relay_share_contact_card` |
76
+ | Contact request | `relay_create_contact_request` |
77
+
78
+ Message-send tools require a caller-supplied idempotency key. Tool schemas do
79
+ not contain Agent Tokens, raw authorization headers, URLs for arbitrary Relay
80
+ routes, or copied OpenAPI response definitions.
81
+
82
+ ## Errors and secrets
83
+
84
+ Tool failures return MCP error results with sanitized text. Environment and
85
+ locally configured Agent Tokens are redacted from tool errors and stderr.
86
+ Successful SDK objects are returned as both JSON text and structured content.
87
+
88
+ ## Development
89
+
90
+ All Linux execution happens in a fresh Daytona sandbox:
91
+
92
+ ```sh
93
+ npm ci
94
+ npm run validate
95
+ ```
96
+
97
+ Validation includes type checking, unit and negative tests, the pinned SDK
98
+ contract hash, an MCP v2 modern protocol spawn test, MCP Inspector v2
99
+ `tools/list --strict`, package packing, isolated tarball installation, and an
100
+ installed-bin protocol test.
package/dist/auth.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export declare const DEFAULT_API_URL = "https://api.relayapp.im";
2
+ export declare const DEFAULT_PROFILE = "default";
3
+ export interface AuthContext {
4
+ env?: NodeJS.ProcessEnv;
5
+ home?: string;
6
+ profile?: string;
7
+ apiURL?: string;
8
+ }
9
+ export interface ResolvedAgentAuth {
10
+ profile: string;
11
+ apiURL: string;
12
+ token: string;
13
+ source: "environment" | "profile";
14
+ configPath: string;
15
+ }
16
+ export declare const relayConfigPath: (context?: AuthContext) => string;
17
+ export declare const validateApiURL: (input: string) => string;
18
+ export declare const resolveAgentAuth: (context?: AuthContext) => Promise<ResolvedAgentAuth>;
19
+ export declare const collectLocalTokens: (context?: AuthContext) => Promise<string[]>;
20
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,eAAe,YAAY,CAAC;AAazC,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD,eAAO,MAAM,eAAe,GAAI,UAAS,WAAgB,KAAG,MAY3D,CAAC;AAeF,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAuB9C,CAAC;AA8DF,eAAO,MAAM,gBAAgB,GAC3B,UAAS,WAAgB,KACxB,OAAO,CAAC,iBAAiB,CA+B3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAS,WAAgB,KACxB,OAAO,CAAC,MAAM,EAAE,CAalB,CAAC"}
package/dist/auth.js ADDED
@@ -0,0 +1,148 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { isAbsolute, join, resolve } from "node:path";
4
+ export const DEFAULT_API_URL = "https://api.relayapp.im";
5
+ export const DEFAULT_PROFILE = "default";
6
+ const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
7
+ const envFor = (context) => context.env ?? process.env;
8
+ export const relayConfigPath = (context = {}) => {
9
+ const env = envFor(context);
10
+ if (env.RELAY_CONFIG_PATH) {
11
+ if (!isAbsolute(env.RELAY_CONFIG_PATH)) {
12
+ throw new Error("RELAY_CONFIG_PATH must be absolute.");
13
+ }
14
+ return env.RELAY_CONFIG_PATH;
15
+ }
16
+ const root = env.RELAY_CONFIG_DIR
17
+ ?? env.XDG_CONFIG_HOME
18
+ ?? join(context.home ?? homedir(), ".config");
19
+ return resolve(root, "relay", "config.json");
20
+ };
21
+ const profileName = (value) => {
22
+ if (!/^[a-z0-9][a-z0-9_-]{0,63}$/i.test(value)) {
23
+ throw new Error("Relay profile name is invalid.");
24
+ }
25
+ return value;
26
+ };
27
+ const isLoopback = (hostname) => hostname === "localhost"
28
+ || hostname === "127.0.0.1"
29
+ || hostname === "::1"
30
+ || hostname === "[::1]";
31
+ export const validateApiURL = (input) => {
32
+ let url;
33
+ try {
34
+ url = new URL(input);
35
+ }
36
+ catch (cause) {
37
+ throw new Error("Relay API URL must be absolute.", { cause });
38
+ }
39
+ if (url.username
40
+ || url.password
41
+ || url.search
42
+ || url.hash
43
+ || (url.pathname !== "" && url.pathname !== "/")) {
44
+ throw new Error("Relay API URL must be an origin without credentials.");
45
+ }
46
+ if (url.protocol !== "https:"
47
+ && !(url.protocol === "http:" && isLoopback(url.hostname))) {
48
+ throw new Error("Relay API URL must use HTTPS (HTTP is loopback-only).");
49
+ }
50
+ return url.origin;
51
+ };
52
+ const tokenValue = (input) => {
53
+ const token = input.trim();
54
+ if (!token || /[\r\n\0]/.test(token)) {
55
+ throw new Error("Relay Agent Token is empty or malformed.");
56
+ }
57
+ return token;
58
+ };
59
+ const readLocalConfig = async (context) => {
60
+ try {
61
+ const parsed = JSON.parse(await readFile(relayConfigPath(context), "utf8"));
62
+ if (!isRecord(parsed)
63
+ || parsed.version !== 1
64
+ || typeof parsed.current_profile !== "string"
65
+ || !isRecord(parsed.profiles)) {
66
+ throw new Error("Relay config has an unsupported format.");
67
+ }
68
+ const profiles = {};
69
+ for (const [name, raw] of Object.entries(parsed.profiles)) {
70
+ profileName(name);
71
+ if (!isRecord(raw))
72
+ throw new Error(`Relay profile ${name} is invalid.`);
73
+ const apiURL = raw.api_url;
74
+ const token = raw.agent_token;
75
+ if (apiURL !== undefined && typeof apiURL !== "string") {
76
+ throw new Error(`Relay profile ${name} has an invalid API URL.`);
77
+ }
78
+ if (token !== undefined && typeof token !== "string") {
79
+ throw new Error(`Relay profile ${name} has an invalid Agent Token.`);
80
+ }
81
+ profiles[name] = {
82
+ ...(apiURL === undefined ? {} : { api_url: validateApiURL(apiURL) }),
83
+ ...(token === undefined ? {} : { agent_token: tokenValue(token) }),
84
+ };
85
+ }
86
+ return {
87
+ version: 1,
88
+ current_profile: profileName(parsed.current_profile),
89
+ profiles,
90
+ };
91
+ }
92
+ catch (error) {
93
+ if (error instanceof Error
94
+ && "code" in error
95
+ && error.code === "ENOENT") {
96
+ return undefined;
97
+ }
98
+ if (error instanceof SyntaxError) {
99
+ throw new Error("Relay config is not valid JSON.", { cause: error });
100
+ }
101
+ throw error;
102
+ }
103
+ };
104
+ export const resolveAgentAuth = async (context = {}) => {
105
+ const env = envFor(context);
106
+ const config = await readLocalConfig(context);
107
+ const profile = profileName(context.profile
108
+ ?? env.RELAY_PROFILE
109
+ ?? config?.current_profile
110
+ ?? DEFAULT_PROFILE);
111
+ const selected = config?.profiles[profile];
112
+ if (config && !selected)
113
+ throw new Error(`Relay profile ${profile} does not exist.`);
114
+ const apiURL = validateApiURL(context.apiURL
115
+ ?? env.RELAY_API_URL
116
+ ?? selected?.api_url
117
+ ?? DEFAULT_API_URL);
118
+ const environmentToken = env.RELAY_AGENT_TOKEN;
119
+ const token = environmentToken ?? selected?.agent_token;
120
+ if (!token) {
121
+ throw new Error(`No Agent Token for Relay profile ${profile}. Configure @relaymessenger/cli or RELAY_AGENT_TOKEN.`);
122
+ }
123
+ return {
124
+ profile,
125
+ apiURL,
126
+ token: tokenValue(token),
127
+ source: environmentToken === undefined ? "profile" : "environment",
128
+ configPath: relayConfigPath(context),
129
+ };
130
+ };
131
+ export const collectLocalTokens = async (context = {}) => {
132
+ const tokens = [];
133
+ const environmentToken = envFor(context).RELAY_AGENT_TOKEN;
134
+ if (environmentToken)
135
+ tokens.push(environmentToken);
136
+ try {
137
+ const config = await readLocalConfig(context);
138
+ for (const profile of Object.values(config?.profiles ?? {})) {
139
+ if (profile.agent_token)
140
+ tokens.push(profile.agent_token);
141
+ }
142
+ }
143
+ catch {
144
+ // A malformed config must not prevent environment-secret redaction.
145
+ }
146
+ return [...new Set(tokens)];
147
+ };
148
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
3
+ import { collectLocalTokens, validateApiURL } from "./auth.js";
4
+ import { safeErrorMessage } from "./redact.js";
5
+ import { createRelayMcpServer } from "./server.js";
6
+ const usage = `Usage: relay-mcp [options]
7
+
8
+ Local MCP v2 stdio server for Relay.
9
+
10
+ Options:
11
+ --profile <name> Select a local Relay profile
12
+ --api-url <url> Override the Relay API origin (never an Agent Token)
13
+ --version Print package version
14
+ --help Print this help
15
+
16
+ Agent Tokens resolve from RELAY_AGENT_TOKEN or the local Relay profile file.
17
+ Remote HTTP and OAuth transports are not implemented.
18
+ `;
19
+ const parseArgs = (args) => {
20
+ const context = {};
21
+ for (let index = 0; index < args.length; index += 1) {
22
+ const argument = args[index];
23
+ if (argument === "--help" || argument === "-h")
24
+ return "help";
25
+ if (argument === "--version" || argument === "-V")
26
+ return "version";
27
+ if (argument === "--profile") {
28
+ const value = args[++index];
29
+ if (!value)
30
+ throw new Error("--profile requires a value.");
31
+ context.profile = value;
32
+ continue;
33
+ }
34
+ if (argument === "--api-url") {
35
+ const value = args[++index];
36
+ if (!value)
37
+ throw new Error("--api-url requires a value.");
38
+ context.apiURL = validateApiURL(value);
39
+ continue;
40
+ }
41
+ throw new Error(`Unknown option: ${argument}`);
42
+ }
43
+ return context;
44
+ };
45
+ try {
46
+ const parsed = parseArgs(process.argv.slice(2));
47
+ if (parsed === "help") {
48
+ process.stdout.write(usage);
49
+ }
50
+ else if (parsed === "version") {
51
+ process.stdout.write("0.1.0-staging.0\n");
52
+ }
53
+ else {
54
+ serveStdio(() => createRelayMcpServer({ authContext: parsed }), {
55
+ legacy: "serve",
56
+ onerror: async (error) => {
57
+ const secrets = await collectLocalTokens(parsed);
58
+ process.stderr.write(`Relay MCP error: ${safeErrorMessage(error, secrets)}\n`);
59
+ },
60
+ });
61
+ }
62
+ }
63
+ catch (error) {
64
+ const secrets = await collectLocalTokens();
65
+ process.stderr.write(`Relay MCP error: ${safeErrorMessage(error, secrets)}\n`);
66
+ process.exitCode = 1;
67
+ }
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,KAAK,GAAG;;;;;;;;;;;;CAYb,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,IAAc,EAAoC,EAAE;IACrE,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC;QAC9B,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAC9D,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QACpE,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC3D,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;YACxB,SAAS;QACX,CAAC;QACD,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC3D,OAAO,CAAC,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACvC,SAAS;QACX,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,IAAI,CAAC;IACH,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,UAAU,CACR,GAAG,EAAE,CAAC,oBAAoB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EACnD;YACE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;gBACvB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;YACjF,CAAC;SACF,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const redact: (value: string, secrets: readonly string[]) => string;
2
+ export declare const safeErrorMessage: (error: unknown, secrets: readonly string[]) => string;
3
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,GACjB,OAAO,MAAM,EACb,SAAS,SAAS,MAAM,EAAE,KACzB,MAqBF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,OAAO,EACd,SAAS,SAAS,MAAM,EAAE,KACzB,MAGF,CAAC"}
package/dist/redact.js ADDED
@@ -0,0 +1,21 @@
1
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2
+ export const redact = (value, secrets) => {
3
+ let output = value;
4
+ for (const secret of secrets) {
5
+ if (secret.length < 4)
6
+ continue;
7
+ output = output.replace(new RegExp(escapeRegExp(secret), "g"), "[REDACTED]");
8
+ try {
9
+ const encoded = encodeURIComponent(secret);
10
+ if (encoded !== secret) {
11
+ output = output.replace(new RegExp(escapeRegExp(encoded), "g"), "[REDACTED]");
12
+ }
13
+ }
14
+ catch {
15
+ // Raw replacement above remains effective.
16
+ }
17
+ }
18
+ return output;
19
+ };
20
+ export const safeErrorMessage = (error, secrets) => redact(error instanceof Error ? error.message : String(error), secrets);
21
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7C,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,KAAa,EACb,OAA0B,EAClB,EAAE;IACV,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAChC,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EACrC,YAAY,CACb,CAAC;QACF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,IAAI,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,EACtC,YAAY,CACb,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAc,EACd,OAA0B,EAClB,EAAE,CAAC,MAAM,CACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,OAAO,CACR,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
+ import Relay from "@relaymessenger/sdk";
3
+ import type { AuthContext } from "./auth.js";
4
+ export interface ResolvedRelayClient {
5
+ client: Relay;
6
+ secrets?: string[];
7
+ }
8
+ export interface RelayMcpServerOptions {
9
+ authContext?: AuthContext;
10
+ resolveClient?: () => Promise<ResolvedRelayClient>;
11
+ collectSecrets?: () => Promise<string[]>;
12
+ }
13
+ export declare const createRelayMcpServer: (options?: RelayMcpServerOptions) => McpServer;
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuB,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAON,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC1C;AAgGD,eAAO,MAAM,oBAAoB,GAC/B,UAAS,qBAA0B,KAClC,SAgXF,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,331 @@
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
+ import Relay, {} from "@relaymessenger/sdk";
3
+ import { z } from "zod";
4
+ import { collectLocalTokens, resolveAgentAuth } from "./auth.js";
5
+ import { safeErrorMessage } from "./redact.js";
6
+ const uuid = z.uuid();
7
+ const cursor = z.string().min(1).max(512).optional();
8
+ const limit = z.number().int().min(1).max(100).optional();
9
+ const relayHandle = z.string()
10
+ .min(1)
11
+ .max(128)
12
+ .regex(/^[^@\s]+$/, "Omit the leading @ and whitespace.");
13
+ const idempotencyKey = z.string().min(1).max(255);
14
+ const messageText = z.string().min(1).max(32_000);
15
+ const readAnnotations = {
16
+ readOnlyHint: true,
17
+ destructiveHint: false,
18
+ idempotentHint: true,
19
+ openWorldHint: true,
20
+ };
21
+ const writeAnnotations = {
22
+ readOnlyHint: false,
23
+ destructiveHint: false,
24
+ idempotentHint: false,
25
+ openWorldHint: true,
26
+ };
27
+ const idempotentWriteAnnotations = {
28
+ readOnlyHint: false,
29
+ destructiveHint: false,
30
+ idempotentHint: true,
31
+ openWorldHint: true,
32
+ };
33
+ const destructiveAnnotations = {
34
+ readOnlyHint: false,
35
+ destructiveHint: true,
36
+ idempotentHint: false,
37
+ openWorldHint: true,
38
+ };
39
+ const serializableObject = (value) => {
40
+ const normalized = value === undefined ? { ok: true } : value;
41
+ const serialized = JSON.stringify(normalized);
42
+ const parsed = JSON.parse(serialized);
43
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
44
+ return parsed;
45
+ }
46
+ return { result: parsed };
47
+ };
48
+ const success = (value) => {
49
+ const structuredContent = serializableObject(value);
50
+ return {
51
+ content: [{
52
+ type: "text",
53
+ text: JSON.stringify(structuredContent, null, 2),
54
+ }],
55
+ structuredContent,
56
+ };
57
+ };
58
+ const textMessage = (text, stableKey) => ({
59
+ parts: [{ type: "text", value: text }],
60
+ idempotency_key: stableKey,
61
+ });
62
+ const operation = async (options, callback) => {
63
+ let secrets = [];
64
+ try {
65
+ secrets = await options.collectSecrets();
66
+ }
67
+ catch {
68
+ // Continue: a malformed local config must not break a custom resolver.
69
+ }
70
+ try {
71
+ const resolved = await options.resolveClient();
72
+ secrets.push(...(resolved.secrets ?? []));
73
+ return success(await callback(resolved.client));
74
+ }
75
+ catch (error) {
76
+ return {
77
+ content: [{
78
+ type: "text",
79
+ text: `Relay tool failed: ${safeErrorMessage(error, secrets)}`,
80
+ }],
81
+ isError: true,
82
+ };
83
+ }
84
+ };
85
+ export const createRelayMcpServer = (options = {}) => {
86
+ const authContext = options.authContext ?? {};
87
+ const dependencies = {
88
+ resolveClient: options.resolveClient ?? (async () => {
89
+ const auth = await resolveAgentAuth(authContext);
90
+ return {
91
+ client: new Relay({
92
+ apiKey: auth.token,
93
+ baseURL: auth.apiURL,
94
+ }),
95
+ secrets: [auth.token],
96
+ };
97
+ }),
98
+ collectSecrets: options.collectSecrets
99
+ ?? (() => collectLocalTokens(authContext)),
100
+ };
101
+ const server = new McpServer({
102
+ name: "relay",
103
+ version: "0.1.0-staging.0",
104
+ }, {
105
+ capabilities: { tools: {} },
106
+ instructions: "Use explicit Relay tools. Message sends require stable idempotency keys. "
107
+ + "Agent authentication is resolved locally and is never a tool argument.",
108
+ });
109
+ server.registerTool("relay_list_chats", {
110
+ title: "List Relay Chats",
111
+ description: "List Chats visible to the authenticated Relay Agent.",
112
+ inputSchema: z.object({ cursor, limit }),
113
+ annotations: readAnnotations,
114
+ }, async (args) => operation(dependencies, async (client) => {
115
+ const page = await client.chats.listChats({
116
+ ...(args.cursor ? { cursor: args.cursor } : {}),
117
+ ...(args.limit === undefined ? {} : { limit: args.limit }),
118
+ });
119
+ return { chats: page.chats, next_cursor: page.nextCursor };
120
+ }));
121
+ server.registerTool("relay_get_chat", {
122
+ title: "Get Relay Chat",
123
+ description: "Retrieve one Relay Chat by ID.",
124
+ inputSchema: z.object({ chat_id: uuid }),
125
+ annotations: readAnnotations,
126
+ }, async ({ chat_id }) => operation(dependencies, (client) => client.chats.retrieve(chat_id)));
127
+ server.registerTool("relay_list_messages", {
128
+ title: "List Relay Messages",
129
+ description: "List Messages in one Relay Chat.",
130
+ inputSchema: z.object({ chat_id: uuid, cursor, limit }),
131
+ annotations: readAnnotations,
132
+ }, async ({ chat_id, cursor: next, limit: pageSize }) => operation(dependencies, async (client) => {
133
+ const page = await client.chats.messages.list(chat_id, {
134
+ ...(next ? { cursor: next } : {}),
135
+ ...(pageSize === undefined ? {} : { limit: pageSize }),
136
+ });
137
+ return { messages: page.messages, next_cursor: page.nextCursor };
138
+ }));
139
+ server.registerTool("relay_get_message", {
140
+ title: "Get Relay Message",
141
+ description: "Retrieve one Relay Message by ID.",
142
+ inputSchema: z.object({ message_id: uuid }),
143
+ annotations: readAnnotations,
144
+ }, async ({ message_id }) => operation(dependencies, (client) => client.messages.retrieve(message_id)));
145
+ server.registerTool("relay_get_message_thread", {
146
+ title: "Get Relay Message Thread",
147
+ description: "List the thread rooted at one Relay Message.",
148
+ inputSchema: z.object({
149
+ message_id: uuid,
150
+ cursor,
151
+ limit,
152
+ order: z.enum(["asc", "desc"]).optional(),
153
+ }),
154
+ annotations: readAnnotations,
155
+ }, async ({ message_id, cursor: next, limit: pageSize, order }) => operation(dependencies, async (client) => {
156
+ const page = await client.messages.listMessagesThread(message_id, {
157
+ ...(next ? { cursor: next } : {}),
158
+ ...(pageSize === undefined ? {} : { limit: pageSize }),
159
+ ...(order ? { order } : {}),
160
+ });
161
+ return { messages: page.messages, next_cursor: page.nextCursor };
162
+ }));
163
+ server.registerTool("relay_send_message", {
164
+ title: "Send Relay Message",
165
+ description: "Resolve or create a Chat and send a text Message to Relay Handles. "
166
+ + "Reuse the same idempotency key only for the same logical send.",
167
+ inputSchema: z.object({
168
+ recipients: z.array(relayHandle).min(1).max(31),
169
+ text: messageText,
170
+ idempotency_key: idempotencyKey,
171
+ }),
172
+ annotations: idempotentWriteAnnotations,
173
+ }, async ({ recipients, text, idempotency_key }) => operation(dependencies, (client) => {
174
+ const body = {
175
+ to: recipients,
176
+ message: textMessage(text, idempotency_key),
177
+ };
178
+ return client.messages.create(body);
179
+ }));
180
+ server.registerTool("relay_send_message_to_chat", {
181
+ title: "Send Message to Relay Chat",
182
+ description: "Send a text Message to a known Relay Chat. Reuse the idempotency key "
183
+ + "only for the same logical send.",
184
+ inputSchema: z.object({
185
+ chat_id: uuid,
186
+ text: messageText,
187
+ idempotency_key: idempotencyKey,
188
+ }),
189
+ annotations: idempotentWriteAnnotations,
190
+ }, async ({ chat_id, text, idempotency_key }) => operation(dependencies, (client) => {
191
+ const body = {
192
+ message: textMessage(text, idempotency_key),
193
+ };
194
+ return client.chats.messages.send(chat_id, body);
195
+ }));
196
+ const reactionInput = z.object({
197
+ message_id: uuid,
198
+ operation: z.enum(["add", "remove"]),
199
+ type: z.enum([
200
+ "love",
201
+ "like",
202
+ "dislike",
203
+ "laugh",
204
+ "emphasize",
205
+ "question",
206
+ "custom",
207
+ ]),
208
+ custom_emoji: z.string().min(1).max(32).optional(),
209
+ part_index: z.number().int().min(0).optional(),
210
+ }).superRefine((value, context) => {
211
+ if (value.type === "custom" && !value.custom_emoji) {
212
+ context.addIssue({
213
+ code: "custom",
214
+ message: "custom_emoji is required when type is custom.",
215
+ path: ["custom_emoji"],
216
+ });
217
+ }
218
+ if (value.type !== "custom" && value.custom_emoji) {
219
+ context.addIssue({
220
+ code: "custom",
221
+ message: "custom_emoji is allowed only when type is custom.",
222
+ path: ["custom_emoji"],
223
+ });
224
+ }
225
+ });
226
+ server.registerTool("relay_react_to_message", {
227
+ title: "React to Relay Message",
228
+ description: "Add or remove a reaction on a Relay Message part.",
229
+ inputSchema: reactionInput,
230
+ annotations: destructiveAnnotations,
231
+ }, async ({ message_id, operation: reactionOperation, type, custom_emoji, part_index }) => operation(dependencies, (client) => {
232
+ const body = {
233
+ operation: reactionOperation,
234
+ type,
235
+ ...(custom_emoji ? { custom_emoji } : {}),
236
+ ...(part_index === undefined ? {} : { part_index }),
237
+ };
238
+ return client.messages.addReaction(message_id, body);
239
+ }));
240
+ server.registerTool("relay_start_typing", {
241
+ title: "Start Relay Typing",
242
+ description: "Start or refresh the Agent typing indicator in a Chat.",
243
+ inputSchema: z.object({ chat_id: uuid }),
244
+ annotations: idempotentWriteAnnotations,
245
+ }, async ({ chat_id }) => operation(dependencies, async (client) => {
246
+ await client.chats.startTyping(chat_id);
247
+ return { ok: true };
248
+ }));
249
+ server.registerTool("relay_stop_typing", {
250
+ title: "Stop Relay Typing",
251
+ description: "Stop the Agent typing indicator in a Chat.",
252
+ inputSchema: z.object({ chat_id: uuid }),
253
+ annotations: idempotentWriteAnnotations,
254
+ }, async ({ chat_id }) => operation(dependencies, async (client) => {
255
+ await client.chats.stopTyping(chat_id);
256
+ return { ok: true };
257
+ }));
258
+ server.registerTool("relay_mark_chat_read", {
259
+ title: "Mark Relay Chat Read",
260
+ description: "Mark the visible Relay Chat as read by the Agent.",
261
+ inputSchema: z.object({ chat_id: uuid }),
262
+ annotations: idempotentWriteAnnotations,
263
+ }, async ({ chat_id }) => operation(dependencies, async (client) => {
264
+ await client.chats.markAsRead(chat_id);
265
+ return { ok: true };
266
+ }));
267
+ server.registerTool("relay_get_contact_card", {
268
+ title: "Get Relay Contact Card",
269
+ description: "Retrieve the authenticated Agent's Relay Contact Card.",
270
+ inputSchema: z.object({ handle: relayHandle.optional() }),
271
+ annotations: readAnnotations,
272
+ }, async ({ handle }) => operation(dependencies, (client) => client.contactCard.retrieve(handle ? { handle } : {})));
273
+ server.registerTool("relay_set_contact_card", {
274
+ title: "Set Relay Contact Card",
275
+ description: "Create or replace the authenticated Agent's Contact Card.",
276
+ inputSchema: z.object({
277
+ handle: relayHandle,
278
+ first_name: z.string().min(1).max(128),
279
+ last_name: z.string().max(128).optional(),
280
+ image_url: z.url().optional(),
281
+ }),
282
+ annotations: writeAnnotations,
283
+ }, async ({ handle, first_name, last_name, image_url }) => operation(dependencies, (client) => {
284
+ const body = {
285
+ handle,
286
+ first_name,
287
+ ...(last_name === undefined ? {} : { last_name }),
288
+ ...(image_url === undefined ? {} : { image_url }),
289
+ };
290
+ return client.contactCard.create(body);
291
+ }));
292
+ const updateContactCardInput = z.object({
293
+ handle: relayHandle,
294
+ first_name: z.string().min(1).max(128).optional(),
295
+ last_name: z.string().max(128).nullable().optional(),
296
+ image_url: z.url().nullable().optional(),
297
+ }).refine((value) => value.first_name !== undefined
298
+ || value.last_name !== undefined
299
+ || value.image_url !== undefined, { message: "At least one Contact Card field must be updated." });
300
+ server.registerTool("relay_update_contact_card", {
301
+ title: "Update Relay Contact Card",
302
+ description: "Update selected fields on the authenticated Agent's Contact Card.",
303
+ inputSchema: updateContactCardInput,
304
+ annotations: writeAnnotations,
305
+ }, async ({ handle, first_name, last_name, image_url }) => operation(dependencies, (client) => {
306
+ const body = {
307
+ handle,
308
+ ...(first_name === undefined ? {} : { first_name }),
309
+ ...(last_name === undefined ? {} : { last_name }),
310
+ ...(image_url === undefined ? {} : { image_url }),
311
+ };
312
+ return client.contactCard.update(body);
313
+ }));
314
+ server.registerTool("relay_share_contact_card", {
315
+ title: "Share Relay Contact Card",
316
+ description: "Share the authenticated Agent's configured Contact Card into a Chat.",
317
+ inputSchema: z.object({ chat_id: uuid }),
318
+ annotations: writeAnnotations,
319
+ }, async ({ chat_id }) => operation(dependencies, async (client) => {
320
+ await client.chats.shareContactCard(chat_id);
321
+ return { ok: true };
322
+ }));
323
+ server.registerTool("relay_create_contact_request", {
324
+ title: "Create Relay Contact Request",
325
+ description: "Ask a Relay user to add the authenticated premium-handle Agent.",
326
+ inputSchema: z.object({ handle: relayHandle }),
327
+ annotations: writeAnnotations,
328
+ }, async ({ handle }) => operation(dependencies, (client) => client.contactRequests.create({ handle })));
329
+ return server;
330
+ };
331
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@relaymessenger/mcp",
3
+ "version": "0.1.0-staging.0",
4
+ "description": "Local MCP v2 stdio server for current Relay messaging tools.",
5
+ "type": "module",
6
+ "bin": {
7
+ "relay-mcp": "./dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/server.d.ts",
12
+ "import": "./dist/server.js",
13
+ "default": "./dist/server.js"
14
+ },
15
+ "./auth": {
16
+ "types": "./dist/auth.d.ts",
17
+ "import": "./dist/auth.js",
18
+ "default": "./dist/auth.js"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "files": [
23
+ "dist/",
24
+ "LICENSE",
25
+ "README.md"
26
+ ],
27
+ "scripts": {
28
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
29
+ "check": "tsc -p tsconfig.json --noEmit",
30
+ "build": "tsc -p tsconfig.json",
31
+ "test": "vitest run",
32
+ "contract:check": "node scripts/check-contract.mjs",
33
+ "boundaries:check": "node scripts/check-boundaries.mjs",
34
+ "protocol:test": "node scripts/protocol-smoke.mjs",
35
+ "inspector:test": "node scripts/inspector-smoke.mjs",
36
+ "pack:smoke": "node scripts/tarball-smoke.mjs",
37
+ "validate": "npm run clean && npm run check && npm run build && npm test && npm run contract:check && npm run boundaries:check && npm run protocol:test && npm run inspector:test && npm run pack:smoke",
38
+ "prepack": "npm run validate"
39
+ },
40
+ "engines": {
41
+ "node": ">=22.22.3"
42
+ },
43
+ "license": "MIT",
44
+ "dependencies": {
45
+ "@modelcontextprotocol/server": "2.0.0",
46
+ "@relaymessenger/sdk": "0.3.0-staging.4",
47
+ "zod": "^4.5.4"
48
+ },
49
+ "devDependencies": {
50
+ "@modelcontextprotocol/client": "2.0.0",
51
+ "@modelcontextprotocol/inspector": "2.4.0",
52
+ "@types/node": "^22.18.0",
53
+ "typescript": "^5.9.3",
54
+ "vitest": "^4.0.0"
55
+ },
56
+ "publishConfig": {
57
+ "access": "public",
58
+ "registry": "https://registry.npmjs.org/",
59
+ "tag": "staging",
60
+ "provenance": true
61
+ },
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "git+https://github.com/RelayMessenger/Relay-MCP.git"
65
+ },
66
+ "homepage": "https://docs.relayapp.im"
67
+ }