@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 +74 -9
- package/dist/index.d.ts +11 -2
- package/dist/index.js +74 -9
- package/package.json +1 -1
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
|
|
187
|
+
const prefixes = getApiKeyPrefixes(apiKey);
|
|
177
188
|
const hash = hashApiKey(apiKey);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
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
|
|
185
|
+
const prefixes = getApiKeyPrefixes(apiKey);
|
|
175
186
|
const hash = hashApiKey(apiKey);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
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;
|