@relaycast/mcp 0.2.2 → 0.2.4

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.
@@ -1,5 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  const DEFAULT_BASE_URL = 'https://api.relaycast.dev';
3
+ /** Passthrough object schema for dynamic API responses. */
4
+ const jsonResult = z.object({}).passthrough();
3
5
  function normalizeBaseUrl(baseUrl) {
4
6
  return (baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
5
7
  }
@@ -26,10 +28,13 @@ function requireWorkspaceKey(session) {
26
28
  export function registerRegistrationTools(server, getRelay, getSession, setSession, baseUrl) {
27
29
  // Tool 1: create_workspace
28
30
  server.registerTool('create_workspace', {
29
- description: 'Create a new workspace and store its workspace key in this MCP session for subsequent registration calls.',
31
+ title: 'Create Workspace',
32
+ description: 'Create a new Relaycast workspace and automatically store its API key in this MCP session. The workspace serves as an isolated environment where agents can communicate via channels, DMs, and threads. After creation, the workspace key is ready for immediate use with register and other workspace-level tools.',
30
33
  inputSchema: {
31
- name: z.string().describe('Workspace name'),
34
+ name: z.string().describe('Human-readable workspace name, used to identify the workspace in dashboards and logs'),
32
35
  },
36
+ outputSchema: jsonResult,
37
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
33
38
  }, async ({ name }) => {
34
39
  const workspace = await createWorkspace(name, baseUrl);
35
40
  const workspaceKey = workspace.api_key ?? workspace.apiKey;
@@ -40,14 +45,20 @@ export function registerRegistrationTools(server, getRelay, getSession, setSessi
40
45
  setSession({ workspaceKey, agentToken: null, agentName: null });
41
46
  return {
42
47
  content: [{ type: 'text', text: JSON.stringify(workspace, null, 2) }],
48
+ structuredContent: workspace,
43
49
  };
44
50
  });
45
51
  // Tool 2: set_workspace_key
46
52
  server.registerTool('set_workspace_key', {
47
- description: 'Set the workspace key (rk_live_...) for this MCP session. This enables register and workspace-level tools.',
53
+ title: 'Set Workspace Key',
54
+ description: 'Authenticate this MCP session by providing an existing workspace API key (rk_live_...). This enables all workspace-level tools including agent registration, channel management, and messaging. If the key belongs to a different workspace than the current session, the previous agent identity is cleared and you must re-register.',
48
55
  inputSchema: {
49
- api_key: z.string().describe('Workspace API key (rk_live_...)'),
56
+ api_key: z.string().describe('Workspace API key starting with "rk_live_", obtained from workspace creation or the Relaycast dashboard'),
50
57
  },
58
+ outputSchema: {
59
+ message: z.string().describe('Confirmation message indicating whether the workspace key was set successfully'),
60
+ },
61
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
51
62
  }, async ({ api_key }) => {
52
63
  if (!api_key.startsWith('rk_live_')) {
53
64
  throw new Error('Workspace key must start with "rk_live_"');
@@ -61,25 +72,25 @@ export function registerRegistrationTools(server, getRelay, getSession, setSessi
61
72
  else {
62
73
  setSession({ workspaceKey: api_key });
63
74
  }
75
+ const message = switchingWorkspace
76
+ ? 'Workspace key set. Previous agent session was cleared; call "register" again.'
77
+ : 'Workspace key set.';
64
78
  return {
65
- content: [
66
- {
67
- type: 'text',
68
- text: switchingWorkspace
69
- ? 'Workspace key set. Previous agent session was cleared; call "register" again.'
70
- : 'Workspace key set.',
71
- },
72
- ],
79
+ content: [{ type: 'text', text: message }],
80
+ structuredContent: { message },
73
81
  };
74
82
  });
75
83
  // Tool 3: register
76
84
  server.registerTool('register', {
77
- description: 'Register this agent in the current workspace and obtain an agent token for subsequent operations.',
85
+ title: 'Register Agent',
86
+ description: 'Register an agent identity in the current workspace and obtain an agent token for all subsequent operations. The agent name must be unique within the workspace. Once registered, the agent can send messages, join channels, react to messages, and perform all other agent-level actions. Re-registering with the same name returns the existing token.',
78
87
  inputSchema: {
79
- name: z.string().describe('Unique agent name'),
80
- type: z.enum(['agent', 'human']).optional().describe('Agent type'),
81
- persona: z.string().optional().describe('Agent persona description'),
88
+ name: z.string().describe('Unique agent name within the workspace, used as the display name in messages and mentions'),
89
+ type: z.enum(['agent', 'human']).optional().describe('Whether this identity represents an AI agent or a human user'),
90
+ persona: z.string().optional().describe('Free-text persona description that other agents can read to understand this agent\'s role and capabilities'),
82
91
  },
92
+ outputSchema: jsonResult,
93
+ annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
83
94
  }, async ({ name, type, persona }) => {
84
95
  requireWorkspaceKey(getSession());
85
96
  const relay = getRelay();
@@ -88,23 +99,30 @@ export function registerRegistrationTools(server, getRelay, getSession, setSessi
88
99
  setSession({ agentToken: result.token, agentName: name });
89
100
  return {
90
101
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
102
+ structuredContent: result,
91
103
  };
92
104
  });
93
105
  // Tool 4: list_agents
94
106
  server.registerTool('list_agents', {
95
- description: 'List all agents registered in the workspace.',
107
+ title: 'List Agents',
108
+ description: 'Retrieve all agents registered in the current workspace. Returns each agent\'s name, type, persona, and online/offline status. Use the optional status filter to find only agents that are currently connected or disconnected.',
96
109
  inputSchema: {
97
110
  status: z
98
111
  .enum(['online', 'offline'])
99
112
  .optional()
100
- .describe('Filter by agent status'),
113
+ .describe('Filter agents by connection status: "online" for currently connected agents, "offline" for disconnected ones'),
114
+ },
115
+ outputSchema: {
116
+ agents: z.array(z.object({}).passthrough()).describe('Array of registered agent objects with name, type, persona, and status'),
101
117
  },
118
+ annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: true },
102
119
  }, async ({ status }) => {
103
120
  requireWorkspaceKey(getSession());
104
121
  const relay = getRelay();
105
122
  const agents = await relay.agents.list(status ? { status } : undefined);
106
123
  return {
107
124
  content: [{ type: 'text', text: JSON.stringify(agents, null, 2) }],
125
+ structuredContent: { agents: agents },
108
126
  };
109
127
  });
110
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/tools/registration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/tools/registration.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,21 @@ import { type McpServerOptions } from './server.js';
4
4
  * Reads from stdin, writes to stdout.
5
5
  */
6
6
  export declare function startStdio(options: McpServerOptions): Promise<void>;
7
+ /**
8
+ * Lifecycle callbacks for session events, used for external session
9
+ * registries (e.g. Redis) to support multi-machine deployments.
10
+ */
11
+ export interface SessionLifecycle {
12
+ onCreated?: (sessionId: string) => void;
13
+ onClosed?: (sessionId: string) => void;
14
+ }
7
15
  /**
8
16
  * Create Express middleware for HTTP+SSE transport (multi-agent).
9
17
  * Each connecting client gets its own session with isolated state and telemetry.
10
18
  */
11
- export declare function createHttpHandler(baseOptions: McpServerOptions): {
19
+ export declare function createHttpHandler(baseOptions: McpServerOptions, lifecycle?: SessionLifecycle): {
20
+ /** Check whether a session ID is owned by this process. */
21
+ hasSession: (sessionId: string) => boolean;
12
22
  handleRequest: (req: import("node:http").IncomingMessage, res: import("node:http").ServerResponse) => Promise<void>;
13
23
  };
14
24
  //# sourceMappingURL=transports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transports.d.ts","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqC,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIvF;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzE;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,gBAAgB;yBAGpD,OAAO,WAAW,EAAE,eAAe,OACnC,OAAO,WAAW,EAAE,cAAc;EA4C5C"}
1
+ {"version":3,"file":"transports.d.ts","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqC,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIvF;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzE;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,gBAAgB,EAAE,SAAS,CAAC,EAAE,gBAAgB;IAEzF,2DAA2D;4BACnC,MAAM;yBAGvB,OAAO,WAAW,EAAE,eAAe,OACnC,OAAO,WAAW,EAAE,cAAc;EAgD5C"}
@@ -21,8 +21,10 @@ const sessions = new Map();
21
21
  * Create Express middleware for HTTP+SSE transport (multi-agent).
22
22
  * Each connecting client gets its own session with isolated state and telemetry.
23
23
  */
24
- export function createHttpHandler(baseOptions) {
24
+ export function createHttpHandler(baseOptions, lifecycle) {
25
25
  return {
26
+ /** Check whether a session ID is owned by this process. */
27
+ hasSession: (sessionId) => sessions.has(sessionId),
26
28
  handleRequest: async (req, res) => {
27
29
  // Check for existing session
28
30
  const sessionId = req.headers['mcp-session-id'];
@@ -44,18 +46,22 @@ export function createHttpHandler(baseOptions) {
44
46
  transport.onclose = () => {
45
47
  if (transport.sessionId) {
46
48
  sessions.delete(transport.sessionId);
49
+ lifecycle?.onClosed?.(transport.sessionId);
47
50
  }
48
51
  };
49
52
  await mcpServer.connect(transport);
50
- if (transport.sessionId) {
53
+ // handleRequest must run first — the session ID is generated during
54
+ // the initialize handshake, not during connect().
55
+ await transport.handleRequest(req, res);
56
+ if (transport.sessionId && !sessions.has(transport.sessionId)) {
51
57
  sessions.set(transport.sessionId, { transport });
58
+ lifecycle?.onCreated?.(transport.sessionId);
52
59
  telemetry.capture('relaycast_mcp_http_session_started', {
53
60
  source_surface: 'mcp',
54
61
  transport: 'http',
55
62
  mcp_transport_session_id: transport.sessionId,
56
63
  });
57
64
  }
58
- await transport.handleRequest(req, res);
59
65
  },
60
66
  };
61
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transports.js","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAyB,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAyB;IACxD,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,GAAG,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwD,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAA6B;IAC7D,OAAO;QACL,aAAa,EAAE,KAAK,EAClB,GAAwC,EACxC,GAAuC,EACvC,EAAE;YACF,6BAA6B;YAC7B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;YAEtE,IAAI,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;gBACzC,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YAED,gEAAgE;YAChE,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;YAElD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;gBAClD,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;aACvC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,oBAAoB,CAAC;gBACrC,GAAG,WAAW;gBACd,kBAAkB,EAAE,MAAM;gBAC1B,SAAS;aACV,CAAC,CAAC;YAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;oBACxB,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAEnC,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBACxB,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBACjD,SAAS,CAAC,OAAO,CAAC,oCAAoC,EAAE;oBACtD,cAAc,EAAE,KAAK;oBACrB,SAAS,EAAE,MAAM;oBACjB,wBAAwB,EAAE,SAAS,CAAC,SAAS;iBAC9C,CAAC,CAAC;YACL,CAAC;YAED,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"transports.js","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAyB,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAyB;IACxD,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,GAAG,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAWD;;;GAGG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwD,CAAC;AAEjF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAA6B,EAAE,SAA4B;IAC3F,OAAO;QACL,2DAA2D;QAC3D,UAAU,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;QAE1D,aAAa,EAAE,KAAK,EAClB,GAAwC,EACxC,GAAuC,EACvC,EAAE;YACF,6BAA6B;YAC7B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;YAEtE,IAAI,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;gBACzC,MAAM,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YAED,gEAAgE;YAChE,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;YAElD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;gBAClD,kBAAkB,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;aACvC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,oBAAoB,CAAC;gBACrC,GAAG,WAAW;gBACd,kBAAkB,EAAE,MAAM;gBAC1B,SAAS;aACV,CAAC,CAAC;YAEH,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;oBACxB,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;oBACrC,SAAS,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAEnC,oEAAoE;YACpE,kDAAkD;YAClD,MAAM,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAExC,IAAI,SAAS,CAAC,SAAS,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9D,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBACjD,SAAS,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBAC5C,SAAS,CAAC,OAAO,CAAC,oCAAoC,EAAE;oBACtD,cAAc,EAAE,KAAK;oBACrB,SAAS,EAAE,MAAM;oBACjB,wBAAwB,EAAE,SAAS,CAAC,SAAS;iBAC9C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface SessionState {
6
6
  agentName: string | null;
7
7
  wsBridge: WsBridge | null;
8
8
  subscriptions: SubscriptionManager | null;
9
+ wsInitAttempted: boolean;
9
10
  }
10
11
  export declare function createInitialSession(workspaceKey?: string | null): SessionState;
11
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,YAAY,CAErF"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAExE,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,YAAY,CASrF"}
package/dist/types.js CHANGED
@@ -1,4 +1,11 @@
1
1
  export function createInitialSession(workspaceKey = null) {
2
- return { workspaceKey, agentToken: null, agentName: null, wsBridge: null, subscriptions: null };
2
+ return {
3
+ workspaceKey,
4
+ agentToken: null,
5
+ agentName: null,
6
+ wsBridge: null,
7
+ subscriptions: null,
8
+ wsInitAttempted: false,
9
+ };
3
10
  }
4
11
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,oBAAoB,CAAC,eAA8B,IAAI;IACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAClG,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,oBAAoB,CAAC,eAA8B,IAAI;IACrE,OAAO;QACL,YAAY;QACZ,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,IAAI;QACd,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,KAAK;KACvB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relaycast/mcp",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,8 +13,8 @@
13
13
  "lint": "eslint src/"
14
14
  },
15
15
  "dependencies": {
16
- "@relaycast/sdk": "0.2.2",
17
- "@relaycast/types": "0.2.2",
16
+ "@relaycast/sdk": "0.2.4",
17
+ "@relaycast/types": "0.2.4",
18
18
  "@modelcontextprotocol/sdk": "^1.26.0",
19
19
  "express": "^5.2.1",
20
20
  "zod": "^4.3.6"