|
7 | 7 | ListToolsRequestSchema, |
8 | 8 | Tool, |
9 | 9 | } from "@modelcontextprotocol/sdk/types.js"; |
| 10 | +import { fetch as undiciFetch, ProxyAgent } from "undici"; |
10 | 11 |
|
11 | 12 | /** |
12 | 13 | * Definition of the Perplexity Ask Tool. |
@@ -169,6 +170,45 @@ if (!PERPLEXITY_API_KEY) { |
169 | 170 | process.exit(1); |
170 | 171 | } |
171 | 172 |
|
| 173 | +/** |
| 174 | + * Gets the proxy URL from environment variables. |
| 175 | + * Checks PERPLEXITY_PROXY, HTTPS_PROXY, HTTP_PROXY in order. |
| 176 | + * |
| 177 | + * @returns {string | undefined} The proxy URL if configured, undefined otherwise |
| 178 | + */ |
| 179 | +function getProxyUrl(): string | undefined { |
| 180 | + return process.env.PERPLEXITY_PROXY || |
| 181 | + process.env.HTTPS_PROXY || |
| 182 | + process.env.HTTP_PROXY || |
| 183 | + undefined; |
| 184 | +} |
| 185 | + |
| 186 | +/** |
| 187 | + * Creates a proxy-aware fetch function. |
| 188 | + * Uses undici with ProxyAgent when a proxy is configured, otherwise uses native fetch. |
| 189 | + * |
| 190 | + * @param {string} url - The URL to fetch |
| 191 | + * @param {RequestInit} options - Fetch options |
| 192 | + * @returns {Promise<Response>} The fetch response |
| 193 | + */ |
| 194 | +async function proxyAwareFetch(url: string, options: RequestInit = {}): Promise<Response> { |
| 195 | + const proxyUrl = getProxyUrl(); |
| 196 | + |
| 197 | + if (proxyUrl) { |
| 198 | + // Use undici with ProxyAgent when proxy is configured |
| 199 | + const proxyAgent = new ProxyAgent(proxyUrl); |
| 200 | + const response = await undiciFetch(url, { |
| 201 | + ...options, |
| 202 | + dispatcher: proxyAgent, |
| 203 | + } as any); |
| 204 | + // Cast to native Response type for compatibility |
| 205 | + return response as unknown as Response; |
| 206 | + } else { |
| 207 | + // Use native fetch when no proxy is configured |
| 208 | + return fetch(url, options); |
| 209 | + } |
| 210 | +} |
| 211 | + |
172 | 212 | /** |
173 | 213 | * Validates an array of message objects for chat completion tools. |
174 | 214 | * Ensures each message has a valid role and content field. |
@@ -240,7 +280,7 @@ export async function performChatCompletion( |
240 | 280 |
|
241 | 281 | let response; |
242 | 282 | try { |
243 | | - response = await fetch(url.toString(), { |
| 283 | + response = await proxyAwareFetch(url.toString(), { |
244 | 284 | method: "POST", |
245 | 285 | headers: { |
246 | 286 | "Content-Type": "application/json", |
@@ -371,7 +411,7 @@ export async function performSearch( |
371 | 411 |
|
372 | 412 | let response; |
373 | 413 | try { |
374 | | - response = await fetch(url.toString(), { |
| 414 | + response = await proxyAwareFetch(url.toString(), { |
375 | 415 | method: "POST", |
376 | 416 | headers: { |
377 | 417 | "Content-Type": "application/json", |
|
0 commit comments