]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
server: wrap headers for mcp proxy (#21072)
authorXuan-Son Nguyen <redacted>
Mon, 30 Mar 2026 06:59:16 +0000 (08:59 +0200)
committerGitHub <redacted>
Mon, 30 Mar 2026 06:59:16 +0000 (08:59 +0200)
* server: wrap headers for mcp proxy

* Update tools/server/server-cors-proxy.h

Co-authored-by: Georgi Gerganov <redacted>
* fix build

* chore: update webui build output

* chore: update webui build output

---------

Co-authored-by: Georgi Gerganov <redacted>
Co-authored-by: Aleksander Grygier <redacted>
tools/server/public/index.html.gz
tools/server/server-cors-proxy.h
tools/server/server-http.h
tools/server/webui/src/lib/services/mcp.service.ts
tools/server/webui/src/lib/utils/cors-proxy.ts
tools/server/webui/src/lib/utils/index.ts

index ffeed79ff7064764fa59591a0150d9842ee40df6..bc9124dd1cec96b2cd2ea12f144fd33f62c78ecf 100644 (file)
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
index c412d4c252339368f2a450ebb848fe491b70d173..ffdd073b9d818bd9e45d20f376897d6332e343f7 100644 (file)
@@ -32,13 +32,22 @@ static server_http_res_ptr proxy_request(const server_http_req & req, std::strin
 
     SRV_INF("proxying %s request to %s://%s:%i%s\n", method.c_str(), parsed_url.scheme.c_str(), parsed_url.host.c_str(), parsed_url.port, parsed_url.path.c_str());
 
+    std::map<std::string, std::string> headers;
+    for (auto [key, value] : req.headers) {
+        auto new_key = key;
+        if (string_starts_with(new_key, "X-Proxy-Header-")) {
+            string_replace_all(new_key, "X-Proxy-Header-", "");
+        }
+        headers[new_key] = value;
+    }
+
     auto proxy = std::make_unique<server_http_proxy>(
             method,
             parsed_url.scheme,
             parsed_url.host,
             parsed_url.port,
             parsed_url.path,
-            req.headers,
+            headers,
             req.body,
             req.should_stop,
             600, // timeout_read (default to 10 minutes)
index 3621064cdf30476f36e5738e4a249e3f78ce36ff..f8a174c4409a1e21344848e4d481e8a09e7f7bb5 100644 (file)
@@ -35,7 +35,7 @@ using server_http_res_ptr = std::unique_ptr<server_http_res>;
 
 struct server_http_req {
     std::map<std::string, std::string> params; // path_params + query_params
-    std::map<std::string, std::string> headers; // reserved for future use
+    std::map<std::string, std::string> headers; // used by MCP proxy
     std::string path;
     std::string query_string; // query parameters string (e.g. "action=save")
     std::string body;
index b38d18676d5243e3db23f13e7a633b23d5ffc6ca..cf401bc30e3ab046819c6295d032baf4bd81cc86 100644 (file)
@@ -39,7 +39,13 @@ import type {
        MCPResourceContent,
        MCPReadResourceResult
 } from '$lib/types';
-import { buildProxiedUrl, throwIfAborted, isAbortError, createBase64DataUrl } from '$lib/utils';
+import {
+       buildProxiedUrl,
+       buildProxiedHeaders,
+       throwIfAborted,
+       isAbortError,
+       createBase64DataUrl
+} from '$lib/utils';
 
 interface ToolResultContentItem {
        type: string;
@@ -118,7 +124,7 @@ export class MCPService {
                const requestInit: RequestInit = {};
 
                if (config.headers) {
-                       requestInit.headers = config.headers;
+                       requestInit.headers = buildProxiedHeaders(config.headers);
                }
 
                if (config.credentials) {
index 39c368ba0beb8967c459492bd7dace06b8e0338b..2eb10b16d447910595e4455f56f518fe431fe37c 100644 (file)
@@ -19,6 +19,21 @@ export function buildProxiedUrl(targetUrl: string): URL {
        return proxyUrl;
 }
 
+/**
+ * Wrap original headers for proxying through the CORS proxy. This avoids issues with duplicated llama.cpp-specific and target headers when using the CORS proxy.
+ * @param headers - The original headers to be proxied to target
+ * @returns List of "wrapped" headers to be sent to the CORS proxy
+ */
+export function buildProxiedHeaders(headers: Record<string, string>): Record<string, string> {
+       const proxiedHeaders: Record<string, string> = {};
+
+       for (const [key, value] of Object.entries(headers)) {
+               proxiedHeaders[`X-Proxy-Header-${key}`] = value;
+       }
+
+       return proxiedHeaders;
+}
+
 /**
  * Get a proxied URL string for use in fetch requests.
  * @param targetUrl - The original URL to proxy
index 2caaf9ac3b377d8df7a045e943a41b9c6c916a24..e3bf1b9f5f34d365abed0312a750f306b15e4207 100644 (file)
@@ -38,7 +38,7 @@ export { highlightCode, detectIncompleteCodeBlock, type IncompleteCodeBlock } fr
 export { setConfigValue, getConfigValue, configToParameterRecord } from './config-helpers';
 
 // CORS Proxy
-export { buildProxiedUrl, getProxiedUrlString } from './cors-proxy';
+export { buildProxiedUrl, getProxiedUrlString, buildProxiedHeaders } from './cors-proxy';
 
 // Conversation utilities
 export { createMessageCountMap, getMessageCount } from './conversation-utils';