Skip to content

Commit aa65a19

Browse files
committed
run format, lint, and type check
1 parent c3cec6c commit aa65a19

File tree

6 files changed

+130
-99
lines changed

6 files changed

+130
-99
lines changed

src/lib/server/mcp/hf.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ export const hasAuthHeader = (h?: Record<string, string>) =>
44
!!h && Object.keys(h).some((k) => k.toLowerCase() === "authorization");
55

66
export const isStrictHfMcpLogin = (urlString: string) => {
7-
try {
8-
const u = new URL(urlString);
9-
const host = u.hostname.toLowerCase();
10-
const allowedHosts = new Set(["hf.co", "huggingface.co"]);
11-
return (
12-
u.protocol === "https:" &&
13-
allowedHosts.has(host) &&
14-
u.pathname === "/mcp" &&
15-
u.search === "?login"
16-
);
17-
} catch {
18-
return false;
19-
}
7+
try {
8+
const u = new URL(urlString);
9+
const host = u.hostname.toLowerCase();
10+
const allowedHosts = new Set(["hf.co", "huggingface.co"]);
11+
return (
12+
u.protocol === "https:" &&
13+
allowedHosts.has(host) &&
14+
u.pathname === "/mcp" &&
15+
u.search === "?login"
16+
);
17+
} catch {
18+
return false;
19+
}
2020
};
2121

2222
export const hasNonEmptyToken = (tok: unknown): tok is string =>

src/lib/server/mcp/tools.ts

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -61,38 +61,43 @@ type ListedTool = {
6161
};
6262

6363
async function listServerTools(
64-
server: McpServerConfig,
65-
opts: { signal?: AbortSignal } = {}
64+
server: McpServerConfig,
65+
opts: { signal?: AbortSignal } = {}
6666
): Promise<ListedTool[]> {
67-
const url = new URL(server.url);
68-
const client = new Client({ name: "chat-ui-mcp", version: "0.1.0" });
69-
try {
70-
try {
71-
const transport = new StreamableHTTPClientTransport(url, {
72-
requestInit: { headers: server.headers, signal: opts.signal },
73-
});
74-
await client.connect(transport);
75-
} catch {
76-
const transport = new SSEClientTransport(url, {
77-
requestInit: { headers: server.headers, signal: opts.signal },
78-
});
79-
await client.connect(transport);
80-
}
81-
82-
const response = await client.listTools({});
83-
const tools = Array.isArray(response?.tools) ? (response.tools as ListedTool[]) : [];
84-
try {
85-
console.debug(
86-
{ server: server.name, url: server.url, count: tools.length, toolNames: tools.map((t) => t?.name).filter(Boolean) },
87-
"[mcp] listed tools from server"
88-
);
89-
} catch {}
90-
return tools;
91-
} finally {
92-
try {
93-
await client.close?.();
94-
} catch {
95-
// ignore close errors
67+
const url = new URL(server.url);
68+
const client = new Client({ name: "chat-ui-mcp", version: "0.1.0" });
69+
try {
70+
try {
71+
const transport = new StreamableHTTPClientTransport(url, {
72+
requestInit: { headers: server.headers, signal: opts.signal },
73+
});
74+
await client.connect(transport);
75+
} catch {
76+
const transport = new SSEClientTransport(url, {
77+
requestInit: { headers: server.headers, signal: opts.signal },
78+
});
79+
await client.connect(transport);
80+
}
81+
82+
const response = await client.listTools({});
83+
const tools = Array.isArray(response?.tools) ? (response.tools as ListedTool[]) : [];
84+
try {
85+
console.debug(
86+
{
87+
server: server.name,
88+
url: server.url,
89+
count: tools.length,
90+
toolNames: tools.map((t) => t?.name).filter(Boolean),
91+
},
92+
"[mcp] listed tools from server"
93+
);
94+
} catch {}
95+
return tools;
96+
} finally {
97+
try {
98+
await client.close?.();
99+
} catch {
100+
// ignore close errors
96101
}
97102
}
98103
}

src/lib/server/textGeneration/mcp/runMcpFlow.ts

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ export async function* runMcpFlow({
4242
> {
4343
// Start from env-configured servers
4444
let servers = getMcpServers();
45-
try {
46-
console.debug(
47-
{ baseServers: servers.map((s) => ({ name: s.name, url: s.url })), count: servers.length },
48-
"[mcp] base servers loaded"
49-
);
50-
} catch {}
45+
try {
46+
console.debug(
47+
{ baseServers: servers.map((s) => ({ name: s.name, url: s.url })), count: servers.length },
48+
"[mcp] base servers loaded"
49+
);
50+
} catch {}
5151

5252
// Merge in request-provided custom servers (if any)
5353
try {
@@ -75,7 +75,11 @@ export async function* runMcpFlow({
7575
console.debug(
7676
{
7777
customProvidedCount: custom.length,
78-
mergedServers: servers.map((s) => ({ name: s.name, url: s.url, hasAuth: !!s.headers?.Authorization })),
78+
mergedServers: servers.map((s) => ({
79+
name: s.name,
80+
url: s.url,
81+
hasAuth: !!s.headers?.Authorization,
82+
})),
7983
},
8084
"[mcp] merged request-provided servers"
8185
);
@@ -164,7 +168,10 @@ export async function* runMcpFlow({
164168
} catch {
165169
// best-effort overlay; continue if anything goes wrong
166170
}
167-
console.debug({ count: servers.length, servers: servers.map((s) => s.name) }, "[mcp] servers configured");
171+
console.debug(
172+
{ count: servers.length, servers: servers.map((s) => s.name) },
173+
"[mcp] servers configured"
174+
);
168175
if (servers.length === 0) {
169176
return false;
170177
}
@@ -173,12 +180,20 @@ export async function* runMcpFlow({
173180
try {
174181
const supportsTools = Boolean((model as unknown as { supportsTools?: boolean }).supportsTools);
175182
const toolsEnabled = Boolean(forceTools) || supportsTools;
176-
console.debug(
177-
{ model: model.id ?? model.name, supportsTools, forceTools: Boolean(forceTools), toolsEnabled },
183+
console.debug(
184+
{
185+
model: model.id ?? model.name,
186+
supportsTools,
187+
forceTools: Boolean(forceTools),
188+
toolsEnabled,
189+
},
178190
"[mcp] tools gate evaluation"
179191
);
180192
if (!toolsEnabled) {
181-
console.info({ model: model.id ?? model.name }, "[mcp] tools disabled for model; skipping MCP flow");
193+
console.info(
194+
{ model: model.id ?? model.name },
195+
"[mcp] tools disabled for model; skipping MCP flow"
196+
);
182197
return false;
183198
}
184199
} catch {
@@ -248,7 +263,7 @@ export async function* runMcpFlow({
248263
route: resolvedRoute,
249264
candidateModelId,
250265
toolCount: oaTools.length,
251-
hasUserToken: Boolean((locals as any)?.token),
266+
hasUserToken: Boolean((locals as unknown as { token?: string })?.token),
252267
},
253268
"[mcp] starting completion with tools"
254269
);
@@ -396,7 +411,7 @@ export async function* runMcpFlow({
396411
messages: messagesOpenAI,
397412
};
398413

399-
const completionStream: Stream<ChatCompletionChunk> = await openai.chat.completions.create(
414+
const completionStream: Stream<ChatCompletionChunk> = await openai.chat.completions.create(
400415
completionRequest,
401416
{
402417
signal: abortSignal,
@@ -446,7 +461,12 @@ export async function* runMcpFlow({
446461
}
447462
if (!firstToolDeltaLogged) {
448463
try {
449-
const first = toolCallState[Object.keys(toolCallState).map((k) => Number(k)).sort((a,b)=>a-b)[0] ?? 0];
464+
const first =
465+
toolCallState[
466+
Object.keys(toolCallState)
467+
.map((k) => Number(k))
468+
.sort((a, b) => a - b)[0] ?? 0
469+
];
450470
console.info(
451471
{ firstCallName: first?.name, hasId: Boolean(first?.id) },
452472
"[mcp] observed streamed tool_call delta"
@@ -522,7 +542,10 @@ export async function* runMcpFlow({
522542
const missingId = Object.values(toolCallState).some((c) => c?.name && !c?.id);
523543
let calls: NormalizedToolCall[];
524544
if (missingId) {
525-
console.debug({ loop }, "[mcp] missing tool_call id in stream; retrying non-stream to recover ids");
545+
console.debug(
546+
{ loop },
547+
"[mcp] missing tool_call id in stream; retrying non-stream to recover ids"
548+
);
526549
const nonStream = await openai.chat.completions.create(
527550
{ ...completionBase, messages: messagesOpenAI, stream: false },
528551
{
@@ -593,10 +616,10 @@ export async function* runMcpFlow({
593616
];
594617
toolMsgCount = event.summary.toolMessages?.length ?? 0;
595618
toolRunCount = event.summary.toolRuns?.length ?? 0;
596-
console.info(
597-
{ toolMsgCount, toolRunCount },
598-
"[mcp] tools executed; continuing loop for follow-up completion"
599-
);
619+
console.info(
620+
{ toolMsgCount, toolRunCount },
621+
"[mcp] tools executed; continuing loop for follow-up completion"
622+
);
600623
}
601624
}
602625
// Continue loop: next iteration will use tool messages to get the final content
@@ -617,7 +640,10 @@ export async function* runMcpFlow({
617640
text: lastAssistantContent,
618641
interrupted: false,
619642
};
620-
console.info({ length: lastAssistantContent.length, loop }, "[mcp] final answer emitted (no tool_calls)");
643+
console.info(
644+
{ length: lastAssistantContent.length, loop },
645+
"[mcp] final answer emitted (no tool_calls)"
646+
);
621647
return true;
622648
}
623649
console.warn("[mcp] exceeded tool-followup loops; falling back");

src/lib/stores/mcpServers.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { MCPServer, ServerStatus, MCPTool } from "$lib/types/Tool";
1212

1313
// Namespace storage by app identity to avoid collisions across apps
1414
function toKeyPart(s: string | undefined): string {
15-
return (s || "").toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
15+
return (s || "").toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
1616
}
1717

1818
const appLabel = toKeyPart(publicEnv.PUBLIC_APP_ASSETS || publicEnv.PUBLIC_APP_NAME);
@@ -29,29 +29,29 @@ const STORAGE_KEYS = {
2929

3030
// Load custom servers from localStorage
3131
function loadCustomServers(): MCPServer[] {
32-
if (!browser) return [];
33-
34-
try {
35-
const json = localStorage.getItem(STORAGE_KEYS.CUSTOM_SERVERS);
36-
return json ? JSON.parse(json) : [];
37-
} catch (error) {
38-
console.error("Failed to load custom MCP servers from localStorage:", error);
39-
return [];
40-
}
32+
if (!browser) return [];
33+
34+
try {
35+
const json = localStorage.getItem(STORAGE_KEYS.CUSTOM_SERVERS);
36+
return json ? JSON.parse(json) : [];
37+
} catch (error) {
38+
console.error("Failed to load custom MCP servers from localStorage:", error);
39+
return [];
40+
}
4141
}
4242

4343
// Load selected server IDs from localStorage
4444
function loadSelectedIds(): Set<string> {
45-
if (!browser) return new Set();
46-
47-
try {
48-
const json = localStorage.getItem(STORAGE_KEYS.SELECTED_IDS);
49-
const ids: string[] = json ? JSON.parse(json) : [];
50-
return new Set(ids);
51-
} catch (error) {
52-
console.error("Failed to load selected MCP server IDs from localStorage:", error);
53-
return new Set();
54-
}
45+
if (!browser) return new Set();
46+
47+
try {
48+
const json = localStorage.getItem(STORAGE_KEYS.SELECTED_IDS);
49+
const ids: string[] = json ? JSON.parse(json) : [];
50+
return new Set(ids);
51+
} catch (error) {
52+
console.error("Failed to load selected MCP server IDs from localStorage:", error);
53+
return new Set();
54+
}
5555
}
5656

5757
// Save custom servers to localStorage

src/lib/utils/hf.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Client-safe HF utilities used in UI components
22

33
export function isStrictHfMcpLogin(urlString: string): boolean {
4-
try {
5-
const u = new URL(urlString);
6-
const host = u.hostname.toLowerCase();
7-
const allowedHosts = new Set(["hf.co", "huggingface.co"]);
8-
return (
9-
u.protocol === "https:" &&
10-
allowedHosts.has(host) &&
11-
u.pathname === "/mcp" &&
12-
u.search === "?login"
13-
);
14-
} catch {
15-
return false;
16-
}
4+
try {
5+
const u = new URL(urlString);
6+
const host = u.hostname.toLowerCase();
7+
const allowedHosts = new Set(["hf.co", "huggingface.co"]);
8+
return (
9+
u.protocol === "https:" &&
10+
allowedHosts.has(host) &&
11+
u.pathname === "/mcp" &&
12+
u.search === "?login"
13+
);
14+
} catch {
15+
return false;
16+
}
1717
}

src/routes/api/mcp/servers/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type { MCPServer } from "$lib/types/Tool";
22
import { config } from "$lib/server/config";
33

44
export async function GET() {
5-
// Parse MCP_SERVERS environment variable
6-
const mcpServersEnv = config.MCP_SERVERS || "[]";
5+
// Parse MCP_SERVERS environment variable
6+
const mcpServersEnv = config.MCP_SERVERS || "[]";
77

88
let servers: Array<{ name: string; url: string; headers?: Record<string, string> }> = [];
99

0 commit comments

Comments
 (0)