@relayrail/server 0.1.6 → 0.1.8

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/cli.js CHANGED
@@ -149,6 +149,17 @@ function getApiKeyPrefix(apiKey) {
149
149
  }
150
150
  return apiKey.substring(0, API_KEY_PREFIX.length + 7);
151
151
  }
152
+ function getApiKeyPrefixes(apiKey) {
153
+ if (!apiKey.startsWith(API_KEY_PREFIX)) {
154
+ return [];
155
+ }
156
+ return [
157
+ apiKey.substring(0, API_KEY_PREFIX.length + 7),
158
+ // 10 chars (current)
159
+ apiKey.substring(0, API_KEY_PREFIX.length + 8)
160
+ // 11 chars (legacy)
161
+ ];
162
+ }
152
163
  async function authenticateApiKey(supabase, apiKey) {
153
164
  if (!apiKey || !apiKey.startsWith(API_KEY_PREFIX)) {
154
165
  return {
@@ -173,11 +184,23 @@ async function authenticateApiKey(supabase, apiKey) {
173
184
  }
174
185
  };
175
186
  }
176
- const prefix = getApiKeyPrefix(apiKey);
187
+ const prefixes = getApiKeyPrefixes(apiKey);
177
188
  const hash = hashApiKey(apiKey);
178
- const agentQuery = supabase.from("agents").select("*").eq("api_key_prefix", prefix);
179
- const agentResult = await agentQuery;
180
- if (agentResult.error || !agentResult.data || agentResult.data.length === 0) {
189
+ let agent = null;
190
+ let anyPrefixFound = false;
191
+ for (const prefix of prefixes) {
192
+ const agentQuery = supabase.from("agents").select("*").eq("api_key_prefix", prefix);
193
+ const agentResult = await agentQuery;
194
+ if (agentResult.data && agentResult.data.length > 0) {
195
+ anyPrefixFound = true;
196
+ const matchingAgent = agentResult.data.find((a) => a.api_key_hash === hash);
197
+ if (matchingAgent) {
198
+ agent = matchingAgent;
199
+ break;
200
+ }
201
+ }
202
+ }
203
+ if (!anyPrefixFound) {
181
204
  return {
182
205
  success: false,
183
206
  error: "API key not found",
@@ -188,7 +211,6 @@ async function authenticateApiKey(supabase, apiKey) {
188
211
  }
189
212
  };
190
213
  }
191
- const agent = agentResult.data.find((a) => a.api_key_hash === hash);
192
214
  if (!agent) {
193
215
  return {
194
216
  success: false,
@@ -1576,16 +1598,22 @@ function createProxyRouter(config) {
1576
1598
  var VERSION = "0.1.0";
1577
1599
  var RelayRailServer = class {
1578
1600
  server;
1579
- supabase;
1601
+ supabase = null;
1580
1602
  config;
1581
1603
  context = null;
1582
1604
  router = null;
1583
1605
  constructor(config) {
1584
1606
  this.config = config;
1585
- this.supabase = createServiceClient(config.supabaseUrl, config.supabaseServiceRoleKey);
1607
+ const hasSupabaseCredentials = config.supabaseServiceRoleKey && config.supabaseServiceRoleKey.length > 0;
1608
+ if (hasSupabaseCredentials) {
1609
+ this.supabase = createServiceClient(config.supabaseUrl, config.supabaseServiceRoleKey);
1610
+ }
1586
1611
  const hasEmail = !!config.resendApiKey;
1587
1612
  const hasSms = !!(config.telnyxApiKey && config.telnyxPhoneNumber);
1588
1613
  if (hasEmail || hasSms) {
1614
+ if (!this.supabase) {
1615
+ throw new Error("Supabase credentials required when using local email/SMS configuration");
1616
+ }
1589
1617
  this.router = createRouter(
1590
1618
  {
1591
1619
  baseUrl: config.baseUrl,
@@ -1605,7 +1633,6 @@ var RelayRailServer = class {
1605
1633
  this.supabase
1606
1634
  );
1607
1635
  } else if (config.apiKey) {
1608
- console.log("[RelayRail] Using proxy router for message delivery");
1609
1636
  this.router = createProxyRouter({
1610
1637
  apiUrl: config.baseUrl,
1611
1638
  apiKey: config.apiKey
@@ -1617,6 +1644,26 @@ var RelayRailServer = class {
1617
1644
  });
1618
1645
  this.registerTools();
1619
1646
  }
1647
+ /**
1648
+ * Check if we're in proxy mode (no direct Supabase access)
1649
+ */
1650
+ isProxyMode() {
1651
+ return !this.supabase && !!this.config.apiKey;
1652
+ }
1653
+ /**
1654
+ * Make a proxy API call
1655
+ */
1656
+ async proxyApiCall(endpoint, body) {
1657
+ const response = await fetch(`${this.config.baseUrl}/api/mcp/${endpoint}`, {
1658
+ method: "POST",
1659
+ headers: {
1660
+ "Content-Type": "application/json",
1661
+ "Authorization": `Bearer ${this.config.apiKey}`
1662
+ },
1663
+ body: JSON.stringify(body)
1664
+ });
1665
+ return response.json();
1666
+ }
1620
1667
  /**
1621
1668
  * Register all MCP tools
1622
1669
  */
@@ -1638,6 +1685,12 @@ var RelayRailServer = class {
1638
1685
  };
1639
1686
  }
1640
1687
  try {
1688
+ if (this.isProxyMode()) {
1689
+ const result2 = await this.proxyApiCall("request-approval", params);
1690
+ return {
1691
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1692
+ };
1693
+ }
1641
1694
  const result = await requestApproval(
1642
1695
  params,
1643
1696
  {
@@ -1681,6 +1734,12 @@ var RelayRailServer = class {
1681
1734
  };
1682
1735
  }
1683
1736
  try {
1737
+ if (this.isProxyMode()) {
1738
+ const result2 = await this.proxyApiCall("send-notification", params);
1739
+ return {
1740
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1741
+ };
1742
+ }
1684
1743
  const result = await sendNotification(
1685
1744
  params,
1686
1745
  {
@@ -1722,6 +1781,12 @@ var RelayRailServer = class {
1722
1781
  };
1723
1782
  }
1724
1783
  try {
1784
+ if (this.isProxyMode()) {
1785
+ const result2 = await this.proxyApiCall("await-response", params);
1786
+ return {
1787
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1788
+ };
1789
+ }
1725
1790
  const result = await awaitResponse(
1726
1791
  params,
1727
1792
  {
@@ -1888,7 +1953,7 @@ var RelayRailServer = class {
1888
1953
  return this.server;
1889
1954
  }
1890
1955
  /**
1891
- * Get the Supabase client
1956
+ * Get the Supabase client (may be null in proxy mode)
1892
1957
  */
1893
1958
  getSupabase() {
1894
1959
  return this.supabase;
package/dist/index.d.ts CHANGED
@@ -239,6 +239,14 @@ declare class RelayRailServer {
239
239
  private context;
240
240
  private router;
241
241
  constructor(config: ServerConfig);
242
+ /**
243
+ * Check if we're in proxy mode (no direct Supabase access)
244
+ */
245
+ private isProxyMode;
246
+ /**
247
+ * Make a proxy API call
248
+ */
249
+ private proxyApiCall;
242
250
  /**
243
251
  * Register all MCP tools
244
252
  */
@@ -260,9 +268,9 @@ declare class RelayRailServer {
260
268
  */
261
269
  getMcpServer(): McpServer;
262
270
  /**
263
- * Get the Supabase client
271
+ * Get the Supabase client (may be null in proxy mode)
264
272
  */
265
- getSupabase(): TypedSupabaseClient;
273
+ getSupabase(): TypedSupabaseClient | null;
266
274
  /**
267
275
  * Get the server configuration
268
276
  */
@@ -288,6 +296,7 @@ declare function createServer(config: ServerConfig): RelayRailServer;
288
296
  declare function hashApiKey(apiKey: string): string;
289
297
  /**
290
298
  * Extract the prefix from an API key for lookup
299
+ * Returns the current 10-char prefix format (rr_ + 7 chars)
291
300
  */
292
301
  declare function getApiKeyPrefix(apiKey: string): string;
293
302
  /**
package/dist/index.js CHANGED
@@ -147,6 +147,17 @@ function getApiKeyPrefix(apiKey) {
147
147
  }
148
148
  return apiKey.substring(0, API_KEY_PREFIX.length + 7);
149
149
  }
150
+ function getApiKeyPrefixes(apiKey) {
151
+ if (!apiKey.startsWith(API_KEY_PREFIX)) {
152
+ return [];
153
+ }
154
+ return [
155
+ apiKey.substring(0, API_KEY_PREFIX.length + 7),
156
+ // 10 chars (current)
157
+ apiKey.substring(0, API_KEY_PREFIX.length + 8)
158
+ // 11 chars (legacy)
159
+ ];
160
+ }
150
161
  async function authenticateApiKey(supabase, apiKey) {
151
162
  if (!apiKey || !apiKey.startsWith(API_KEY_PREFIX)) {
152
163
  return {
@@ -171,11 +182,23 @@ async function authenticateApiKey(supabase, apiKey) {
171
182
  }
172
183
  };
173
184
  }
174
- const prefix = getApiKeyPrefix(apiKey);
185
+ const prefixes = getApiKeyPrefixes(apiKey);
175
186
  const hash = hashApiKey(apiKey);
176
- const agentQuery = supabase.from("agents").select("*").eq("api_key_prefix", prefix);
177
- const agentResult = await agentQuery;
178
- if (agentResult.error || !agentResult.data || agentResult.data.length === 0) {
187
+ let agent = null;
188
+ let anyPrefixFound = false;
189
+ for (const prefix of prefixes) {
190
+ const agentQuery = supabase.from("agents").select("*").eq("api_key_prefix", prefix);
191
+ const agentResult = await agentQuery;
192
+ if (agentResult.data && agentResult.data.length > 0) {
193
+ anyPrefixFound = true;
194
+ const matchingAgent = agentResult.data.find((a) => a.api_key_hash === hash);
195
+ if (matchingAgent) {
196
+ agent = matchingAgent;
197
+ break;
198
+ }
199
+ }
200
+ }
201
+ if (!anyPrefixFound) {
179
202
  return {
180
203
  success: false,
181
204
  error: "API key not found",
@@ -186,7 +209,6 @@ async function authenticateApiKey(supabase, apiKey) {
186
209
  }
187
210
  };
188
211
  }
189
- const agent = agentResult.data.find((a) => a.api_key_hash === hash);
190
212
  if (!agent) {
191
213
  return {
192
214
  success: false,
@@ -1574,16 +1596,22 @@ function createProxyRouter(config) {
1574
1596
  var VERSION = "0.1.0";
1575
1597
  var RelayRailServer = class {
1576
1598
  server;
1577
- supabase;
1599
+ supabase = null;
1578
1600
  config;
1579
1601
  context = null;
1580
1602
  router = null;
1581
1603
  constructor(config) {
1582
1604
  this.config = config;
1583
- this.supabase = createServiceClient(config.supabaseUrl, config.supabaseServiceRoleKey);
1605
+ const hasSupabaseCredentials = config.supabaseServiceRoleKey && config.supabaseServiceRoleKey.length > 0;
1606
+ if (hasSupabaseCredentials) {
1607
+ this.supabase = createServiceClient(config.supabaseUrl, config.supabaseServiceRoleKey);
1608
+ }
1584
1609
  const hasEmail = !!config.resendApiKey;
1585
1610
  const hasSms = !!(config.telnyxApiKey && config.telnyxPhoneNumber);
1586
1611
  if (hasEmail || hasSms) {
1612
+ if (!this.supabase) {
1613
+ throw new Error("Supabase credentials required when using local email/SMS configuration");
1614
+ }
1587
1615
  this.router = createRouter(
1588
1616
  {
1589
1617
  baseUrl: config.baseUrl,
@@ -1603,7 +1631,6 @@ var RelayRailServer = class {
1603
1631
  this.supabase
1604
1632
  );
1605
1633
  } else if (config.apiKey) {
1606
- console.log("[RelayRail] Using proxy router for message delivery");
1607
1634
  this.router = createProxyRouter({
1608
1635
  apiUrl: config.baseUrl,
1609
1636
  apiKey: config.apiKey
@@ -1615,6 +1642,26 @@ var RelayRailServer = class {
1615
1642
  });
1616
1643
  this.registerTools();
1617
1644
  }
1645
+ /**
1646
+ * Check if we're in proxy mode (no direct Supabase access)
1647
+ */
1648
+ isProxyMode() {
1649
+ return !this.supabase && !!this.config.apiKey;
1650
+ }
1651
+ /**
1652
+ * Make a proxy API call
1653
+ */
1654
+ async proxyApiCall(endpoint, body) {
1655
+ const response = await fetch(`${this.config.baseUrl}/api/mcp/${endpoint}`, {
1656
+ method: "POST",
1657
+ headers: {
1658
+ "Content-Type": "application/json",
1659
+ "Authorization": `Bearer ${this.config.apiKey}`
1660
+ },
1661
+ body: JSON.stringify(body)
1662
+ });
1663
+ return response.json();
1664
+ }
1618
1665
  /**
1619
1666
  * Register all MCP tools
1620
1667
  */
@@ -1636,6 +1683,12 @@ var RelayRailServer = class {
1636
1683
  };
1637
1684
  }
1638
1685
  try {
1686
+ if (this.isProxyMode()) {
1687
+ const result2 = await this.proxyApiCall("request-approval", params);
1688
+ return {
1689
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1690
+ };
1691
+ }
1639
1692
  const result = await requestApproval(
1640
1693
  params,
1641
1694
  {
@@ -1679,6 +1732,12 @@ var RelayRailServer = class {
1679
1732
  };
1680
1733
  }
1681
1734
  try {
1735
+ if (this.isProxyMode()) {
1736
+ const result2 = await this.proxyApiCall("send-notification", params);
1737
+ return {
1738
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1739
+ };
1740
+ }
1682
1741
  const result = await sendNotification(
1683
1742
  params,
1684
1743
  {
@@ -1720,6 +1779,12 @@ var RelayRailServer = class {
1720
1779
  };
1721
1780
  }
1722
1781
  try {
1782
+ if (this.isProxyMode()) {
1783
+ const result2 = await this.proxyApiCall("await-response", params);
1784
+ return {
1785
+ content: [{ type: "text", text: JSON.stringify(result2) }]
1786
+ };
1787
+ }
1723
1788
  const result = await awaitResponse(
1724
1789
  params,
1725
1790
  {
@@ -1886,7 +1951,7 @@ var RelayRailServer = class {
1886
1951
  return this.server;
1887
1952
  }
1888
1953
  /**
1889
- * Get the Supabase client
1954
+ * Get the Supabase client (may be null in proxy mode)
1890
1955
  */
1891
1956
  getSupabase() {
1892
1957
  return this.supabase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relayrail/server",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "RelayRail MCP Server - SMS/Email connectivity for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",