Download frontend/components/AdminTabs/mcp/CustomInstallForm.jsx from ruslanmv/gitpilot: direct link, hf CLI and curl.
- Browser
- Download file 3.65 kB
-
https://huggingface.co/spaces/ruslanmv/gitpilot/resolve/main/frontend/components/AdminTabs/mcp/CustomInstallForm.jsx
- Command line
-
hf download hf://spaces/ruslanmv/gitpilot/frontend/components/AdminTabs/mcp/CustomInstallForm.jsx
-
curl -L -o CustomInstallForm.jsx https://huggingface.co/spaces/ruslanmv/gitpilot/resolve/main/frontend/components/AdminTabs/mcp/CustomInstallForm.jsx
3.65 kB
| // frontend/components/AdminTabs/mcp/CustomInstallForm.jsx | |
| // Paste-a-register.json form for installing a custom MCP server. | |
| import React, { useState } from "react"; | |
| const SAMPLE = `{ | |
| "name": "mcp-neo4j-server", | |
| "endpoint": "http://mcp-neo4j-server:8083/mcp", | |
| "description": "Neo4j MCP server for graph schema discovery", | |
| "tags": ["graph", "neo4j"], | |
| "auth": { "type": "bearer", "env": "MCP_NEO4J_SERVER_TOKEN" } | |
| }`; | |
| export default function CustomInstallForm({ onSubmit }) { | |
| const [text, setText] = useState(SAMPLE); | |
| const [err, setErr] = useState(null); | |
| const [submitting, setSubmitting] = useState(false); | |
| const handleSubmit = async () => { | |
| setErr(null); | |
| let parsed; | |
| try { | |
| parsed = JSON.parse(text); | |
| } catch (e) { | |
| setErr("Invalid JSON: " + (e?.message || "")); | |
| return; | |
| } | |
| if (!parsed.name || !parsed.endpoint) { | |
| setErr("register.json must include 'name' and 'endpoint'."); | |
| return; | |
| } | |
| setSubmitting(true); | |
| try { | |
| await onSubmit(parsed); | |
| setText(SAMPLE); | |
| } catch (e) { | |
| setErr(e?.message || "Install failed"); | |
| } finally { | |
| setSubmitting(false); | |
| } | |
| }; | |
| return ( | |
| <div | |
| style={{ | |
| background: "#1a1b26", | |
| border: "1px solid #2a2b36", | |
| borderRadius: "8px", | |
| padding: "20px", | |
| }} | |
| > | |
| <h4 style={{ margin: "0 0 6px 0", color: "#e0e0e7" }}>Install custom server</h4> | |
| <p style={{ margin: "0 0 12px 0", fontSize: "12px", color: "#a0a0b0" }}> | |
| Paste a Context Forge <code>register.json</code>. The server lands | |
| disabled — turn it on from the Installed tab once you have set its | |
| auth token. | |
| </p> | |
| <textarea | |
| value={text} | |
| onChange={(e) => setText(e.target.value)} | |
| rows={12} | |
| spellCheck={false} | |
| aria-label="register.json" | |
| style={{ | |
| width: "100%", | |
| fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", | |
| fontSize: "12px", | |
| background: "#0f1018", | |
| color: "#cdd0d8", | |
| border: "1px solid #2a2b36", | |
| borderRadius: "6px", | |
| padding: "12px", | |
| resize: "vertical", | |
| boxSizing: "border-box", | |
| }} | |
| /> | |
| {err && ( | |
| <div | |
| role="alert" | |
| style={{ | |
| marginTop: "8px", | |
| padding: "8px 12px", | |
| background: "#3a0f0f", | |
| border: "1px solid #5a1f1f", | |
| borderRadius: "6px", | |
| color: "#fca5a5", | |
| fontSize: "12px", | |
| }} | |
| > | |
| {err} | |
| </div> | |
| )} | |
| <div | |
| style={{ | |
| display: "flex", | |
| justifyContent: "flex-end", | |
| gap: "8px", | |
| marginTop: "12px", | |
| }} | |
| > | |
| <button | |
| onClick={() => setText(SAMPLE)} | |
| style={{ | |
| padding: "6px 12px", | |
| background: "transparent", | |
| color: "#cdd0d8", | |
| border: "1px solid #3a3b4a", | |
| borderRadius: "4px", | |
| cursor: "pointer", | |
| fontSize: "12px", | |
| }} | |
| > | |
| Reset | |
| </button> | |
| <button | |
| onClick={handleSubmit} | |
| disabled={submitting} | |
| style={{ | |
| padding: "6px 14px", | |
| background: "#3B82F6", | |
| color: "#fff", | |
| border: "none", | |
| borderRadius: "4px", | |
| cursor: submitting ? "not-allowed" : "pointer", | |
| fontSize: "12px", | |
| fontWeight: 600, | |
| }} | |
| > | |
| {submitting ? "Installing…" : "Install server"} | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| } | |