Skip to content

Commit b62d515

Browse files
Merge pull request #31 from modelcontextprotocol/feature/splash-copy-buttons
feat: add copy buttons to example server URLs on splash page
2 parents 58554ed + c8e22b8 commit b62d515

3 files changed

Lines changed: 75 additions & 7 deletions

File tree

src/index.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,21 @@ async function main() {
238238
const splashPath = path.join(srcStaticDir, 'index.html');
239239
let html = fs.readFileSync(splashPath, 'utf8');
240240

241-
// Inject example server endpoints
242-
const exampleServersHtml = AVAILABLE_EXAMPLES.map(slug => `
243-
<div class="endpoint">
244-
<span class="method post">POST</span>
245-
<span>/${slug}/mcp - ${formatServerName(slug)} MCP App Server</span>
246-
</div>`).join('');
241+
// Inject example server endpoints with copy buttons
242+
const exampleServersHtml = AVAILABLE_EXAMPLES.map(slug => {
243+
const fullUrl = `${config.baseUri}/${slug}/mcp`;
244+
return `
245+
<div class="endpoint endpoint-with-copy">
246+
<div class="endpoint-info">
247+
<span class="method post">POST</span>
248+
<span>/${slug}/mcp - ${formatServerName(slug)} MCP App Server</span>
249+
</div>
250+
<button class="copy-btn" onclick="copyUrl(this, '${fullUrl}')">
251+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
252+
<span class="btn-text">Copy</span>
253+
</button>
254+
</div>`;
255+
}).join('');
247256
html = html.replace('<!-- EXAMPLE_SERVERS_PLACEHOLDER -->', exampleServersHtml);
248257

249258
res.send(html);

src/static/index.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,30 @@ <h2>MCP App Example Servers</h2>
9797

9898
<footer>
9999
<p>
100-
Built by the <a href="https://modelcontextprotocol.io">Model Context Protocol</a> team
100+
Built by the <a href="https://modelcontextprotocol.io">Model Context Protocol</a> team
101101
as a reference implementation for the MCP ecosystem.
102102
</p>
103103
</footer>
104+
105+
<script>
106+
function copyUrl(btn, url) {
107+
// Fallback for non-HTTPS contexts
108+
const textarea = document.createElement('textarea');
109+
textarea.value = url;
110+
textarea.style.position = 'fixed';
111+
textarea.style.opacity = '0';
112+
document.body.appendChild(textarea);
113+
textarea.select();
114+
document.execCommand('copy');
115+
document.body.removeChild(textarea);
116+
117+
btn.classList.add('copied');
118+
btn.querySelector('.btn-text').textContent = 'Copied!';
119+
setTimeout(() => {
120+
btn.classList.remove('copied');
121+
btn.querySelector('.btn-text').textContent = 'Copy';
122+
}, 2000);
123+
}
124+
</script>
104125
</body>
105126
</html>

src/static/styles.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,44 @@ h1 {
117117
gap: 1rem;
118118
}
119119

120+
.endpoint-with-copy {
121+
justify-content: space-between;
122+
}
123+
124+
.endpoint-info {
125+
display: flex;
126+
align-items: center;
127+
gap: 1rem;
128+
flex: 1;
129+
}
130+
131+
.copy-btn {
132+
background: #000000;
133+
color: #ffffff;
134+
border: none;
135+
padding: 0.4rem 0.75rem;
136+
font-family: inherit;
137+
font-size: 0.85rem;
138+
cursor: pointer;
139+
transition: all 0.2s ease;
140+
display: flex;
141+
align-items: center;
142+
gap: 0.4rem;
143+
}
144+
145+
.copy-btn:hover {
146+
background: #333333;
147+
}
148+
149+
.copy-btn.copied {
150+
background: #009900;
151+
}
152+
153+
.copy-btn svg {
154+
width: 14px;
155+
height: 14px;
156+
}
157+
120158
.method {
121159
font-weight: bold;
122160
min-width: 80px;

0 commit comments

Comments
 (0)