@mcpjam/inspector 1.0.19 → 1.0.21
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/.env.production +2 -1
- package/dist/client/assets/index-B6vbeD-k.css +1 -0
- package/dist/client/assets/index-BK5R5b7m.js +1958 -0
- package/dist/client/index.html +2 -2
- package/dist/client/openrouter_logo.png +0 -0
- package/dist/server/index.js +550 -249
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -3
- package/dist/client/assets/index-Bf9F3wwu.js +0 -1886
- package/dist/client/assets/index-DkqfjygH.css +0 -1
package/dist/server/index.js
CHANGED
|
@@ -39,7 +39,7 @@ import * as Sentry2 from "@sentry/node";
|
|
|
39
39
|
import { serve } from "@hono/node-server";
|
|
40
40
|
import dotenv from "dotenv";
|
|
41
41
|
import fixPath from "fix-path";
|
|
42
|
-
import { Hono as
|
|
42
|
+
import { Hono as Hono15 } from "hono";
|
|
43
43
|
import { HTTPException } from "hono/http-exception";
|
|
44
44
|
import { cors } from "hono/cors";
|
|
45
45
|
import { logger } from "hono/logger";
|
|
@@ -885,7 +885,7 @@ var MCPClientManager = class {
|
|
|
885
885
|
};
|
|
886
886
|
|
|
887
887
|
// routes/mcp/index.ts
|
|
888
|
-
import { Hono as
|
|
888
|
+
import { Hono as Hono14 } from "hono";
|
|
889
889
|
|
|
890
890
|
// routes/mcp/connect.ts
|
|
891
891
|
import { Hono } from "hono";
|
|
@@ -1472,7 +1472,8 @@ resources.post("/widget/store", async (c) => {
|
|
|
1472
1472
|
toolInput,
|
|
1473
1473
|
toolOutput,
|
|
1474
1474
|
toolResponseMetadata,
|
|
1475
|
-
toolId
|
|
1475
|
+
toolId,
|
|
1476
|
+
theme
|
|
1476
1477
|
} = body;
|
|
1477
1478
|
if (!serverId || !uri || !toolId) {
|
|
1478
1479
|
return c.json({ success: false, error: "Missing required fields" }, 400);
|
|
@@ -1484,6 +1485,7 @@ resources.post("/widget/store", async (c) => {
|
|
|
1484
1485
|
toolOutput,
|
|
1485
1486
|
toolResponseMetadata: toolResponseMetadata ?? null,
|
|
1486
1487
|
toolId,
|
|
1488
|
+
theme: theme ?? "dark",
|
|
1487
1489
|
timestamp: Date.now()
|
|
1488
1490
|
});
|
|
1489
1491
|
return c.json({ success: true });
|
|
@@ -1544,7 +1546,14 @@ resources.get("/widget-content/:toolId", async (c) => {
|
|
|
1544
1546
|
404
|
|
1545
1547
|
);
|
|
1546
1548
|
}
|
|
1547
|
-
const {
|
|
1549
|
+
const {
|
|
1550
|
+
serverId,
|
|
1551
|
+
uri,
|
|
1552
|
+
toolInput,
|
|
1553
|
+
toolOutput,
|
|
1554
|
+
toolResponseMetadata,
|
|
1555
|
+
theme
|
|
1556
|
+
} = widgetData;
|
|
1548
1557
|
const mcpClientManager2 = c.mcpClientManager;
|
|
1549
1558
|
const availableServers = mcpClientManager2.listServers().filter((id) => Boolean(mcpClientManager2.getClient(id)));
|
|
1550
1559
|
let actualServerId = serverId;
|
|
@@ -1604,10 +1613,13 @@ resources.get("/widget-content/:toolId", async (c) => {
|
|
|
1604
1613
|
toolResponseMetadata: ${JSON.stringify(toolResponseMetadata ?? null)},
|
|
1605
1614
|
displayMode: 'inline',
|
|
1606
1615
|
maxHeight: 600,
|
|
1607
|
-
theme:
|
|
1616
|
+
theme: ${JSON.stringify(theme ?? "dark")},
|
|
1608
1617
|
locale: 'en-US',
|
|
1609
1618
|
safeArea: { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
|
|
1610
|
-
userAgent: {
|
|
1619
|
+
userAgent: {
|
|
1620
|
+
device: { type: 'desktop' },
|
|
1621
|
+
capabilities: { hover: true, touch: false }
|
|
1622
|
+
},
|
|
1611
1623
|
widgetState: null,
|
|
1612
1624
|
|
|
1613
1625
|
async setWidgetState(state) {
|
|
@@ -1731,6 +1743,28 @@ resources.get("/widget-content/:toolId", async (c) => {
|
|
|
1731
1743
|
}
|
|
1732
1744
|
} catch (err) {}
|
|
1733
1745
|
}, 0);
|
|
1746
|
+
|
|
1747
|
+
// Listen for theme changes from parent
|
|
1748
|
+
window.addEventListener('message', (event) => {
|
|
1749
|
+
if (event.data.type === 'webplus:set_globals') {
|
|
1750
|
+
const { globals } = event.data;
|
|
1751
|
+
|
|
1752
|
+
// Update theme if provided
|
|
1753
|
+
if (globals?.theme && window.openai) {
|
|
1754
|
+
window.openai.theme = globals.theme;
|
|
1755
|
+
|
|
1756
|
+
// Dispatch event for widgets that use useTheme() hook
|
|
1757
|
+
try {
|
|
1758
|
+
const globalsEvent = new CustomEvent('webplus:set_globals', {
|
|
1759
|
+
detail: { globals: { theme: globals.theme } }
|
|
1760
|
+
});
|
|
1761
|
+
window.dispatchEvent(globalsEvent);
|
|
1762
|
+
} catch (err) {
|
|
1763
|
+
console.error('[OpenAI Widget] Failed to dispatch theme change:', err);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1734
1768
|
})();
|
|
1735
1769
|
</script>
|
|
1736
1770
|
`;
|
|
@@ -1875,224 +1909,6 @@ var MCPJAM_PROVIDED_MODEL_IDS = [
|
|
|
1875
1909
|
var isMCPJamProvidedModel = (modelId) => {
|
|
1876
1910
|
return MCPJAM_PROVIDED_MODEL_IDS.includes(modelId);
|
|
1877
1911
|
};
|
|
1878
|
-
var Model = /* @__PURE__ */ ((Model2) => {
|
|
1879
|
-
Model2["CLAUDE_OPUS_4_0"] = "claude-opus-4-0";
|
|
1880
|
-
Model2["CLAUDE_SONNET_4_0"] = "claude-sonnet-4-0";
|
|
1881
|
-
Model2["CLAUDE_3_7_SONNET_LATEST"] = "claude-3-7-sonnet-latest";
|
|
1882
|
-
Model2["CLAUDE_3_5_SONNET_LATEST"] = "claude-3-5-sonnet-latest";
|
|
1883
|
-
Model2["CLAUDE_3_5_HAIKU_LATEST"] = "claude-3-5-haiku-latest";
|
|
1884
|
-
Model2["GPT_4_1"] = "gpt-4.1";
|
|
1885
|
-
Model2["GPT_4_1_MINI"] = "gpt-4.1-mini";
|
|
1886
|
-
Model2["GPT_4_1_NANO"] = "gpt-4.1-nano";
|
|
1887
|
-
Model2["GPT_4O"] = "gpt-4o";
|
|
1888
|
-
Model2["GPT_4O_MINI"] = "gpt-4o-mini";
|
|
1889
|
-
Model2["GPT_4_TURBO"] = "gpt-4-turbo";
|
|
1890
|
-
Model2["GPT_4"] = "gpt-4";
|
|
1891
|
-
Model2["GPT_5"] = "gpt-5";
|
|
1892
|
-
Model2["GPT_5_MINI"] = "gpt-5-mini";
|
|
1893
|
-
Model2["GPT_5_NANO"] = "gpt-5-nano";
|
|
1894
|
-
Model2["GPT_5_MAIN"] = "openai/gpt-5";
|
|
1895
|
-
Model2["GPT_5_PRO"] = "gpt-5-pro";
|
|
1896
|
-
Model2["GPT_5_CODEX"] = "gpt-5-codex";
|
|
1897
|
-
Model2["GPT_3_5_TURBO"] = "gpt-3.5-turbo";
|
|
1898
|
-
Model2["DEEPSEEK_CHAT"] = "deepseek-chat";
|
|
1899
|
-
Model2["DEEPSEEK_REASONER"] = "deepseek-reasoner";
|
|
1900
|
-
Model2["GEMINI_2_5_PRO"] = "gemini-2.5-pro";
|
|
1901
|
-
Model2["GEMINI_2_5_FLASH"] = "gemini-2.5-flash";
|
|
1902
|
-
Model2["GEMINI_2_5_FLASH_LITE"] = "gemini-2.5-flash-lite";
|
|
1903
|
-
Model2["GEMINI_2_0_FLASH_EXP"] = "gemini-2.0-flash-exp";
|
|
1904
|
-
Model2["GEMINI_1_5_PRO"] = "gemini-1.5-pro";
|
|
1905
|
-
Model2["GEMINI_1_5_PRO_002"] = "gemini-1.5-pro-002";
|
|
1906
|
-
Model2["GEMINI_1_5_FLASH"] = "gemini-1.5-flash";
|
|
1907
|
-
Model2["GEMINI_1_5_FLASH_002"] = "gemini-1.5-flash-002";
|
|
1908
|
-
Model2["GEMINI_1_5_FLASH_8B"] = "gemini-1.5-flash-8b";
|
|
1909
|
-
Model2["GEMINI_1_5_FLASH_8B_001"] = "gemini-1.5-flash-8b-001";
|
|
1910
|
-
Model2["GEMMA_3_2B"] = "gemma-3-2b";
|
|
1911
|
-
Model2["GEMMA_3_9B"] = "gemma-3-9b";
|
|
1912
|
-
Model2["GEMMA_3_27B"] = "gemma-3-27b";
|
|
1913
|
-
Model2["GEMMA_2_2B"] = "gemma-2-2b";
|
|
1914
|
-
Model2["GEMMA_2_9B"] = "gemma-2-9b";
|
|
1915
|
-
Model2["GEMMA_2_27B"] = "gemma-2-27b";
|
|
1916
|
-
Model2["CODE_GEMMA_2B"] = "codegemma-2b";
|
|
1917
|
-
Model2["CODE_GEMMA_7B"] = "codegemma-7b";
|
|
1918
|
-
Model2["MISTRAL_LARGE_LATEST"] = "mistral-large-latest";
|
|
1919
|
-
Model2["MISTRAL_SMALL_LATEST"] = "mistral-small-latest";
|
|
1920
|
-
Model2["CODESTRAL_LATEST"] = "codestral-latest";
|
|
1921
|
-
Model2["MINISTRAL_8B_LATEST"] = "ministral-8b-latest";
|
|
1922
|
-
Model2["MINISTRAL_3B_LATEST"] = "ministral-3b-latest";
|
|
1923
|
-
return Model2;
|
|
1924
|
-
})(Model || {});
|
|
1925
|
-
var SUPPORTED_MODELS = [
|
|
1926
|
-
{
|
|
1927
|
-
id: "claude-opus-4-0" /* CLAUDE_OPUS_4_0 */,
|
|
1928
|
-
name: "Claude Opus 4",
|
|
1929
|
-
provider: "anthropic"
|
|
1930
|
-
},
|
|
1931
|
-
{
|
|
1932
|
-
id: "claude-sonnet-4-0" /* CLAUDE_SONNET_4_0 */,
|
|
1933
|
-
name: "Claude Sonnet 4",
|
|
1934
|
-
provider: "anthropic"
|
|
1935
|
-
},
|
|
1936
|
-
{
|
|
1937
|
-
id: "claude-3-7-sonnet-latest" /* CLAUDE_3_7_SONNET_LATEST */,
|
|
1938
|
-
name: "Claude Sonnet 3.7",
|
|
1939
|
-
provider: "anthropic"
|
|
1940
|
-
},
|
|
1941
|
-
{
|
|
1942
|
-
id: "claude-3-5-sonnet-latest" /* CLAUDE_3_5_SONNET_LATEST */,
|
|
1943
|
-
name: "Claude Sonnet 3.5",
|
|
1944
|
-
provider: "anthropic"
|
|
1945
|
-
},
|
|
1946
|
-
{
|
|
1947
|
-
id: "claude-3-5-haiku-latest" /* CLAUDE_3_5_HAIKU_LATEST */,
|
|
1948
|
-
name: "Claude Haiku 3.5",
|
|
1949
|
-
provider: "anthropic"
|
|
1950
|
-
},
|
|
1951
|
-
{ id: "gpt-5" /* GPT_5 */, name: "GPT-5", provider: "openai" },
|
|
1952
|
-
{ id: "gpt-5-mini" /* GPT_5_MINI */, name: "GPT-5 Mini", provider: "openai" },
|
|
1953
|
-
{ id: "gpt-5-nano" /* GPT_5_NANO */, name: "GPT-5 Nano", provider: "openai" },
|
|
1954
|
-
{ id: Model.GPT_5_CHAT_LATEST, name: "GPT-5 Chat", provider: "openai" },
|
|
1955
|
-
{ id: "gpt-5-pro" /* GPT_5_PRO */, name: "GPT-5 Pro", provider: "openai" },
|
|
1956
|
-
{ id: "gpt-5-codex" /* GPT_5_CODEX */, name: "GPT-5 Codex", provider: "openai" },
|
|
1957
|
-
{ id: "gpt-4.1" /* GPT_4_1 */, name: "GPT-4.1", provider: "openai" },
|
|
1958
|
-
{ id: "gpt-4.1-mini" /* GPT_4_1_MINI */, name: "GPT-4.1 Mini", provider: "openai" },
|
|
1959
|
-
{ id: "gpt-4.1-nano" /* GPT_4_1_NANO */, name: "GPT-4.1 Nano", provider: "openai" },
|
|
1960
|
-
{ id: "gpt-4o" /* GPT_4O */, name: "GPT-4o", provider: "openai" },
|
|
1961
|
-
{ id: "gpt-4o-mini" /* GPT_4O_MINI */, name: "GPT-4o Mini", provider: "openai" },
|
|
1962
|
-
{ id: "deepseek-chat" /* DEEPSEEK_CHAT */, name: "DeepSeek Chat", provider: "deepseek" },
|
|
1963
|
-
{
|
|
1964
|
-
id: "deepseek-reasoner" /* DEEPSEEK_REASONER */,
|
|
1965
|
-
name: "DeepSeek Reasoner",
|
|
1966
|
-
provider: "deepseek"
|
|
1967
|
-
},
|
|
1968
|
-
// Google Gemini models (latest first)
|
|
1969
|
-
{
|
|
1970
|
-
id: "gemini-2.5-pro" /* GEMINI_2_5_PRO */,
|
|
1971
|
-
name: "Gemini 2.5 Pro",
|
|
1972
|
-
provider: "google"
|
|
1973
|
-
},
|
|
1974
|
-
{
|
|
1975
|
-
id: "gemini-2.5-flash" /* GEMINI_2_5_FLASH */,
|
|
1976
|
-
name: "Gemini 2.5 Flash",
|
|
1977
|
-
provider: "google"
|
|
1978
|
-
},
|
|
1979
|
-
{
|
|
1980
|
-
id: "gemini-2.0-flash-exp" /* GEMINI_2_0_FLASH_EXP */,
|
|
1981
|
-
name: "Gemini 2.0 Flash Experimental",
|
|
1982
|
-
provider: "google"
|
|
1983
|
-
},
|
|
1984
|
-
{
|
|
1985
|
-
id: "gemini-1.5-pro-002" /* GEMINI_1_5_PRO_002 */,
|
|
1986
|
-
name: "Gemini 1.5 Pro 002",
|
|
1987
|
-
provider: "google"
|
|
1988
|
-
},
|
|
1989
|
-
{
|
|
1990
|
-
id: "gemini-1.5-pro" /* GEMINI_1_5_PRO */,
|
|
1991
|
-
name: "Gemini 1.5 Pro",
|
|
1992
|
-
provider: "google"
|
|
1993
|
-
},
|
|
1994
|
-
{
|
|
1995
|
-
id: "gemini-1.5-flash-002" /* GEMINI_1_5_FLASH_002 */,
|
|
1996
|
-
name: "Gemini 1.5 Flash 002",
|
|
1997
|
-
provider: "google"
|
|
1998
|
-
},
|
|
1999
|
-
{
|
|
2000
|
-
id: "gemini-1.5-flash" /* GEMINI_1_5_FLASH */,
|
|
2001
|
-
name: "Gemini 1.5 Flash",
|
|
2002
|
-
provider: "google"
|
|
2003
|
-
},
|
|
2004
|
-
{
|
|
2005
|
-
id: "meta-llama/llama-3.3-70b-instruct",
|
|
2006
|
-
name: "Llama 3.3 70B (Free)",
|
|
2007
|
-
provider: "meta"
|
|
2008
|
-
},
|
|
2009
|
-
{
|
|
2010
|
-
id: "openai/gpt-oss-120b",
|
|
2011
|
-
name: "GPT-OSS 120B (Free)",
|
|
2012
|
-
provider: "openai"
|
|
2013
|
-
},
|
|
2014
|
-
{
|
|
2015
|
-
id: "x-ai/grok-4-fast",
|
|
2016
|
-
name: "Grok 4 Fast (Free)",
|
|
2017
|
-
provider: "x-ai"
|
|
2018
|
-
},
|
|
2019
|
-
{
|
|
2020
|
-
id: "openai/gpt-5-nano",
|
|
2021
|
-
name: "GPT-5 Nano (Free)",
|
|
2022
|
-
provider: "openai"
|
|
2023
|
-
},
|
|
2024
|
-
{
|
|
2025
|
-
id: "anthropic/claude-sonnet-4.5",
|
|
2026
|
-
name: "Claude Sonnet 4.5 (Free)",
|
|
2027
|
-
provider: "anthropic"
|
|
2028
|
-
},
|
|
2029
|
-
{
|
|
2030
|
-
id: "anthropic/claude-haiku-4.5",
|
|
2031
|
-
name: "Claude Haiku 4.5 (Free)",
|
|
2032
|
-
provider: "anthropic"
|
|
2033
|
-
},
|
|
2034
|
-
{
|
|
2035
|
-
id: "openai/gpt-5-codex",
|
|
2036
|
-
name: "GPT-5 Codex (Free)",
|
|
2037
|
-
provider: "openai"
|
|
2038
|
-
},
|
|
2039
|
-
{
|
|
2040
|
-
id: "openai/gpt-5",
|
|
2041
|
-
name: "GPT-5 (Free)",
|
|
2042
|
-
provider: "openai"
|
|
2043
|
-
},
|
|
2044
|
-
{
|
|
2045
|
-
id: "openai/gpt-5-mini",
|
|
2046
|
-
name: "GPT-5 Mini (Free)",
|
|
2047
|
-
provider: "openai"
|
|
2048
|
-
},
|
|
2049
|
-
{
|
|
2050
|
-
id: "google/gemini-2.5-flash-preview-09-2025",
|
|
2051
|
-
name: "Gemini 2.5 Flash Preview (Free)",
|
|
2052
|
-
provider: "google"
|
|
2053
|
-
},
|
|
2054
|
-
{
|
|
2055
|
-
id: "moonshotai/kimi-k2-0905",
|
|
2056
|
-
name: "Kimi K2 (Free)",
|
|
2057
|
-
provider: "moonshotai"
|
|
2058
|
-
},
|
|
2059
|
-
{
|
|
2060
|
-
id: "google/gemini-2.5-flash",
|
|
2061
|
-
name: "Gemini 2.5 Flash (Free)",
|
|
2062
|
-
provider: "google"
|
|
2063
|
-
},
|
|
2064
|
-
{
|
|
2065
|
-
id: "z-ai/glm-4.6",
|
|
2066
|
-
name: "GLM 4.6 (Free)",
|
|
2067
|
-
provider: "z-ai"
|
|
2068
|
-
},
|
|
2069
|
-
// Mistral models
|
|
2070
|
-
{
|
|
2071
|
-
id: "mistral-large-latest" /* MISTRAL_LARGE_LATEST */,
|
|
2072
|
-
name: "Mistral Large",
|
|
2073
|
-
provider: "mistral"
|
|
2074
|
-
},
|
|
2075
|
-
{
|
|
2076
|
-
id: "mistral-small-latest" /* MISTRAL_SMALL_LATEST */,
|
|
2077
|
-
name: "Mistral Small",
|
|
2078
|
-
provider: "mistral"
|
|
2079
|
-
},
|
|
2080
|
-
{
|
|
2081
|
-
id: "codestral-latest" /* CODESTRAL_LATEST */,
|
|
2082
|
-
name: "Codestral",
|
|
2083
|
-
provider: "mistral"
|
|
2084
|
-
},
|
|
2085
|
-
{
|
|
2086
|
-
id: "ministral-8b-latest" /* MINISTRAL_8B_LATEST */,
|
|
2087
|
-
name: "Ministral 8B",
|
|
2088
|
-
provider: "mistral"
|
|
2089
|
-
},
|
|
2090
|
-
{
|
|
2091
|
-
id: "ministral-3b-latest" /* MINISTRAL_3B_LATEST */,
|
|
2092
|
-
name: "Ministral 3B",
|
|
2093
|
-
provider: "mistral"
|
|
2094
|
-
}
|
|
2095
|
-
];
|
|
2096
1912
|
|
|
2097
1913
|
// routes/mcp/chat.ts
|
|
2098
1914
|
import { TextEncoder as TextEncoder2 } from "util";
|
|
@@ -2123,6 +1939,7 @@ import { createDeepSeek } from "@ai-sdk/deepseek";
|
|
|
2123
1939
|
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
2124
1940
|
import { createMistral } from "@ai-sdk/mistral";
|
|
2125
1941
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
1942
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
2126
1943
|
import { createOllama } from "ollama-ai-provider-v2";
|
|
2127
1944
|
var createLlmModel = (modelDefinition, apiKey, ollamaBaseUrl, litellmBaseUrl) => {
|
|
2128
1945
|
if (!modelDefinition?.id || !modelDefinition?.provider) {
|
|
@@ -2155,6 +1972,8 @@ var createLlmModel = (modelDefinition, apiKey, ollamaBaseUrl, litellmBaseUrl) =>
|
|
|
2155
1972
|
});
|
|
2156
1973
|
return openai.chat(modelDefinition.id);
|
|
2157
1974
|
}
|
|
1975
|
+
case "openrouter":
|
|
1976
|
+
return createOpenRouter({ apiKey })(modelDefinition.id);
|
|
2158
1977
|
default:
|
|
2159
1978
|
throw new Error(
|
|
2160
1979
|
`Unsupported provider: ${modelDefinition.provider} for model: ${modelDefinition.id}`
|
|
@@ -3042,9 +2861,382 @@ chat.post("/", async (c) => {
|
|
|
3042
2861
|
});
|
|
3043
2862
|
var chat_default = chat;
|
|
3044
2863
|
|
|
3045
|
-
// routes/mcp/
|
|
2864
|
+
// routes/mcp/chat-v2.ts
|
|
3046
2865
|
import { Hono as Hono7 } from "hono";
|
|
3047
|
-
|
|
2866
|
+
import {
|
|
2867
|
+
convertToModelMessages,
|
|
2868
|
+
streamText as streamText2,
|
|
2869
|
+
stepCountIs,
|
|
2870
|
+
createUIMessageStream,
|
|
2871
|
+
createUIMessageStreamResponse
|
|
2872
|
+
} from "ai";
|
|
2873
|
+
import zodToJsonSchema2 from "zod-to-json-schema";
|
|
2874
|
+
var DEFAULT_TEMPERATURE = 0.7;
|
|
2875
|
+
var chatV2 = new Hono7();
|
|
2876
|
+
chatV2.post("/", async (c) => {
|
|
2877
|
+
try {
|
|
2878
|
+
const body = await c.req.json();
|
|
2879
|
+
const mcpClientManager2 = c.mcpClientManager;
|
|
2880
|
+
const { messages, apiKey, model } = body;
|
|
2881
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
2882
|
+
return c.json({ error: "messages are required" }, 400);
|
|
2883
|
+
}
|
|
2884
|
+
const modelDefinition = model;
|
|
2885
|
+
if (!modelDefinition) {
|
|
2886
|
+
return c.json({ error: "model is not supported" }, 400);
|
|
2887
|
+
}
|
|
2888
|
+
const mcpTools = await mcpClientManager2.getToolsForAiSdk();
|
|
2889
|
+
if (modelDefinition.id && isMCPJamProvidedModel(modelDefinition.id)) {
|
|
2890
|
+
if (!process.env.CONVEX_HTTP_URL) {
|
|
2891
|
+
return c.json(
|
|
2892
|
+
{ error: "Server missing CONVEX_HTTP_URL configuration" },
|
|
2893
|
+
500
|
|
2894
|
+
);
|
|
2895
|
+
}
|
|
2896
|
+
const flattenedTools = mcpTools;
|
|
2897
|
+
const toolDefs = [];
|
|
2898
|
+
for (const [name, tool2] of Object.entries(flattenedTools)) {
|
|
2899
|
+
if (!tool2) continue;
|
|
2900
|
+
let serializedSchema;
|
|
2901
|
+
const schema = tool2.inputSchema;
|
|
2902
|
+
if (schema) {
|
|
2903
|
+
if (typeof schema === "object" && schema !== null && "jsonSchema" in schema) {
|
|
2904
|
+
serializedSchema = schema.jsonSchema;
|
|
2905
|
+
} else {
|
|
2906
|
+
try {
|
|
2907
|
+
serializedSchema = zodToJsonSchema2(schema);
|
|
2908
|
+
} catch {
|
|
2909
|
+
serializedSchema = {
|
|
2910
|
+
type: "object",
|
|
2911
|
+
properties: {},
|
|
2912
|
+
additionalProperties: false
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
toolDefs.push({
|
|
2918
|
+
name,
|
|
2919
|
+
description: tool2.description,
|
|
2920
|
+
inputSchema: serializedSchema ?? {
|
|
2921
|
+
type: "object",
|
|
2922
|
+
properties: {},
|
|
2923
|
+
additionalProperties: false
|
|
2924
|
+
}
|
|
2925
|
+
});
|
|
2926
|
+
}
|
|
2927
|
+
const authHeader = c.req.header("authorization") || void 0;
|
|
2928
|
+
let messageHistory = convertToModelMessages(messages);
|
|
2929
|
+
let steps = 0;
|
|
2930
|
+
const MAX_STEPS2 = 20;
|
|
2931
|
+
const stream = createUIMessageStream({
|
|
2932
|
+
execute: async ({ writer }) => {
|
|
2933
|
+
const msgId = `asst_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2934
|
+
while (steps < MAX_STEPS2) {
|
|
2935
|
+
const res = await fetch(`${process.env.CONVEX_HTTP_URL}/stream`, {
|
|
2936
|
+
method: "POST",
|
|
2937
|
+
headers: {
|
|
2938
|
+
"content-type": "application/json",
|
|
2939
|
+
...authHeader ? { authorization: authHeader } : {}
|
|
2940
|
+
},
|
|
2941
|
+
body: JSON.stringify({
|
|
2942
|
+
mode: "step",
|
|
2943
|
+
messages: JSON.stringify(messageHistory),
|
|
2944
|
+
model: String(modelDefinition.id),
|
|
2945
|
+
temperature: body.temperature ?? DEFAULT_TEMPERATURE,
|
|
2946
|
+
tools: toolDefs
|
|
2947
|
+
})
|
|
2948
|
+
});
|
|
2949
|
+
if (!res.ok) {
|
|
2950
|
+
const errorText = await res.text().catch(() => "step failed");
|
|
2951
|
+
writer.write({ type: "error", errorText });
|
|
2952
|
+
break;
|
|
2953
|
+
}
|
|
2954
|
+
const json = await res.json();
|
|
2955
|
+
if (!json?.ok || !Array.isArray(json.messages)) {
|
|
2956
|
+
break;
|
|
2957
|
+
}
|
|
2958
|
+
for (const m of json.messages) {
|
|
2959
|
+
if (m?.role === "assistant" && Array.isArray(m.content)) {
|
|
2960
|
+
for (const item of m.content) {
|
|
2961
|
+
if (item?.type === "text" && typeof item.text === "string") {
|
|
2962
|
+
writer.write({ type: "text-start", id: msgId });
|
|
2963
|
+
writer.write({
|
|
2964
|
+
type: "text-delta",
|
|
2965
|
+
id: msgId,
|
|
2966
|
+
delta: item.text
|
|
2967
|
+
});
|
|
2968
|
+
writer.write({ type: "text-end", id: msgId });
|
|
2969
|
+
} else if (item?.type === "tool-call") {
|
|
2970
|
+
if (item.input == null)
|
|
2971
|
+
item.input = item.parameters ?? item.args ?? {};
|
|
2972
|
+
if (!item.toolCallId)
|
|
2973
|
+
item.toolCallId = `tc_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2974
|
+
writer.write({
|
|
2975
|
+
type: "tool-input-available",
|
|
2976
|
+
toolCallId: item.toolCallId,
|
|
2977
|
+
toolName: item.toolName ?? item.name,
|
|
2978
|
+
input: item.input
|
|
2979
|
+
});
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
messageHistory.push(m);
|
|
2984
|
+
}
|
|
2985
|
+
const beforeLen = messageHistory.length;
|
|
2986
|
+
if (hasUnresolvedToolCalls(messageHistory)) {
|
|
2987
|
+
await executeToolCallsFromMessages(messageHistory, {
|
|
2988
|
+
clientManager: mcpClientManager2
|
|
2989
|
+
});
|
|
2990
|
+
}
|
|
2991
|
+
const newMessages = messageHistory.slice(beforeLen);
|
|
2992
|
+
for (const msg of newMessages) {
|
|
2993
|
+
if (msg?.role === "tool" && Array.isArray(msg.content)) {
|
|
2994
|
+
for (const item of msg.content) {
|
|
2995
|
+
if (item?.type === "tool-result") {
|
|
2996
|
+
writer.write({
|
|
2997
|
+
type: "tool-output-available",
|
|
2998
|
+
toolCallId: item.toolCallId,
|
|
2999
|
+
output: item.output ?? item.result ?? item.value
|
|
3000
|
+
});
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
steps++;
|
|
3006
|
+
const finishReason = json.finishReason;
|
|
3007
|
+
if (finishReason && finishReason !== "tool-calls") {
|
|
3008
|
+
break;
|
|
3009
|
+
}
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
});
|
|
3013
|
+
return createUIMessageStreamResponse({ stream });
|
|
3014
|
+
}
|
|
3015
|
+
const llmModel = createLlmModel(
|
|
3016
|
+
modelDefinition,
|
|
3017
|
+
apiKey ?? "",
|
|
3018
|
+
body.ollamaBaseUrl,
|
|
3019
|
+
body.litellmBaseUrl
|
|
3020
|
+
);
|
|
3021
|
+
const result = streamText2({
|
|
3022
|
+
model: llmModel,
|
|
3023
|
+
messages: convertToModelMessages(messages),
|
|
3024
|
+
temperature: body.temperature ?? DEFAULT_TEMPERATURE,
|
|
3025
|
+
tools: mcpTools,
|
|
3026
|
+
stopWhen: stepCountIs(20)
|
|
3027
|
+
});
|
|
3028
|
+
return result.toUIMessageStreamResponse();
|
|
3029
|
+
} catch (error) {
|
|
3030
|
+
console.error("[mcp/chat-v2] failed to process chat request", error);
|
|
3031
|
+
return c.json({ error: "Unexpected error" }, 500);
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
var chat_v2_default = chatV2;
|
|
3035
|
+
|
|
3036
|
+
// routes/mcp/oauth.ts
|
|
3037
|
+
import { Hono as Hono8 } from "hono";
|
|
3038
|
+
var oauth = new Hono8();
|
|
3039
|
+
oauth.post("/debug/proxy", async (c) => {
|
|
3040
|
+
try {
|
|
3041
|
+
const {
|
|
3042
|
+
url,
|
|
3043
|
+
method = "GET",
|
|
3044
|
+
body,
|
|
3045
|
+
headers: customHeaders
|
|
3046
|
+
} = await c.req.json();
|
|
3047
|
+
if (!url) {
|
|
3048
|
+
return c.json({ error: "Missing url parameter" }, 400);
|
|
3049
|
+
}
|
|
3050
|
+
let targetUrl;
|
|
3051
|
+
try {
|
|
3052
|
+
targetUrl = new URL(url);
|
|
3053
|
+
if (targetUrl.protocol !== "https:" && targetUrl.protocol !== "http:") {
|
|
3054
|
+
return c.json({ error: "Invalid protocol" }, 400);
|
|
3055
|
+
}
|
|
3056
|
+
} catch (error) {
|
|
3057
|
+
return c.json({ error: "Invalid URL format" }, 400);
|
|
3058
|
+
}
|
|
3059
|
+
const requestHeaders = {
|
|
3060
|
+
"User-Agent": "MCP-Inspector/1.0",
|
|
3061
|
+
...customHeaders
|
|
3062
|
+
};
|
|
3063
|
+
console.log("[OAuth Debug Proxy]");
|
|
3064
|
+
console.log(" URL:", url);
|
|
3065
|
+
console.log(" Method:", method);
|
|
3066
|
+
console.log(" Headers:", requestHeaders);
|
|
3067
|
+
if (body) {
|
|
3068
|
+
console.log(" Body:", JSON.stringify(body, null, 2));
|
|
3069
|
+
}
|
|
3070
|
+
const contentType = customHeaders?.["Content-Type"] || customHeaders?.["content-type"];
|
|
3071
|
+
const isFormUrlEncoded = contentType?.includes(
|
|
3072
|
+
"application/x-www-form-urlencoded"
|
|
3073
|
+
);
|
|
3074
|
+
if (method === "POST" && body && !contentType) {
|
|
3075
|
+
requestHeaders["Content-Type"] = "application/json";
|
|
3076
|
+
}
|
|
3077
|
+
const fetchOptions = {
|
|
3078
|
+
method,
|
|
3079
|
+
headers: requestHeaders
|
|
3080
|
+
};
|
|
3081
|
+
if (method === "POST" && body) {
|
|
3082
|
+
if (isFormUrlEncoded && typeof body === "object") {
|
|
3083
|
+
const params = new URLSearchParams();
|
|
3084
|
+
for (const [key, value] of Object.entries(body)) {
|
|
3085
|
+
params.append(key, String(value));
|
|
3086
|
+
}
|
|
3087
|
+
fetchOptions.body = params.toString();
|
|
3088
|
+
} else {
|
|
3089
|
+
fetchOptions.body = JSON.stringify(body);
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
const response = await fetch(targetUrl.toString(), fetchOptions);
|
|
3093
|
+
const headers = {};
|
|
3094
|
+
response.headers.forEach((value, key) => {
|
|
3095
|
+
headers[key] = value;
|
|
3096
|
+
});
|
|
3097
|
+
let responseBody = null;
|
|
3098
|
+
const contentTypeHeader = headers["content-type"] || "";
|
|
3099
|
+
if (contentTypeHeader.includes("text/event-stream")) {
|
|
3100
|
+
try {
|
|
3101
|
+
const text = await response.text();
|
|
3102
|
+
const events = [];
|
|
3103
|
+
const lines = text.split("\n");
|
|
3104
|
+
let currentEvent = {};
|
|
3105
|
+
for (const line of lines) {
|
|
3106
|
+
if (line.startsWith("event:")) {
|
|
3107
|
+
currentEvent.event = line.substring(6).trim();
|
|
3108
|
+
} else if (line.startsWith("data:")) {
|
|
3109
|
+
const data = line.substring(5).trim();
|
|
3110
|
+
try {
|
|
3111
|
+
currentEvent.data = JSON.parse(data);
|
|
3112
|
+
} catch {
|
|
3113
|
+
currentEvent.data = data;
|
|
3114
|
+
}
|
|
3115
|
+
} else if (line.startsWith("id:")) {
|
|
3116
|
+
currentEvent.id = line.substring(3).trim();
|
|
3117
|
+
} else if (line === "") {
|
|
3118
|
+
if (Object.keys(currentEvent).length > 0) {
|
|
3119
|
+
events.push(currentEvent);
|
|
3120
|
+
currentEvent = {};
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
responseBody = events.length > 0 ? {
|
|
3125
|
+
events,
|
|
3126
|
+
// If there's a "message" event with MCP response, extract it
|
|
3127
|
+
mcpResponse: events.find((e) => e.event === "message" || !e.event)?.data || null
|
|
3128
|
+
} : { raw: text };
|
|
3129
|
+
} catch (error) {
|
|
3130
|
+
console.error("Failed to parse SSE response:", error);
|
|
3131
|
+
responseBody = { error: "Failed to parse SSE stream" };
|
|
3132
|
+
}
|
|
3133
|
+
} else {
|
|
3134
|
+
try {
|
|
3135
|
+
responseBody = await response.json();
|
|
3136
|
+
} catch {
|
|
3137
|
+
try {
|
|
3138
|
+
responseBody = await response.text();
|
|
3139
|
+
} catch {
|
|
3140
|
+
responseBody = null;
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
console.log(" Response:", response.status, response.statusText);
|
|
3145
|
+
return c.json({
|
|
3146
|
+
status: response.status,
|
|
3147
|
+
statusText: response.statusText,
|
|
3148
|
+
headers,
|
|
3149
|
+
body: responseBody
|
|
3150
|
+
});
|
|
3151
|
+
} catch (error) {
|
|
3152
|
+
console.error("[OAuth Debug Proxy] Error:", error);
|
|
3153
|
+
return c.json(
|
|
3154
|
+
{
|
|
3155
|
+
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
3156
|
+
},
|
|
3157
|
+
500
|
|
3158
|
+
);
|
|
3159
|
+
}
|
|
3160
|
+
});
|
|
3161
|
+
oauth.post("/proxy", async (c) => {
|
|
3162
|
+
try {
|
|
3163
|
+
const {
|
|
3164
|
+
url,
|
|
3165
|
+
method = "GET",
|
|
3166
|
+
body,
|
|
3167
|
+
headers: customHeaders
|
|
3168
|
+
} = await c.req.json();
|
|
3169
|
+
if (!url) {
|
|
3170
|
+
return c.json({ error: "Missing url parameter" }, 400);
|
|
3171
|
+
}
|
|
3172
|
+
let targetUrl;
|
|
3173
|
+
try {
|
|
3174
|
+
targetUrl = new URL(url);
|
|
3175
|
+
if (targetUrl.protocol !== "https:" && targetUrl.protocol !== "http:") {
|
|
3176
|
+
return c.json({ error: "Invalid protocol" }, 400);
|
|
3177
|
+
}
|
|
3178
|
+
} catch (error) {
|
|
3179
|
+
return c.json({ error: "Invalid URL format" }, 400);
|
|
3180
|
+
}
|
|
3181
|
+
const requestHeaders = {
|
|
3182
|
+
"User-Agent": "MCP-Inspector/1.0",
|
|
3183
|
+
...customHeaders
|
|
3184
|
+
};
|
|
3185
|
+
const contentType = customHeaders?.["Content-Type"] || customHeaders?.["content-type"];
|
|
3186
|
+
const isFormUrlEncoded = contentType?.includes(
|
|
3187
|
+
"application/x-www-form-urlencoded"
|
|
3188
|
+
);
|
|
3189
|
+
if (method === "POST" && body && !contentType) {
|
|
3190
|
+
requestHeaders["Content-Type"] = "application/json";
|
|
3191
|
+
}
|
|
3192
|
+
const fetchOptions = {
|
|
3193
|
+
method,
|
|
3194
|
+
headers: requestHeaders
|
|
3195
|
+
};
|
|
3196
|
+
if (method === "POST" && body) {
|
|
3197
|
+
if (isFormUrlEncoded && typeof body === "object") {
|
|
3198
|
+
const params = new URLSearchParams();
|
|
3199
|
+
for (const [key, value] of Object.entries(body)) {
|
|
3200
|
+
params.append(key, String(value));
|
|
3201
|
+
}
|
|
3202
|
+
fetchOptions.body = params.toString();
|
|
3203
|
+
} else if (typeof body === "string") {
|
|
3204
|
+
fetchOptions.body = body;
|
|
3205
|
+
} else {
|
|
3206
|
+
fetchOptions.body = JSON.stringify(body);
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
const response = await fetch(targetUrl.toString(), fetchOptions);
|
|
3210
|
+
const headers = {};
|
|
3211
|
+
response.headers.forEach((value, key) => {
|
|
3212
|
+
headers[key] = value;
|
|
3213
|
+
});
|
|
3214
|
+
let responseBody = null;
|
|
3215
|
+
try {
|
|
3216
|
+
responseBody = await response.json();
|
|
3217
|
+
} catch {
|
|
3218
|
+
try {
|
|
3219
|
+
responseBody = await response.text();
|
|
3220
|
+
} catch {
|
|
3221
|
+
responseBody = null;
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
return c.json({
|
|
3225
|
+
status: response.status,
|
|
3226
|
+
statusText: response.statusText,
|
|
3227
|
+
headers,
|
|
3228
|
+
body: responseBody
|
|
3229
|
+
});
|
|
3230
|
+
} catch (error) {
|
|
3231
|
+
console.error("OAuth proxy error:", error);
|
|
3232
|
+
return c.json(
|
|
3233
|
+
{
|
|
3234
|
+
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
3235
|
+
},
|
|
3236
|
+
500
|
|
3237
|
+
);
|
|
3238
|
+
}
|
|
3239
|
+
});
|
|
3048
3240
|
oauth.get("/metadata", async (c) => {
|
|
3049
3241
|
try {
|
|
3050
3242
|
const url = c.req.query("url");
|
|
@@ -3054,8 +3246,8 @@ oauth.get("/metadata", async (c) => {
|
|
|
3054
3246
|
let metadataUrl;
|
|
3055
3247
|
try {
|
|
3056
3248
|
metadataUrl = new URL(url);
|
|
3057
|
-
if (metadataUrl.protocol !== "https:") {
|
|
3058
|
-
return c.json({ error: "
|
|
3249
|
+
if (metadataUrl.protocol !== "https:" && metadataUrl.protocol !== "http:") {
|
|
3250
|
+
return c.json({ error: "Invalid protocol" }, 400);
|
|
3059
3251
|
}
|
|
3060
3252
|
} catch (error) {
|
|
3061
3253
|
return c.json({ error: "Invalid URL format" }, 400);
|
|
@@ -3090,8 +3282,8 @@ oauth.get("/metadata", async (c) => {
|
|
|
3090
3282
|
var oauth_default = oauth;
|
|
3091
3283
|
|
|
3092
3284
|
// routes/mcp/export.ts
|
|
3093
|
-
import { Hono as
|
|
3094
|
-
var exporter = new
|
|
3285
|
+
import { Hono as Hono9 } from "hono";
|
|
3286
|
+
var exporter = new Hono9();
|
|
3095
3287
|
exporter.post("/server", async (c) => {
|
|
3096
3288
|
try {
|
|
3097
3289
|
const { serverId } = await c.req.json();
|
|
@@ -3147,20 +3339,20 @@ exporter.post("/server", async (c) => {
|
|
|
3147
3339
|
var export_default = exporter;
|
|
3148
3340
|
|
|
3149
3341
|
// routes/mcp/interceptor.ts
|
|
3150
|
-
import { Hono as
|
|
3151
|
-
var interceptor = new
|
|
3342
|
+
import { Hono as Hono10 } from "hono";
|
|
3343
|
+
var interceptor = new Hono10();
|
|
3152
3344
|
var interceptor_default = interceptor;
|
|
3153
3345
|
|
|
3154
3346
|
// routes/mcp/evals.ts
|
|
3155
|
-
import { Hono as
|
|
3347
|
+
import { Hono as Hono11 } from "hono";
|
|
3156
3348
|
import { z as z3 } from "zod";
|
|
3157
3349
|
|
|
3158
3350
|
// ../evals-cli/src/evals/runner.ts
|
|
3159
3351
|
import { MCPClient } from "@mastra/mcp";
|
|
3160
|
-
import { streamText as
|
|
3352
|
+
import { streamText as streamText3 } from "ai";
|
|
3161
3353
|
|
|
3162
3354
|
// ../node_modules/convex/dist/esm/index.js
|
|
3163
|
-
var version = "1.
|
|
3355
|
+
var version = "1.27.3";
|
|
3164
3356
|
|
|
3165
3357
|
// ../node_modules/convex/dist/esm/values/base64.js
|
|
3166
3358
|
var lookup = [];
|
|
@@ -3791,7 +3983,7 @@ function createApi(pathParts = []) {
|
|
|
3791
3983
|
}
|
|
3792
3984
|
var anyApi = createApi();
|
|
3793
3985
|
|
|
3794
|
-
// ../node_modules/convex/dist/esm/
|
|
3986
|
+
// ../node_modules/convex/dist/esm/browser/long.js
|
|
3795
3987
|
var __defProp4 = Object.defineProperty;
|
|
3796
3988
|
var __defNormalProp3 = (obj, key, value) => key in obj ? __defProp4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3797
3989
|
var __publicField3 = (obj, key, value) => __defNormalProp3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -3868,7 +4060,7 @@ var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
|
|
|
3868
4060
|
var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
|
|
3869
4061
|
var MAX_UNSIGNED_VALUE = new Long(4294967295 | 0, 4294967295 | 0);
|
|
3870
4062
|
|
|
3871
|
-
// ../node_modules/
|
|
4063
|
+
// ../node_modules/jwt-decode/build/esm/index.js
|
|
3872
4064
|
var InvalidTokenError = class extends Error {
|
|
3873
4065
|
};
|
|
3874
4066
|
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
@@ -8686,7 +8878,7 @@ import { z as z2 } from "zod";
|
|
|
8686
8878
|
|
|
8687
8879
|
// ../shared/tools.ts
|
|
8688
8880
|
import { z } from "zod";
|
|
8689
|
-
import { zodToJsonSchema as
|
|
8881
|
+
import { zodToJsonSchema as zodToJsonSchema3 } from "zod-to-json-schema";
|
|
8690
8882
|
import { tool } from "ai";
|
|
8691
8883
|
var fallbackInputSchema = z.object({}).passthrough();
|
|
8692
8884
|
var UNREPRESENTABLE_JSON_SCHEMA_MESSAGES = [
|
|
@@ -8721,7 +8913,7 @@ function canConvertToJSONSchema(schema) {
|
|
|
8721
8913
|
}
|
|
8722
8914
|
}
|
|
8723
8915
|
try {
|
|
8724
|
-
|
|
8916
|
+
zodToJsonSchema3(schema);
|
|
8725
8917
|
return true;
|
|
8726
8918
|
} catch (error) {
|
|
8727
8919
|
if (isUnrepresentableSchemaError(error)) {
|
|
@@ -8961,7 +9153,7 @@ var isValidLlmApiKey = (key) => {
|
|
|
8961
9153
|
};
|
|
8962
9154
|
|
|
8963
9155
|
// ../evals-cli/src/utils/helpers.ts
|
|
8964
|
-
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
9156
|
+
import { createOpenRouter as createOpenRouter2 } from "@openrouter/ai-sdk-provider";
|
|
8965
9157
|
import { createOpenAI as createOpenAI2 } from "@ai-sdk/openai";
|
|
8966
9158
|
import { createAnthropic as createAnthropic2 } from "@ai-sdk/anthropic";
|
|
8967
9159
|
var createLlmModel2 = (provider, model, llmsConfig) => {
|
|
@@ -8974,7 +9166,7 @@ var createLlmModel2 = (provider, model, llmsConfig) => {
|
|
|
8974
9166
|
case "openai":
|
|
8975
9167
|
return createOpenAI2({ apiKey: llmsConfig.openai })(model);
|
|
8976
9168
|
case "openrouter":
|
|
8977
|
-
return
|
|
9169
|
+
return createOpenRouter2({ apiKey: llmsConfig.openrouter })(model);
|
|
8978
9170
|
default:
|
|
8979
9171
|
Logger.errorWithExit(`Unsupported provider: ${provider}`);
|
|
8980
9172
|
}
|
|
@@ -9234,7 +9426,7 @@ var runIteration = async ({
|
|
|
9234
9426
|
let assistantStreaming = false;
|
|
9235
9427
|
let streamResult;
|
|
9236
9428
|
try {
|
|
9237
|
-
streamResult = await
|
|
9429
|
+
streamResult = await streamText3({
|
|
9238
9430
|
model: createLlmModel2(provider, model, llms),
|
|
9239
9431
|
system,
|
|
9240
9432
|
temperature,
|
|
@@ -9692,7 +9884,7 @@ async function collectToolsForServers(clientManager, serverIds) {
|
|
|
9692
9884
|
);
|
|
9693
9885
|
return perServerTools.flat();
|
|
9694
9886
|
}
|
|
9695
|
-
var evals = new
|
|
9887
|
+
var evals = new Hono11();
|
|
9696
9888
|
var RunEvalsRequestSchema = z3.object({
|
|
9697
9889
|
tests: z3.array(
|
|
9698
9890
|
z3.object({
|
|
@@ -9832,11 +10024,11 @@ evals.post("/generate-tests", async (c) => {
|
|
|
9832
10024
|
var evals_default = evals;
|
|
9833
10025
|
|
|
9834
10026
|
// routes/mcp/http-adapters.ts
|
|
9835
|
-
import { Hono as
|
|
10027
|
+
import { Hono as Hono12 } from "hono";
|
|
9836
10028
|
|
|
9837
10029
|
// services/mcp-http-bridge.ts
|
|
9838
10030
|
import { z as z4 } from "zod";
|
|
9839
|
-
import { zodToJsonSchema as
|
|
10031
|
+
import { zodToJsonSchema as zodToJsonSchema4 } from "zod-to-json-schema";
|
|
9840
10032
|
function buildInitializeResult(serverId, mode) {
|
|
9841
10033
|
if (mode === "adapter") {
|
|
9842
10034
|
return {
|
|
@@ -9868,7 +10060,7 @@ function toJsonSchemaMaybe(schema) {
|
|
|
9868
10060
|
try {
|
|
9869
10061
|
if (schema && typeof schema === "object") {
|
|
9870
10062
|
if (schema instanceof z4.ZodType || "_def" in schema && "parse" in schema) {
|
|
9871
|
-
return
|
|
10063
|
+
return zodToJsonSchema4(schema);
|
|
9872
10064
|
}
|
|
9873
10065
|
}
|
|
9874
10066
|
} catch {
|
|
@@ -10039,7 +10231,7 @@ async function handleJsonRpc(serverId, body, clientManager, mode) {
|
|
|
10039
10231
|
var sessions = /* @__PURE__ */ new Map();
|
|
10040
10232
|
var latestSessionByServer = /* @__PURE__ */ new Map();
|
|
10041
10233
|
function createHttpHandler(mode, routePrefix) {
|
|
10042
|
-
const router = new
|
|
10234
|
+
const router = new Hono12();
|
|
10043
10235
|
router.options(
|
|
10044
10236
|
"/:serverId",
|
|
10045
10237
|
(c) => c.body(null, 204, {
|
|
@@ -10258,8 +10450,115 @@ function createHttpHandler(mode, routePrefix) {
|
|
|
10258
10450
|
var adapterHttp = createHttpHandler("adapter", "adapter-http");
|
|
10259
10451
|
var managerHttp = createHttpHandler("manager", "manager-http");
|
|
10260
10452
|
|
|
10453
|
+
// routes/mcp/elicitation.ts
|
|
10454
|
+
import { Hono as Hono13 } from "hono";
|
|
10455
|
+
var elicitation = new Hono13();
|
|
10456
|
+
var elicitationSubscribers = /* @__PURE__ */ new Set();
|
|
10457
|
+
function broadcastElicitation(event) {
|
|
10458
|
+
for (const sub of Array.from(elicitationSubscribers)) {
|
|
10459
|
+
try {
|
|
10460
|
+
sub.send(event);
|
|
10461
|
+
} catch {
|
|
10462
|
+
try {
|
|
10463
|
+
sub.close();
|
|
10464
|
+
} catch {
|
|
10465
|
+
}
|
|
10466
|
+
elicitationSubscribers.delete(sub);
|
|
10467
|
+
}
|
|
10468
|
+
}
|
|
10469
|
+
}
|
|
10470
|
+
var isCallbackRegistered = false;
|
|
10471
|
+
elicitation.use("*", async (c, next) => {
|
|
10472
|
+
if (!isCallbackRegistered) {
|
|
10473
|
+
const manager = c.mcpClientManager;
|
|
10474
|
+
manager.setElicitationCallback(({ requestId, message, schema }) => {
|
|
10475
|
+
return new Promise((resolve2, reject) => {
|
|
10476
|
+
try {
|
|
10477
|
+
manager.getPendingElicitations().set(requestId, { resolve: resolve2, reject });
|
|
10478
|
+
} catch {
|
|
10479
|
+
}
|
|
10480
|
+
broadcastElicitation({
|
|
10481
|
+
type: "elicitation_request",
|
|
10482
|
+
requestId,
|
|
10483
|
+
message,
|
|
10484
|
+
schema,
|
|
10485
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10486
|
+
});
|
|
10487
|
+
});
|
|
10488
|
+
});
|
|
10489
|
+
isCallbackRegistered = true;
|
|
10490
|
+
}
|
|
10491
|
+
await next();
|
|
10492
|
+
});
|
|
10493
|
+
elicitation.get("/stream", async (c) => {
|
|
10494
|
+
const encoder = new TextEncoder();
|
|
10495
|
+
const stream = new ReadableStream({
|
|
10496
|
+
start(controller) {
|
|
10497
|
+
const send = (event) => {
|
|
10498
|
+
const payload = `data: ${JSON.stringify(event)}
|
|
10499
|
+
|
|
10500
|
+
`;
|
|
10501
|
+
controller.enqueue(encoder.encode(payload));
|
|
10502
|
+
};
|
|
10503
|
+
const keepAlive = setInterval(() => {
|
|
10504
|
+
try {
|
|
10505
|
+
controller.enqueue(encoder.encode(`: keep-alive
|
|
10506
|
+
|
|
10507
|
+
`));
|
|
10508
|
+
} catch {
|
|
10509
|
+
}
|
|
10510
|
+
}, 25e3);
|
|
10511
|
+
const close = () => {
|
|
10512
|
+
clearInterval(keepAlive);
|
|
10513
|
+
try {
|
|
10514
|
+
controller.close();
|
|
10515
|
+
} catch {
|
|
10516
|
+
}
|
|
10517
|
+
};
|
|
10518
|
+
controller.enqueue(encoder.encode(`retry: 1500
|
|
10519
|
+
|
|
10520
|
+
`));
|
|
10521
|
+
const subscriber = { send, close };
|
|
10522
|
+
elicitationSubscribers.add(subscriber);
|
|
10523
|
+
c.req.raw.signal?.addEventListener?.("abort", () => {
|
|
10524
|
+
elicitationSubscribers.delete(subscriber);
|
|
10525
|
+
close();
|
|
10526
|
+
});
|
|
10527
|
+
}
|
|
10528
|
+
});
|
|
10529
|
+
return new Response(stream, {
|
|
10530
|
+
status: 200,
|
|
10531
|
+
headers: {
|
|
10532
|
+
"Content-Type": "text/event-stream",
|
|
10533
|
+
"Cache-Control": "no-cache, no-transform",
|
|
10534
|
+
Connection: "keep-alive",
|
|
10535
|
+
"X-Accel-Buffering": "no",
|
|
10536
|
+
"Access-Control-Allow-Origin": "*"
|
|
10537
|
+
}
|
|
10538
|
+
});
|
|
10539
|
+
});
|
|
10540
|
+
elicitation.post("/respond", async (c) => {
|
|
10541
|
+
try {
|
|
10542
|
+
const body = await c.req.json();
|
|
10543
|
+
const { requestId, action, content } = body;
|
|
10544
|
+
if (!requestId || !action) {
|
|
10545
|
+
return c.json({ error: "Missing requestId or action" }, 400);
|
|
10546
|
+
}
|
|
10547
|
+
const response = action === "accept" ? { action: "accept", content: content ?? {} } : { action };
|
|
10548
|
+
const ok = c.mcpClientManager.respondToElicitation(requestId, response);
|
|
10549
|
+
if (!ok) {
|
|
10550
|
+
return c.json({ error: "Unknown or expired requestId" }, 404);
|
|
10551
|
+
}
|
|
10552
|
+
broadcastElicitation({ type: "elicitation_complete", requestId });
|
|
10553
|
+
return c.json({ ok: true });
|
|
10554
|
+
} catch (e) {
|
|
10555
|
+
return c.json({ error: e?.message || "Failed to respond" }, 400);
|
|
10556
|
+
}
|
|
10557
|
+
});
|
|
10558
|
+
var elicitation_default = elicitation;
|
|
10559
|
+
|
|
10261
10560
|
// routes/mcp/index.ts
|
|
10262
|
-
var mcp = new
|
|
10561
|
+
var mcp = new Hono14();
|
|
10263
10562
|
mcp.get("/health", (c) => {
|
|
10264
10563
|
return c.json({
|
|
10265
10564
|
service: "MCP API",
|
|
@@ -10268,6 +10567,8 @@ mcp.get("/health", (c) => {
|
|
|
10268
10567
|
});
|
|
10269
10568
|
});
|
|
10270
10569
|
mcp.route("/chat", chat_default);
|
|
10570
|
+
mcp.route("/chat-v2", chat_v2_default);
|
|
10571
|
+
mcp.route("/elicitation", elicitation_default);
|
|
10271
10572
|
mcp.route("/connect", connect_default);
|
|
10272
10573
|
mcp.route("/servers", servers_default);
|
|
10273
10574
|
mcp.route("/tools", tools_default);
|
|
@@ -10483,7 +10784,7 @@ try {
|
|
|
10483
10784
|
fixPath();
|
|
10484
10785
|
} catch {
|
|
10485
10786
|
}
|
|
10486
|
-
var app = new
|
|
10787
|
+
var app = new Hono15().onError((err, c) => {
|
|
10487
10788
|
console.error("Unhandled error:", err);
|
|
10488
10789
|
Sentry2.captureException(err);
|
|
10489
10790
|
if (err instanceof HTTPException) {
|