Skip to content

Commit 24c0190

Browse files
committed
feat: add index.html for mcp-proxy with configuration conversion functionality
1 parent 111b4cf commit 24c0190

File tree

1 file changed

+238
-0
lines changed

1 file changed

+238
-0
lines changed

docs/assets/index.html

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
<!DOCTYPE html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>mcp-proxy</title>
7+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
8+
<style>
9+
.config-area {
10+
height: 500px;
11+
resize: none;
12+
}
13+
14+
.converter-container {
15+
min-height: 80vh;
16+
}
17+
</style>
18+
</head>
19+
<body>
20+
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
21+
<div class="container">
22+
<a class="navbar-brand" href="#">mcp-proxy</a>
23+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
24+
<span class="navbar-toggler-icon"></span>
25+
</button>
26+
<div class="collapse navbar-collapse" id="navbarNav">
27+
<ul class="navbar-nav me-auto">
28+
<li class="nav-item">
29+
<a class="nav-link active" href="#">Home</a>
30+
</li>
31+
<li class="nav-item">
32+
<a class="nav-link" href="https://github.com/TBXark/mcp-proxy" target="_blank">GitHub</a>
33+
</li>
34+
<li class="nav-item">
35+
<a class="nav-link" href="#features">Feature</a>
36+
</li>
37+
</ul>
38+
</div>
39+
</div>
40+
</nav>
41+
<main class="container my-5">
42+
<div class="row mb-5">
43+
<div class="col-12 text-center">
44+
<h1 class="display-4">mcp-proxy</h1>
45+
<p class="lead">An MCP proxy server that aggregates and serves multiple MCP resource servers through a single HTTP server.</p>
46+
</div>
47+
</div>
48+
<div class="row mb-5">
49+
<div class="col-8 offset-2">
50+
<div class="card bg-dark text-white">
51+
<div class="card-header d-flex align-items-center">
52+
<div class="d-flex me-3">
53+
<div class="rounded-circle bg-danger me-2" style="width: 12px; height: 12px;"></div>
54+
<div class="rounded-circle bg-warning me-2" style="width: 12px; height: 12px;"></div>
55+
<div class="rounded-circle bg-success" style="width: 12px; height: 12px;"></div>
56+
</div>
57+
</div>
58+
<div class="card-body p-0">
59+
<pre class="m-0 p-3"
60+
style="font-family: monospace; background-color: #1e1e1e; border-radius: 0 0 0.375rem 0.375rem;">
61+
<code class="text-white"><span class="text-success">$</span> docker run -d -p 9090:9090 -v ./config.json:/config/config.json ghcr.io/tbxark/mcp-proxy:latest
62+
</code></pre>
63+
</div>
64+
</div>
65+
</div>
66+
</div>
67+
<div class="row mb-5">
68+
<div class="col-12 text-center">
69+
<p class="lead">Convert the configuration of <strong>mcp-proxy</strong> to the configuration for Claude.</p>
70+
</div>
71+
</div>
72+
<div class="row converter-container">
73+
<div class="col-md-6">
74+
<div class="card h-100">
75+
<div class="card-header bg-primary text-white">
76+
<h5 class="mb-0">mcp-proxy</h5>
77+
</div>
78+
<div class="card-body">
79+
<textarea id="fromConfig" class="form-control config-area"
80+
placeholder="Paste mcp-proxy configuration..."></textarea>
81+
</div>
82+
<div class="card-footer">
83+
<button id="convertBtn" class="btn btn-primary w-100">convert →</button>
84+
</div>
85+
</div>
86+
</div>
87+
<div class="col-md-6">
88+
<div class="card h-100">
89+
<div class="card-header bg-warning text-white">
90+
<h5 class="mb-0">Claude</h5>
91+
</div>
92+
<div class="card-body">
93+
<textarea id="claudeConfig" class="form-control config-area"
94+
placeholder="The configuration of the converted version will be displayed here...."
95+
readonly></textarea>
96+
</div>
97+
<div class="card-footer">
98+
<button id="copyBtn" class="btn btn-warning w-100">copy</button>
99+
</div>
100+
</div>
101+
</div>
102+
</div>
103+
<div class="row mt-5" id="features">
104+
<div class="col-12">
105+
<h2 class="mb-4">Features</h2>
106+
<div class="accordion" id="featuresAccordion">
107+
<div class="accordion-item">
108+
<h2 class="accordion-header">
109+
<button class="accordion-button" type="button" data-bs-toggle="collapse"
110+
data-bs-target="#feature1">
111+
Proxy Multiple MCP Clients
112+
</button>
113+
</h2>
114+
<div id="feature1" class="accordion-collapse collapse show" data-bs-parent="#featuresAccordion">
115+
<div class="accordion-body">
116+
Connects to multiple MCP resource servers and aggregates their tools and capabilities.
117+
</div>
118+
</div>
119+
</div>
120+
<div class="accordion-item">
121+
<h2 class="accordion-header">
122+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
123+
data-bs-target="#feature2">
124+
SSE Support
125+
</button>
126+
</h2>
127+
<div id="feature2" class="accordion-collapse collapse" data-bs-parent="#featuresAccordion">
128+
<div class="accordion-body">
129+
Provides an SSE (Server-Sent Events) server for real-time updates.
130+
</div>
131+
</div>
132+
</div>
133+
<div class="accordion-item">
134+
<h2 class="accordion-header">
135+
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
136+
data-bs-target="#feature3">
137+
Flexible Configuration
138+
</button>
139+
</h2>
140+
<div id="feature3" class="accordion-collapse collapse" data-bs-parent="#featuresAccordion">
141+
<div class="accordion-body">
142+
Supports multiple client types (stdio, sse or streamable-http) with customizable settings.
143+
</div>
144+
</div>
145+
</div>
146+
</div>
147+
</div>
148+
</div>
149+
</main>
150+
<footer class="bg-dark text-white py-4 mt-5">
151+
<div class="container">
152+
<div class="row">
153+
<div class="col-md-6">
154+
<h5>mcp-proxy</h5>
155+
</div>
156+
<div class="col-md-6 text-md-end">
157+
<a href="https://github.com/TBXark/mcp-proxy" class="text-white me-3" target="_blank">GitHub</a>
158+
<a href="https://github.com/TBXark/mcp-proxy/blob/master/LICENSE" class="text-white" target="_blank">MIT
159+
LICENSE</a>
160+
</div>
161+
</div>
162+
</div>
163+
</footer>
164+
165+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
166+
<script>
167+
document.getElementById('convertBtn').addEventListener('click', function () {
168+
try {
169+
const fromConfig = JSON.parse(document.getElementById('fromConfig').value);
170+
const claudeConfig = convertConfig(fromConfig);
171+
document.getElementById('claudeConfig').value = JSON.stringify(claudeConfig, null, 2);
172+
} catch (e) {
173+
alert('Configuration conversion failed:' + e.message);
174+
}
175+
});
176+
177+
document.getElementById('copyBtn').addEventListener('click', function () {
178+
const claudeConfig = document.getElementById('claudeConfig');
179+
claudeConfig.select();
180+
document.execCommand('copy');
181+
alert('Configuration has been copied to the clipboard.');
182+
});
183+
184+
function convertConfig(fromConfig) {
185+
const claudeConfig = {
186+
mcpServers: {}
187+
};
188+
const options = fromConfig?.mcpProxy?.options ?? {};
189+
const baseURL = fromConfig?.mcpProxy?.baseURL;
190+
const mcpServers = fromConfig?.mcpServers ?? {};
191+
if (!baseURL || !isValidUrl(baseURL)) {
192+
console.error('Invalid or missing baseURL in mcpProxy configuration');
193+
return claudeConfig;
194+
}
195+
try {
196+
const baseUrlObj = new URL(baseURL);
197+
for (const key of Object.keys(mcpServers)) {
198+
const url = new URL(baseUrlObj);
199+
url.pathname = `${url.pathname.replace(/\/+$/, '')}/${key}/sse`.replace(/\/+/g, '/');
200+
const server = {
201+
url: url.toString()
202+
};
203+
const token = mcpServers[key]?.options?.authTokens?.[0] ?? options?.authTokens?.[0];
204+
if (token) {
205+
server.headers = {
206+
Authorization: token
207+
};
208+
}
209+
210+
claudeConfig.mcpServers[key] = server;
211+
}
212+
} catch (error) {
213+
console.error('Error processing URL configuration:', error);
214+
}
215+
216+
return claudeConfig;
217+
}
218+
219+
function isValidUrl(urlString) {
220+
try {
221+
new URL(urlString);
222+
return true;
223+
} catch (error) {
224+
return false;
225+
}
226+
}
227+
228+
async function main() {
229+
const fromConfig = await fetch("https://raw.githubusercontent.com/TBXark/mcp-proxy/refs/heads/master/config.json").then(r => r.text())
230+
document.getElementById('fromConfig').value = fromConfig;
231+
const claudeConfig = convertConfig(JSON.parse(fromConfig));
232+
document.getElementById('claudeConfig').value = JSON.stringify(claudeConfig, null, 2);
233+
}
234+
235+
main().catch(console.error);
236+
</script>
237+
</body>
238+
</html>

0 commit comments

Comments
 (0)