multicorn-shield 1.3.5 → 1.4.0
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/CHANGELOG.md +24 -0
- package/dist/multicorn-proxy.js +132 -37
- package/dist/multicorn-shield.js +131 -36
- package/dist/shield-extension.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
- Bump `version` in `package.json` before publishing to npm.
|
|
11
11
|
|
|
12
|
+
## [1.4.0] - 2026-05-08
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Hosted proxy wizard now prompts for upstream MCP server authentication (header name and value) when the target server requires credentials
|
|
17
|
+
- Helpful examples shown during hosted proxy setup: common MCP server URLs (GitHub, Supabase, Atlassian, Stripe) with links to where to find tokens
|
|
18
|
+
- Upstream auth headers are stored encrypted and forwarded by the proxy to the target MCP server on every request
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Target MCP server URL prompt now shows common examples instead of a generic placeholder
|
|
23
|
+
- "govern" replaced with "control" in all user-facing copy
|
|
24
|
+
- "upstream auth" replaced with "server credentials" in all user-facing copy
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Hosted proxy connections to MCP servers requiring authentication (e.g. GitHub, Supabase) now work end-to-end - previously the proxy forwarded requests without credentials
|
|
29
|
+
|
|
30
|
+
## [1.3.6] - 2026-05-08
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Hosted proxy URLs now embed the API key as a query parameter fallback for MCP clients that don't send static Authorization headers (fixes Cursor, Claude Desktop, and other clients that ignore the headers config during discovery)
|
|
35
|
+
|
|
12
36
|
## [1.3.5] - 2026-05-08
|
|
13
37
|
|
|
14
38
|
### Fixed
|
package/dist/multicorn-proxy.js
CHANGED
|
@@ -1500,8 +1500,8 @@ async function promptProxyConfig(ask, agentName) {
|
|
|
1500
1500
|
while (targetUrl.length === 0) {
|
|
1501
1501
|
process.stderr.write(
|
|
1502
1502
|
"\n" + style.bold("Target MCP server URL:") + "\n" + style.dim(
|
|
1503
|
-
"
|
|
1504
|
-
) + "\n"
|
|
1503
|
+
"This is the URL of the MCP server you want Shield to control. Common examples:"
|
|
1504
|
+
) + "\n" + style.dim(" GitHub: https://api.githubcopilot.com/mcp/") + "\n" + style.dim(" Supabase: https://mcp.supabase.com/sse") + "\n" + style.dim(" Atlassian: https://mcp.atlassian.com/v1/sse") + "\n" + style.dim(" Stripe: https://mcp.stripe.com/v1/sse") + "\n" + style.dim("Check your MCP server's documentation for the correct URL.") + "\n"
|
|
1505
1505
|
);
|
|
1506
1506
|
const input = await ask("URL: ");
|
|
1507
1507
|
if (input.trim().length === 0) {
|
|
@@ -1521,10 +1521,44 @@ async function promptProxyConfig(ask, agentName) {
|
|
|
1521
1521
|
targetUrl = input.trim();
|
|
1522
1522
|
}
|
|
1523
1523
|
const shortName = normalizeAgentName(agentName) || "shield-mcp";
|
|
1524
|
-
|
|
1524
|
+
process.stderr.write(
|
|
1525
|
+
"\n" + style.bold("Does this MCP server require authentication?") + "\n" + style.dim(
|
|
1526
|
+
"Most MCP servers need a token or API key. Check the server's docs for how to get one:"
|
|
1527
|
+
) + "\n" + style.dim(" GitHub: Settings > Developer Settings > Personal Access Tokens") + "\n" + style.dim(
|
|
1528
|
+
" Supabase: Project Settings > API > anon or scoped key (service role bypasses RLS; avoid for most MCP)"
|
|
1529
|
+
) + "\n" + style.dim(" Atlassian: id.atlassian.com > API Tokens") + "\n" + style.dim(" Stripe: Dashboard > Developers > API Keys") + "\n"
|
|
1530
|
+
);
|
|
1531
|
+
const authReply = await ask("(y/N): ");
|
|
1532
|
+
const authNorm = authReply.trim().toLowerCase();
|
|
1533
|
+
const wantsAuth = authNorm === "y" || authNorm === "yes";
|
|
1534
|
+
let upstreamHeaders;
|
|
1535
|
+
if (wantsAuth) {
|
|
1536
|
+
process.stderr.write(
|
|
1537
|
+
"\n" + style.bold("Enter the Authorization header value.") + "\n" + style.dim(" For Bearer tokens: Bearer ghp_xxxxxxxxxxxx") + "\n" + style.dim(" For API keys: Bearer sk-xxxxxxxxxxxx") + "\n"
|
|
1538
|
+
);
|
|
1539
|
+
const headerVal = await ask("Value: ");
|
|
1540
|
+
const trimmed = headerVal.trim();
|
|
1541
|
+
if (trimmed.length > 0) {
|
|
1542
|
+
upstreamHeaders = { Authorization: trimmed };
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
return {
|
|
1546
|
+
targetUrl,
|
|
1547
|
+
shortName,
|
|
1548
|
+
...upstreamHeaders !== void 0 ? { upstreamHeaders } : {}
|
|
1549
|
+
};
|
|
1525
1550
|
}
|
|
1526
|
-
async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform) {
|
|
1551
|
+
async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform, upstreamHeaders) {
|
|
1527
1552
|
let response;
|
|
1553
|
+
const body = {
|
|
1554
|
+
server_name: serverName,
|
|
1555
|
+
target_url: targetUrl,
|
|
1556
|
+
platform,
|
|
1557
|
+
agent_name: agentName
|
|
1558
|
+
};
|
|
1559
|
+
if (upstreamHeaders !== void 0 && Object.keys(upstreamHeaders).length > 0) {
|
|
1560
|
+
body["upstream_headers"] = upstreamHeaders;
|
|
1561
|
+
}
|
|
1528
1562
|
try {
|
|
1529
1563
|
response = await fetch(`${baseUrl}/api/v1/proxy/config`, {
|
|
1530
1564
|
method: "POST",
|
|
@@ -1532,12 +1566,7 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
|
|
|
1532
1566
|
"Content-Type": "application/json",
|
|
1533
1567
|
"X-Multicorn-Key": apiKey
|
|
1534
1568
|
},
|
|
1535
|
-
body: JSON.stringify(
|
|
1536
|
-
server_name: serverName,
|
|
1537
|
-
target_url: targetUrl,
|
|
1538
|
-
platform,
|
|
1539
|
-
agent_name: agentName
|
|
1540
|
-
}),
|
|
1569
|
+
body: JSON.stringify(body),
|
|
1541
1570
|
signal: AbortSignal.timeout(1e4)
|
|
1542
1571
|
});
|
|
1543
1572
|
} catch (error) {
|
|
@@ -1564,6 +1593,41 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
|
|
|
1564
1593
|
const data = envelope["data"];
|
|
1565
1594
|
return typeof data?.["proxy_url"] === "string" ? data["proxy_url"] : "";
|
|
1566
1595
|
}
|
|
1596
|
+
function shouldEmbedKeyInHostedProxyUrl(platform) {
|
|
1597
|
+
return HOSTED_PROXY_PLATFORMS_WITH_URL_KEY.has(platform);
|
|
1598
|
+
}
|
|
1599
|
+
function hostedProxyUrlWithKeyParam(proxyUrl, apiKey) {
|
|
1600
|
+
if (apiKey.length === 0) {
|
|
1601
|
+
process.stderr.write(
|
|
1602
|
+
style.yellow("\u26A0") + " Could not add key to proxy URL: API key is empty; using URL without key query parameter.\n"
|
|
1603
|
+
);
|
|
1604
|
+
return proxyUrl;
|
|
1605
|
+
}
|
|
1606
|
+
try {
|
|
1607
|
+
const u = new URL(proxyUrl);
|
|
1608
|
+
u.searchParams.set("key", apiKey);
|
|
1609
|
+
return u.toString();
|
|
1610
|
+
} catch (err) {
|
|
1611
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1612
|
+
process.stderr.write(
|
|
1613
|
+
style.yellow("\u26A0") + " Could not parse proxy URL to append key query parameter; using URL unchanged. " + style.dim(detail) + "\n"
|
|
1614
|
+
);
|
|
1615
|
+
return proxyUrl;
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
function formatHostedProxyUrlForStderr(platform, proxyUrl, apiKey) {
|
|
1619
|
+
if (!shouldEmbedKeyInHostedProxyUrl(platform) || apiKey.length === 0) {
|
|
1620
|
+
return proxyUrl;
|
|
1621
|
+
}
|
|
1622
|
+
try {
|
|
1623
|
+
const u = new URL(proxyUrl);
|
|
1624
|
+
const redactedLabel = apiKey.length <= 4 ? "****" : `mcs_...${apiKey.slice(-4)}`;
|
|
1625
|
+
u.searchParams.set("key", redactedLabel);
|
|
1626
|
+
return u.toString();
|
|
1627
|
+
} catch {
|
|
1628
|
+
return proxyUrl;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1567
1631
|
function writeMcpAddedLine(shortName, filePath) {
|
|
1568
1632
|
process.stderr.write(
|
|
1569
1633
|
style.green("\u2713") + ' MCP server "' + shortName + '" added to ' + style.cyan(filePath) + "\n"
|
|
@@ -1713,8 +1777,9 @@ function printHostedProxyPostWriteHints(platform, shortName) {
|
|
|
1713
1777
|
}
|
|
1714
1778
|
async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey, workspacePath) {
|
|
1715
1779
|
const authHeader = `Bearer ${apiKey}`;
|
|
1780
|
+
const proxyUrlWithKeyWhenNeeded = shouldEmbedKeyInHostedProxyUrl(platform) ? hostedProxyUrlWithKeyParam(proxyUrl, apiKey) : proxyUrl;
|
|
1716
1781
|
if (platform === "gemini-cli") {
|
|
1717
|
-
await mergeGeminiHostedMcpServersIntoSettings(shortName,
|
|
1782
|
+
await mergeGeminiHostedMcpServersIntoSettings(shortName, proxyUrlWithKeyWhenNeeded, apiKey);
|
|
1718
1783
|
process.stderr.write(
|
|
1719
1784
|
style.dim(
|
|
1720
1785
|
"For project-specific config, copy the mcpServers entry into .gemini/settings.json in your project root. Restart Gemini CLI if it is already running."
|
|
@@ -1739,20 +1804,24 @@ async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey,
|
|
|
1739
1804
|
let result = "parse-error";
|
|
1740
1805
|
if (platform === "cursor") {
|
|
1741
1806
|
result = await mergeMcpServersObjectStyle(getCursorMcpJsonPath(), shortName, {
|
|
1742
|
-
url:
|
|
1807
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1743
1808
|
headers: { Authorization: authHeader }
|
|
1744
1809
|
});
|
|
1745
1810
|
if (result === "parse-error") {
|
|
1746
1811
|
printHostedProxyJsonParseWarning(getCursorMcpJsonPath());
|
|
1747
1812
|
}
|
|
1748
1813
|
} else if (platform === "claude-desktop") {
|
|
1749
|
-
result = await mergeClaudeDesktopHostedMcpRemote(
|
|
1814
|
+
result = await mergeClaudeDesktopHostedMcpRemote(
|
|
1815
|
+
shortName,
|
|
1816
|
+
proxyUrlWithKeyWhenNeeded,
|
|
1817
|
+
apiKey
|
|
1818
|
+
);
|
|
1750
1819
|
if (result === "parse-error") {
|
|
1751
1820
|
printHostedProxyJsonParseWarning(getClaudeDesktopConfigPath());
|
|
1752
1821
|
}
|
|
1753
1822
|
} else if (platform === "windsurf") {
|
|
1754
1823
|
result = await mergeMcpServersObjectStyle(getWindsurfMcpConfigPath(), shortName, {
|
|
1755
|
-
serverUrl:
|
|
1824
|
+
serverUrl: proxyUrlWithKeyWhenNeeded,
|
|
1756
1825
|
headers: { Authorization: authHeader }
|
|
1757
1826
|
});
|
|
1758
1827
|
if (result === "parse-error") {
|
|
@@ -1760,25 +1829,30 @@ async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey,
|
|
|
1760
1829
|
}
|
|
1761
1830
|
} else if (platform === "cline") {
|
|
1762
1831
|
result = await mergeMcpServersObjectStyle(getClineMcpSettingsPath(), shortName, {
|
|
1763
|
-
url:
|
|
1832
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1764
1833
|
headers: { Authorization: authHeader }
|
|
1765
1834
|
});
|
|
1766
1835
|
if (result === "parse-error") {
|
|
1767
1836
|
printHostedProxyJsonParseWarning(getClineMcpSettingsPath());
|
|
1768
1837
|
}
|
|
1769
1838
|
} else if (platform === "kilo-code") {
|
|
1770
|
-
result = await mergeKiloCodeProjectMcp(
|
|
1839
|
+
result = await mergeKiloCodeProjectMcp(
|
|
1840
|
+
workspacePath,
|
|
1841
|
+
shortName,
|
|
1842
|
+
proxyUrlWithKeyWhenNeeded,
|
|
1843
|
+
apiKey
|
|
1844
|
+
);
|
|
1771
1845
|
if (result === "parse-error") {
|
|
1772
1846
|
printHostedProxyJsonParseWarning(join(workspacePath, ".kilocode", "mcp.json"));
|
|
1773
1847
|
}
|
|
1774
1848
|
} else if (platform === "continue-dev") {
|
|
1775
|
-
result = await mergeContinueHostedMcp(shortName,
|
|
1849
|
+
result = await mergeContinueHostedMcp(shortName, proxyUrlWithKeyWhenNeeded, apiKey);
|
|
1776
1850
|
if (result === "parse-error") {
|
|
1777
1851
|
printHostedProxyJsonParseWarning(getContinueConfigJsonPath());
|
|
1778
1852
|
}
|
|
1779
1853
|
} else {
|
|
1780
1854
|
result = await mergeMcpServersObjectStyle(getCursorMcpJsonPath(), shortName, {
|
|
1781
|
-
url:
|
|
1855
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1782
1856
|
headers: { Authorization: authHeader }
|
|
1783
1857
|
});
|
|
1784
1858
|
if (result === "parse-error") {
|
|
@@ -1823,6 +1897,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1823
1897
|
]);
|
|
1824
1898
|
const usesInlineKey = hostedInlinePlatforms.has(platform);
|
|
1825
1899
|
const authHeader = usesInlineKey ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
|
|
1900
|
+
const urlInSnippet = usesInlineKey && shouldEmbedKeyInHostedProxyUrl(platform) ? hostedProxyUrlWithKeyParam(routingToken, apiKey) : routingToken;
|
|
1826
1901
|
let snippetText;
|
|
1827
1902
|
if (platform === "github-copilot") {
|
|
1828
1903
|
snippetText = JSON.stringify(
|
|
@@ -1831,7 +1906,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1831
1906
|
servers: {
|
|
1832
1907
|
[shortName]: {
|
|
1833
1908
|
type: "http",
|
|
1834
|
-
url:
|
|
1909
|
+
url: urlInSnippet,
|
|
1835
1910
|
headers: {
|
|
1836
1911
|
Authorization: authHeader
|
|
1837
1912
|
}
|
|
@@ -1843,13 +1918,13 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1843
1918
|
2
|
|
1844
1919
|
);
|
|
1845
1920
|
} else if (platform === "goose") {
|
|
1846
|
-
snippetText = gooseHostedProxyYaml(shortName,
|
|
1921
|
+
snippetText = gooseHostedProxyYaml(shortName, urlInSnippet, authHeader);
|
|
1847
1922
|
} else if (platform === "gemini-cli") {
|
|
1848
1923
|
snippetText = JSON.stringify(
|
|
1849
1924
|
{
|
|
1850
1925
|
mcpServers: {
|
|
1851
1926
|
[shortName]: {
|
|
1852
|
-
httpUrl:
|
|
1927
|
+
httpUrl: urlInSnippet,
|
|
1853
1928
|
headers: {
|
|
1854
1929
|
Authorization: authHeader
|
|
1855
1930
|
}
|
|
@@ -1865,7 +1940,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1865
1940
|
mcpServers: {
|
|
1866
1941
|
[shortName]: {
|
|
1867
1942
|
command: "npx",
|
|
1868
|
-
args: ["-y", "mcp-remote",
|
|
1943
|
+
args: ["-y", "mcp-remote", urlInSnippet, "--header", `Authorization: ${authHeader}`]
|
|
1869
1944
|
}
|
|
1870
1945
|
}
|
|
1871
1946
|
},
|
|
@@ -1879,7 +1954,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1879
1954
|
{
|
|
1880
1955
|
name: shortName,
|
|
1881
1956
|
type: "streamable-http",
|
|
1882
|
-
url:
|
|
1957
|
+
url: urlInSnippet,
|
|
1883
1958
|
headers: {
|
|
1884
1959
|
Authorization: authHeader
|
|
1885
1960
|
}
|
|
@@ -1895,7 +1970,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1895
1970
|
{
|
|
1896
1971
|
mcpServers: {
|
|
1897
1972
|
[shortName]: {
|
|
1898
|
-
[urlKey]:
|
|
1973
|
+
[urlKey]: urlInSnippet,
|
|
1899
1974
|
headers: {
|
|
1900
1975
|
Authorization: authHeader
|
|
1901
1976
|
}
|
|
@@ -2399,7 +2474,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2399
2474
|
}
|
|
2400
2475
|
}
|
|
2401
2476
|
} else {
|
|
2402
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2477
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2403
2478
|
let proxyUrl = "";
|
|
2404
2479
|
let created = false;
|
|
2405
2480
|
while (!created) {
|
|
@@ -2411,7 +2486,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2411
2486
|
agentName,
|
|
2412
2487
|
targetUrl,
|
|
2413
2488
|
shortName,
|
|
2414
|
-
selectedPlatform
|
|
2489
|
+
selectedPlatform,
|
|
2490
|
+
upstreamHeaders
|
|
2415
2491
|
);
|
|
2416
2492
|
spinner.stop(true, "Proxy config created!");
|
|
2417
2493
|
created = true;
|
|
@@ -2426,7 +2502,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2426
2502
|
}
|
|
2427
2503
|
if (created && proxyUrl.length > 0) {
|
|
2428
2504
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2429
|
-
process.stderr.write(
|
|
2505
|
+
process.stderr.write(
|
|
2506
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2507
|
+
);
|
|
2430
2508
|
await applyHostedProxyMcpConfig(
|
|
2431
2509
|
selectedPlatform,
|
|
2432
2510
|
proxyUrl,
|
|
@@ -2490,7 +2568,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2490
2568
|
}
|
|
2491
2569
|
}
|
|
2492
2570
|
} else {
|
|
2493
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2571
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2494
2572
|
let proxyUrl = "";
|
|
2495
2573
|
let created = false;
|
|
2496
2574
|
while (!created) {
|
|
@@ -2502,7 +2580,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2502
2580
|
agentName,
|
|
2503
2581
|
targetUrl,
|
|
2504
2582
|
shortName,
|
|
2505
|
-
selectedPlatform
|
|
2583
|
+
selectedPlatform,
|
|
2584
|
+
upstreamHeaders
|
|
2506
2585
|
);
|
|
2507
2586
|
spinner.stop(true, "Proxy config created!");
|
|
2508
2587
|
created = true;
|
|
@@ -2517,7 +2596,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2517
2596
|
}
|
|
2518
2597
|
if (created && proxyUrl.length > 0) {
|
|
2519
2598
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2520
|
-
process.stderr.write(
|
|
2599
|
+
process.stderr.write(
|
|
2600
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2601
|
+
);
|
|
2521
2602
|
await applyHostedProxyMcpConfig(
|
|
2522
2603
|
selectedPlatform,
|
|
2523
2604
|
proxyUrl,
|
|
@@ -2575,7 +2656,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2575
2656
|
}
|
|
2576
2657
|
}
|
|
2577
2658
|
} else {
|
|
2578
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2659
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2579
2660
|
let proxyUrl = "";
|
|
2580
2661
|
let created = false;
|
|
2581
2662
|
while (!created) {
|
|
@@ -2587,7 +2668,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2587
2668
|
agentName,
|
|
2588
2669
|
targetUrl,
|
|
2589
2670
|
shortName,
|
|
2590
|
-
selectedPlatform
|
|
2671
|
+
selectedPlatform,
|
|
2672
|
+
upstreamHeaders
|
|
2591
2673
|
);
|
|
2592
2674
|
spinner.stop(true, "Proxy config created!");
|
|
2593
2675
|
created = true;
|
|
@@ -2602,7 +2684,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2602
2684
|
}
|
|
2603
2685
|
if (created && proxyUrl.length > 0) {
|
|
2604
2686
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2605
|
-
process.stderr.write(
|
|
2687
|
+
process.stderr.write(
|
|
2688
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2689
|
+
);
|
|
2606
2690
|
await applyHostedProxyMcpConfig(
|
|
2607
2691
|
selectedPlatform,
|
|
2608
2692
|
proxyUrl,
|
|
@@ -2623,7 +2707,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2623
2707
|
}
|
|
2624
2708
|
}
|
|
2625
2709
|
} else {
|
|
2626
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2710
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2627
2711
|
let proxyUrl = "";
|
|
2628
2712
|
let created = false;
|
|
2629
2713
|
while (!created) {
|
|
@@ -2635,7 +2719,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2635
2719
|
agentName,
|
|
2636
2720
|
targetUrl,
|
|
2637
2721
|
shortName,
|
|
2638
|
-
selectedPlatform
|
|
2722
|
+
selectedPlatform,
|
|
2723
|
+
upstreamHeaders
|
|
2639
2724
|
);
|
|
2640
2725
|
spinner.stop(true, "Proxy config created!");
|
|
2641
2726
|
created = true;
|
|
@@ -2650,7 +2735,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2650
2735
|
}
|
|
2651
2736
|
if (created && proxyUrl.length > 0) {
|
|
2652
2737
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2653
|
-
process.stderr.write(
|
|
2738
|
+
process.stderr.write(
|
|
2739
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2740
|
+
);
|
|
2654
2741
|
await applyHostedProxyMcpConfig(
|
|
2655
2742
|
selectedPlatform,
|
|
2656
2743
|
proxyUrl,
|
|
@@ -2831,7 +2918,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2831
2918
|
}
|
|
2832
2919
|
return lastConfig;
|
|
2833
2920
|
}
|
|
2834
|
-
var SECRET_JSON_FILE_OPTIONS, style, BANNER, NativePluginPrerequisiteMissingError, CONFIG_DIR, CONFIG_PATH, OPENCLAW_CONFIG_PATH, ANSI_PATTERN, OPENCLAW_MIN_VERSION, INIT_WIZARD_PLATFORM_REGISTRY, INIT_WIZARD_MENU_SECTIONS, INIT_WIZARD_SELECTION_MAX, PLATFORM_BY_SELECTION, DEFAULT_SHIELD_API_BASE_URL;
|
|
2921
|
+
var SECRET_JSON_FILE_OPTIONS, style, BANNER, NativePluginPrerequisiteMissingError, CONFIG_DIR, CONFIG_PATH, OPENCLAW_CONFIG_PATH, ANSI_PATTERN, OPENCLAW_MIN_VERSION, INIT_WIZARD_PLATFORM_REGISTRY, INIT_WIZARD_MENU_SECTIONS, INIT_WIZARD_SELECTION_MAX, PLATFORM_BY_SELECTION, HOSTED_PROXY_PLATFORMS_WITH_URL_KEY, DEFAULT_SHIELD_API_BASE_URL;
|
|
2835
2922
|
var init_config = __esm({
|
|
2836
2923
|
"src/proxy/config.ts"() {
|
|
2837
2924
|
init_consent();
|
|
@@ -2922,6 +3009,14 @@ var init_config = __esm({
|
|
|
2922
3009
|
PLATFORM_BY_SELECTION = Object.fromEntries(
|
|
2923
3010
|
INIT_WIZARD_PLATFORM_REGISTRY.map((e, i) => [i + 1, e.slug])
|
|
2924
3011
|
);
|
|
3012
|
+
HOSTED_PROXY_PLATFORMS_WITH_URL_KEY = /* @__PURE__ */ new Set([
|
|
3013
|
+
"cursor",
|
|
3014
|
+
"claude-desktop",
|
|
3015
|
+
"github-copilot",
|
|
3016
|
+
"kilo-code",
|
|
3017
|
+
"continue-dev",
|
|
3018
|
+
"goose"
|
|
3019
|
+
]);
|
|
2925
3020
|
DEFAULT_SHIELD_API_BASE_URL = "https://api.multicorn.ai";
|
|
2926
3021
|
}
|
|
2927
3022
|
});
|
package/dist/multicorn-shield.js
CHANGED
|
@@ -1571,8 +1571,8 @@ async function promptProxyConfig(ask, agentName) {
|
|
|
1571
1571
|
while (targetUrl.length === 0) {
|
|
1572
1572
|
process.stderr.write(
|
|
1573
1573
|
"\n" + style.bold("Target MCP server URL:") + "\n" + style.dim(
|
|
1574
|
-
"
|
|
1575
|
-
) + "\n"
|
|
1574
|
+
"This is the URL of the MCP server you want Shield to control. Common examples:"
|
|
1575
|
+
) + "\n" + style.dim(" GitHub: https://api.githubcopilot.com/mcp/") + "\n" + style.dim(" Supabase: https://mcp.supabase.com/sse") + "\n" + style.dim(" Atlassian: https://mcp.atlassian.com/v1/sse") + "\n" + style.dim(" Stripe: https://mcp.stripe.com/v1/sse") + "\n" + style.dim("Check your MCP server's documentation for the correct URL.") + "\n"
|
|
1576
1576
|
);
|
|
1577
1577
|
const input = await ask("URL: ");
|
|
1578
1578
|
if (input.trim().length === 0) {
|
|
@@ -1592,10 +1592,44 @@ async function promptProxyConfig(ask, agentName) {
|
|
|
1592
1592
|
targetUrl = input.trim();
|
|
1593
1593
|
}
|
|
1594
1594
|
const shortName = normalizeAgentName(agentName) || "shield-mcp";
|
|
1595
|
-
|
|
1595
|
+
process.stderr.write(
|
|
1596
|
+
"\n" + style.bold("Does this MCP server require authentication?") + "\n" + style.dim(
|
|
1597
|
+
"Most MCP servers need a token or API key. Check the server's docs for how to get one:"
|
|
1598
|
+
) + "\n" + style.dim(" GitHub: Settings > Developer Settings > Personal Access Tokens") + "\n" + style.dim(
|
|
1599
|
+
" Supabase: Project Settings > API > anon or scoped key (service role bypasses RLS; avoid for most MCP)"
|
|
1600
|
+
) + "\n" + style.dim(" Atlassian: id.atlassian.com > API Tokens") + "\n" + style.dim(" Stripe: Dashboard > Developers > API Keys") + "\n"
|
|
1601
|
+
);
|
|
1602
|
+
const authReply = await ask("(y/N): ");
|
|
1603
|
+
const authNorm = authReply.trim().toLowerCase();
|
|
1604
|
+
const wantsAuth = authNorm === "y" || authNorm === "yes";
|
|
1605
|
+
let upstreamHeaders;
|
|
1606
|
+
if (wantsAuth) {
|
|
1607
|
+
process.stderr.write(
|
|
1608
|
+
"\n" + style.bold("Enter the Authorization header value.") + "\n" + style.dim(" For Bearer tokens: Bearer ghp_xxxxxxxxxxxx") + "\n" + style.dim(" For API keys: Bearer sk-xxxxxxxxxxxx") + "\n"
|
|
1609
|
+
);
|
|
1610
|
+
const headerVal = await ask("Value: ");
|
|
1611
|
+
const trimmed = headerVal.trim();
|
|
1612
|
+
if (trimmed.length > 0) {
|
|
1613
|
+
upstreamHeaders = { Authorization: trimmed };
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
return {
|
|
1617
|
+
targetUrl,
|
|
1618
|
+
shortName,
|
|
1619
|
+
...upstreamHeaders !== void 0 ? { upstreamHeaders } : {}
|
|
1620
|
+
};
|
|
1596
1621
|
}
|
|
1597
|
-
async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform) {
|
|
1622
|
+
async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverName, platform, upstreamHeaders) {
|
|
1598
1623
|
let response;
|
|
1624
|
+
const body = {
|
|
1625
|
+
server_name: serverName,
|
|
1626
|
+
target_url: targetUrl,
|
|
1627
|
+
platform,
|
|
1628
|
+
agent_name: agentName
|
|
1629
|
+
};
|
|
1630
|
+
if (upstreamHeaders !== void 0 && Object.keys(upstreamHeaders).length > 0) {
|
|
1631
|
+
body["upstream_headers"] = upstreamHeaders;
|
|
1632
|
+
}
|
|
1599
1633
|
try {
|
|
1600
1634
|
response = await fetch(`${baseUrl}/api/v1/proxy/config`, {
|
|
1601
1635
|
method: "POST",
|
|
@@ -1603,12 +1637,7 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
|
|
|
1603
1637
|
"Content-Type": "application/json",
|
|
1604
1638
|
"X-Multicorn-Key": apiKey
|
|
1605
1639
|
},
|
|
1606
|
-
body: JSON.stringify(
|
|
1607
|
-
server_name: serverName,
|
|
1608
|
-
target_url: targetUrl,
|
|
1609
|
-
platform,
|
|
1610
|
-
agent_name: agentName
|
|
1611
|
-
}),
|
|
1640
|
+
body: JSON.stringify(body),
|
|
1612
1641
|
signal: AbortSignal.timeout(1e4)
|
|
1613
1642
|
});
|
|
1614
1643
|
} catch (error) {
|
|
@@ -1635,6 +1664,49 @@ async function createProxyConfig(baseUrl, apiKey, agentName, targetUrl, serverNa
|
|
|
1635
1664
|
const data = envelope["data"];
|
|
1636
1665
|
return typeof data?.["proxy_url"] === "string" ? data["proxy_url"] : "";
|
|
1637
1666
|
}
|
|
1667
|
+
var HOSTED_PROXY_PLATFORMS_WITH_URL_KEY = /* @__PURE__ */ new Set([
|
|
1668
|
+
"cursor",
|
|
1669
|
+
"claude-desktop",
|
|
1670
|
+
"github-copilot",
|
|
1671
|
+
"kilo-code",
|
|
1672
|
+
"continue-dev",
|
|
1673
|
+
"goose"
|
|
1674
|
+
]);
|
|
1675
|
+
function shouldEmbedKeyInHostedProxyUrl(platform) {
|
|
1676
|
+
return HOSTED_PROXY_PLATFORMS_WITH_URL_KEY.has(platform);
|
|
1677
|
+
}
|
|
1678
|
+
function hostedProxyUrlWithKeyParam(proxyUrl, apiKey) {
|
|
1679
|
+
if (apiKey.length === 0) {
|
|
1680
|
+
process.stderr.write(
|
|
1681
|
+
style.yellow("\u26A0") + " Could not add key to proxy URL: API key is empty; using URL without key query parameter.\n"
|
|
1682
|
+
);
|
|
1683
|
+
return proxyUrl;
|
|
1684
|
+
}
|
|
1685
|
+
try {
|
|
1686
|
+
const u = new URL(proxyUrl);
|
|
1687
|
+
u.searchParams.set("key", apiKey);
|
|
1688
|
+
return u.toString();
|
|
1689
|
+
} catch (err) {
|
|
1690
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
1691
|
+
process.stderr.write(
|
|
1692
|
+
style.yellow("\u26A0") + " Could not parse proxy URL to append key query parameter; using URL unchanged. " + style.dim(detail) + "\n"
|
|
1693
|
+
);
|
|
1694
|
+
return proxyUrl;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
function formatHostedProxyUrlForStderr(platform, proxyUrl, apiKey) {
|
|
1698
|
+
if (!shouldEmbedKeyInHostedProxyUrl(platform) || apiKey.length === 0) {
|
|
1699
|
+
return proxyUrl;
|
|
1700
|
+
}
|
|
1701
|
+
try {
|
|
1702
|
+
const u = new URL(proxyUrl);
|
|
1703
|
+
const redactedLabel = apiKey.length <= 4 ? "****" : `mcs_...${apiKey.slice(-4)}`;
|
|
1704
|
+
u.searchParams.set("key", redactedLabel);
|
|
1705
|
+
return u.toString();
|
|
1706
|
+
} catch {
|
|
1707
|
+
return proxyUrl;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1638
1710
|
function writeMcpAddedLine(shortName, filePath) {
|
|
1639
1711
|
process.stderr.write(
|
|
1640
1712
|
style.green("\u2713") + ' MCP server "' + shortName + '" added to ' + style.cyan(filePath) + "\n"
|
|
@@ -1784,8 +1856,9 @@ function printHostedProxyPostWriteHints(platform, shortName) {
|
|
|
1784
1856
|
}
|
|
1785
1857
|
async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey, workspacePath) {
|
|
1786
1858
|
const authHeader = `Bearer ${apiKey}`;
|
|
1859
|
+
const proxyUrlWithKeyWhenNeeded = shouldEmbedKeyInHostedProxyUrl(platform) ? hostedProxyUrlWithKeyParam(proxyUrl, apiKey) : proxyUrl;
|
|
1787
1860
|
if (platform === "gemini-cli") {
|
|
1788
|
-
await mergeGeminiHostedMcpServersIntoSettings(shortName,
|
|
1861
|
+
await mergeGeminiHostedMcpServersIntoSettings(shortName, proxyUrlWithKeyWhenNeeded, apiKey);
|
|
1789
1862
|
process.stderr.write(
|
|
1790
1863
|
style.dim(
|
|
1791
1864
|
"For project-specific config, copy the mcpServers entry into .gemini/settings.json in your project root. Restart Gemini CLI if it is already running."
|
|
@@ -1810,20 +1883,24 @@ async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey,
|
|
|
1810
1883
|
let result = "parse-error";
|
|
1811
1884
|
if (platform === "cursor") {
|
|
1812
1885
|
result = await mergeMcpServersObjectStyle(getCursorMcpJsonPath(), shortName, {
|
|
1813
|
-
url:
|
|
1886
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1814
1887
|
headers: { Authorization: authHeader }
|
|
1815
1888
|
});
|
|
1816
1889
|
if (result === "parse-error") {
|
|
1817
1890
|
printHostedProxyJsonParseWarning(getCursorMcpJsonPath());
|
|
1818
1891
|
}
|
|
1819
1892
|
} else if (platform === "claude-desktop") {
|
|
1820
|
-
result = await mergeClaudeDesktopHostedMcpRemote(
|
|
1893
|
+
result = await mergeClaudeDesktopHostedMcpRemote(
|
|
1894
|
+
shortName,
|
|
1895
|
+
proxyUrlWithKeyWhenNeeded,
|
|
1896
|
+
apiKey
|
|
1897
|
+
);
|
|
1821
1898
|
if (result === "parse-error") {
|
|
1822
1899
|
printHostedProxyJsonParseWarning(getClaudeDesktopConfigPath());
|
|
1823
1900
|
}
|
|
1824
1901
|
} else if (platform === "windsurf") {
|
|
1825
1902
|
result = await mergeMcpServersObjectStyle(getWindsurfMcpConfigPath(), shortName, {
|
|
1826
|
-
serverUrl:
|
|
1903
|
+
serverUrl: proxyUrlWithKeyWhenNeeded,
|
|
1827
1904
|
headers: { Authorization: authHeader }
|
|
1828
1905
|
});
|
|
1829
1906
|
if (result === "parse-error") {
|
|
@@ -1831,25 +1908,30 @@ async function applyHostedProxyMcpConfig(platform, proxyUrl, shortName, apiKey,
|
|
|
1831
1908
|
}
|
|
1832
1909
|
} else if (platform === "cline") {
|
|
1833
1910
|
result = await mergeMcpServersObjectStyle(getClineMcpSettingsPath(), shortName, {
|
|
1834
|
-
url:
|
|
1911
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1835
1912
|
headers: { Authorization: authHeader }
|
|
1836
1913
|
});
|
|
1837
1914
|
if (result === "parse-error") {
|
|
1838
1915
|
printHostedProxyJsonParseWarning(getClineMcpSettingsPath());
|
|
1839
1916
|
}
|
|
1840
1917
|
} else if (platform === "kilo-code") {
|
|
1841
|
-
result = await mergeKiloCodeProjectMcp(
|
|
1918
|
+
result = await mergeKiloCodeProjectMcp(
|
|
1919
|
+
workspacePath,
|
|
1920
|
+
shortName,
|
|
1921
|
+
proxyUrlWithKeyWhenNeeded,
|
|
1922
|
+
apiKey
|
|
1923
|
+
);
|
|
1842
1924
|
if (result === "parse-error") {
|
|
1843
1925
|
printHostedProxyJsonParseWarning(join(workspacePath, ".kilocode", "mcp.json"));
|
|
1844
1926
|
}
|
|
1845
1927
|
} else if (platform === "continue-dev") {
|
|
1846
|
-
result = await mergeContinueHostedMcp(shortName,
|
|
1928
|
+
result = await mergeContinueHostedMcp(shortName, proxyUrlWithKeyWhenNeeded, apiKey);
|
|
1847
1929
|
if (result === "parse-error") {
|
|
1848
1930
|
printHostedProxyJsonParseWarning(getContinueConfigJsonPath());
|
|
1849
1931
|
}
|
|
1850
1932
|
} else {
|
|
1851
1933
|
result = await mergeMcpServersObjectStyle(getCursorMcpJsonPath(), shortName, {
|
|
1852
|
-
url:
|
|
1934
|
+
url: proxyUrlWithKeyWhenNeeded,
|
|
1853
1935
|
headers: { Authorization: authHeader }
|
|
1854
1936
|
});
|
|
1855
1937
|
if (result === "parse-error") {
|
|
@@ -1894,6 +1976,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1894
1976
|
]);
|
|
1895
1977
|
const usesInlineKey = hostedInlinePlatforms.has(platform);
|
|
1896
1978
|
const authHeader = usesInlineKey ? `Bearer ${apiKey}` : "Bearer YOUR_SHIELD_API_KEY";
|
|
1979
|
+
const urlInSnippet = usesInlineKey && shouldEmbedKeyInHostedProxyUrl(platform) ? hostedProxyUrlWithKeyParam(routingToken, apiKey) : routingToken;
|
|
1897
1980
|
let snippetText;
|
|
1898
1981
|
if (platform === "github-copilot") {
|
|
1899
1982
|
snippetText = JSON.stringify(
|
|
@@ -1902,7 +1985,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1902
1985
|
servers: {
|
|
1903
1986
|
[shortName]: {
|
|
1904
1987
|
type: "http",
|
|
1905
|
-
url:
|
|
1988
|
+
url: urlInSnippet,
|
|
1906
1989
|
headers: {
|
|
1907
1990
|
Authorization: authHeader
|
|
1908
1991
|
}
|
|
@@ -1914,13 +1997,13 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1914
1997
|
2
|
|
1915
1998
|
);
|
|
1916
1999
|
} else if (platform === "goose") {
|
|
1917
|
-
snippetText = gooseHostedProxyYaml(shortName,
|
|
2000
|
+
snippetText = gooseHostedProxyYaml(shortName, urlInSnippet, authHeader);
|
|
1918
2001
|
} else if (platform === "gemini-cli") {
|
|
1919
2002
|
snippetText = JSON.stringify(
|
|
1920
2003
|
{
|
|
1921
2004
|
mcpServers: {
|
|
1922
2005
|
[shortName]: {
|
|
1923
|
-
httpUrl:
|
|
2006
|
+
httpUrl: urlInSnippet,
|
|
1924
2007
|
headers: {
|
|
1925
2008
|
Authorization: authHeader
|
|
1926
2009
|
}
|
|
@@ -1936,7 +2019,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1936
2019
|
mcpServers: {
|
|
1937
2020
|
[shortName]: {
|
|
1938
2021
|
command: "npx",
|
|
1939
|
-
args: ["-y", "mcp-remote",
|
|
2022
|
+
args: ["-y", "mcp-remote", urlInSnippet, "--header", `Authorization: ${authHeader}`]
|
|
1940
2023
|
}
|
|
1941
2024
|
}
|
|
1942
2025
|
},
|
|
@@ -1950,7 +2033,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1950
2033
|
{
|
|
1951
2034
|
name: shortName,
|
|
1952
2035
|
type: "streamable-http",
|
|
1953
|
-
url:
|
|
2036
|
+
url: urlInSnippet,
|
|
1954
2037
|
headers: {
|
|
1955
2038
|
Authorization: authHeader
|
|
1956
2039
|
}
|
|
@@ -1966,7 +2049,7 @@ function printPlatformSnippet(platform, routingToken, shortName, apiKey) {
|
|
|
1966
2049
|
{
|
|
1967
2050
|
mcpServers: {
|
|
1968
2051
|
[shortName]: {
|
|
1969
|
-
[urlKey]:
|
|
2052
|
+
[urlKey]: urlInSnippet,
|
|
1970
2053
|
headers: {
|
|
1971
2054
|
Authorization: authHeader
|
|
1972
2055
|
}
|
|
@@ -2471,7 +2554,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2471
2554
|
}
|
|
2472
2555
|
}
|
|
2473
2556
|
} else {
|
|
2474
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2557
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2475
2558
|
let proxyUrl = "";
|
|
2476
2559
|
let created = false;
|
|
2477
2560
|
while (!created) {
|
|
@@ -2483,7 +2566,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2483
2566
|
agentName,
|
|
2484
2567
|
targetUrl,
|
|
2485
2568
|
shortName,
|
|
2486
|
-
selectedPlatform
|
|
2569
|
+
selectedPlatform,
|
|
2570
|
+
upstreamHeaders
|
|
2487
2571
|
);
|
|
2488
2572
|
spinner.stop(true, "Proxy config created!");
|
|
2489
2573
|
created = true;
|
|
@@ -2498,7 +2582,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2498
2582
|
}
|
|
2499
2583
|
if (created && proxyUrl.length > 0) {
|
|
2500
2584
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2501
|
-
process.stderr.write(
|
|
2585
|
+
process.stderr.write(
|
|
2586
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2587
|
+
);
|
|
2502
2588
|
await applyHostedProxyMcpConfig(
|
|
2503
2589
|
selectedPlatform,
|
|
2504
2590
|
proxyUrl,
|
|
@@ -2562,7 +2648,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2562
2648
|
}
|
|
2563
2649
|
}
|
|
2564
2650
|
} else {
|
|
2565
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2651
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2566
2652
|
let proxyUrl = "";
|
|
2567
2653
|
let created = false;
|
|
2568
2654
|
while (!created) {
|
|
@@ -2574,7 +2660,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2574
2660
|
agentName,
|
|
2575
2661
|
targetUrl,
|
|
2576
2662
|
shortName,
|
|
2577
|
-
selectedPlatform
|
|
2663
|
+
selectedPlatform,
|
|
2664
|
+
upstreamHeaders
|
|
2578
2665
|
);
|
|
2579
2666
|
spinner.stop(true, "Proxy config created!");
|
|
2580
2667
|
created = true;
|
|
@@ -2589,7 +2676,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2589
2676
|
}
|
|
2590
2677
|
if (created && proxyUrl.length > 0) {
|
|
2591
2678
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2592
|
-
process.stderr.write(
|
|
2679
|
+
process.stderr.write(
|
|
2680
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2681
|
+
);
|
|
2593
2682
|
await applyHostedProxyMcpConfig(
|
|
2594
2683
|
selectedPlatform,
|
|
2595
2684
|
proxyUrl,
|
|
@@ -2647,7 +2736,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2647
2736
|
}
|
|
2648
2737
|
}
|
|
2649
2738
|
} else {
|
|
2650
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2739
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2651
2740
|
let proxyUrl = "";
|
|
2652
2741
|
let created = false;
|
|
2653
2742
|
while (!created) {
|
|
@@ -2659,7 +2748,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2659
2748
|
agentName,
|
|
2660
2749
|
targetUrl,
|
|
2661
2750
|
shortName,
|
|
2662
|
-
selectedPlatform
|
|
2751
|
+
selectedPlatform,
|
|
2752
|
+
upstreamHeaders
|
|
2663
2753
|
);
|
|
2664
2754
|
spinner.stop(true, "Proxy config created!");
|
|
2665
2755
|
created = true;
|
|
@@ -2674,7 +2764,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2674
2764
|
}
|
|
2675
2765
|
if (created && proxyUrl.length > 0) {
|
|
2676
2766
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2677
|
-
process.stderr.write(
|
|
2767
|
+
process.stderr.write(
|
|
2768
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2769
|
+
);
|
|
2678
2770
|
await applyHostedProxyMcpConfig(
|
|
2679
2771
|
selectedPlatform,
|
|
2680
2772
|
proxyUrl,
|
|
@@ -2695,7 +2787,7 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2695
2787
|
}
|
|
2696
2788
|
}
|
|
2697
2789
|
} else {
|
|
2698
|
-
const { targetUrl, shortName } = await promptProxyConfig(ask, agentName);
|
|
2790
|
+
const { targetUrl, shortName, upstreamHeaders } = await promptProxyConfig(ask, agentName);
|
|
2699
2791
|
let proxyUrl = "";
|
|
2700
2792
|
let created = false;
|
|
2701
2793
|
while (!created) {
|
|
@@ -2707,7 +2799,8 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2707
2799
|
agentName,
|
|
2708
2800
|
targetUrl,
|
|
2709
2801
|
shortName,
|
|
2710
|
-
selectedPlatform
|
|
2802
|
+
selectedPlatform,
|
|
2803
|
+
upstreamHeaders
|
|
2711
2804
|
);
|
|
2712
2805
|
spinner.stop(true, "Proxy config created!");
|
|
2713
2806
|
created = true;
|
|
@@ -2722,7 +2815,9 @@ You have ${String(agentsForPlatform.length)} agent(s) connected for ${selectedLa
|
|
|
2722
2815
|
}
|
|
2723
2816
|
if (created && proxyUrl.length > 0) {
|
|
2724
2817
|
process.stderr.write("\n" + style.bold("Your Shield proxy URL:") + "\n");
|
|
2725
|
-
process.stderr.write(
|
|
2818
|
+
process.stderr.write(
|
|
2819
|
+
" " + style.cyan(formatHostedProxyUrlForStderr(selectedPlatform, proxyUrl, apiKey)) + "\n"
|
|
2820
|
+
);
|
|
2726
2821
|
await applyHostedProxyMcpConfig(
|
|
2727
2822
|
selectedPlatform,
|
|
2728
2823
|
proxyUrl,
|
package/dist/shield-extension.js
CHANGED
|
@@ -22417,7 +22417,7 @@ async function writeExtensionBackup(claudeDesktopConfigPath, mcpServers) {
|
|
|
22417
22417
|
|
|
22418
22418
|
// package.json
|
|
22419
22419
|
var package_default = {
|
|
22420
|
-
version: "1.
|
|
22420
|
+
version: "1.4.0"};
|
|
22421
22421
|
|
|
22422
22422
|
// src/package-meta.ts
|
|
22423
22423
|
var PACKAGE_VERSION = package_default.version;
|
package/package.json
CHANGED