@remcp/remcp 0.1.2 → 0.1.3
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/README.md +5 -7
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/public/app.js +25 -24
- package/public/authorize.html +9 -20
- package/public/copy.js +9 -18
- package/public/docs.html +31 -32
- package/public/index.html +38 -58
- package/public/oauth-app.js +22 -13
- package/public/privacy.html +34 -14
- package/public/security.html +25 -12
- package/public/style.css +34 -32
- package/public/support.html +30 -14
- package/public/terms.html +31 -14
package/README.md
CHANGED
|
@@ -11,17 +11,15 @@ ReMCP is an open-source remote MCP bridge for computers you control. A lightweig
|
|
|
11
11
|
|
|
12
12
|
Requires Node.js 22.5 or newer.
|
|
13
13
|
|
|
14
|
-
1.
|
|
15
|
-
2. Run it on the computer you want to connect:
|
|
14
|
+
1. Install the CLI:
|
|
16
15
|
|
|
17
16
|
```bash
|
|
18
|
-
|
|
19
|
-
--server https://remcp.delio24.com \
|
|
20
|
-
--code YOUR_PAIRING_CODE \
|
|
21
|
-
--install
|
|
17
|
+
npm install --global @remcp/remcp@latest
|
|
22
18
|
```
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
2. Open <https://remcp.delio24.com/#connect>, sign in with Google or GitHub, and choose **Generate pairing command**. Run the exact generated command on the computer you want to pair.
|
|
21
|
+
|
|
22
|
+
3. Verify:
|
|
25
23
|
|
|
26
24
|
```bash
|
|
27
25
|
remcp --version
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "remcp",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"description": "Securely use files, directories, searches, terminal sessions, and processes on computers you have paired with ReMCP.",
|
|
6
6
|
"homepage": "https://remcp.delio24.com",
|
|
7
7
|
"repository": "https://github.com/antonbaider/remcp",
|
package/public/app.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-app.js';
|
|
2
|
-
import { getAuth, GoogleAuthProvider, onAuthStateChanged, signInWithPopup,
|
|
2
|
+
import { getAuth, GoogleAuthProvider, GithubAuthProvider, onAuthStateChanged, signInWithPopup, signOut } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-auth.js';
|
|
3
3
|
|
|
4
4
|
const cfg = await fetch(`/api/config?fresh=${Date.now()}`, { cache: 'no-store' }).then(r => r.json());
|
|
5
5
|
const auth = getAuth(initializeApp(cfg.firebase));
|
|
6
6
|
const $ = selector => document.querySelector(selector);
|
|
7
|
-
const showError = error => { $('#auth-error').textContent = error?.message || String(error); };
|
|
8
7
|
const googleProvider = new GoogleAuthProvider();
|
|
8
|
+
const githubProvider = new GithubAuthProvider();
|
|
9
|
+
googleProvider.setCustomParameters({ prompt: 'select_account' });
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const friendlyAuthError = error => {
|
|
12
|
+
const code = error?.code || '';
|
|
13
|
+
if (code === 'auth/popup-closed-by-user' || code === 'auth/cancelled-popup-request') return '';
|
|
14
|
+
if (code === 'auth/account-exists-with-different-credential') return 'This email is already linked to another sign-in provider.';
|
|
15
|
+
if (code === 'auth/operation-not-allowed') return 'This sign-in provider is not enabled.';
|
|
16
|
+
return error?.message || String(error);
|
|
17
|
+
};
|
|
18
|
+
const showError = error => { $('#auth-error').textContent = friendlyAuthError(error); };
|
|
19
|
+
|
|
20
|
+
async function signIn(button, provider, idleLabel) {
|
|
13
21
|
const label = button.querySelector('span');
|
|
14
22
|
button.disabled = true;
|
|
15
23
|
$('#auth-error').textContent = '';
|
|
16
|
-
label.textContent = 'Opening
|
|
17
|
-
try { await signInWithPopup(auth,
|
|
24
|
+
label.textContent = 'Opening…';
|
|
25
|
+
try { await signInWithPopup(auth, provider); }
|
|
18
26
|
catch (error) { showError(error); }
|
|
19
|
-
finally { button.disabled = false; label.textContent =
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
$('#
|
|
27
|
+
finally { button.disabled = false; label.textContent = idleLabel; }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
$('#mcp-url').textContent = cfg.mcpUrl;
|
|
31
|
+
$('#google').onclick = () => signIn($('#google'), googleProvider, 'Continue with Google');
|
|
32
|
+
$('#github').onclick = () => signIn($('#github'), githubProvider, 'Continue with GitHub');
|
|
23
33
|
$('#logout').onclick = () => signOut(auth);
|
|
24
34
|
|
|
25
|
-
document.addEventListener('click', async event => {
|
|
26
|
-
const button = event.target.closest('[data-copy]');
|
|
27
|
-
if (!button) return;
|
|
28
|
-
const target = document.querySelector(button.dataset.copy);
|
|
29
|
-
if (!target) return;
|
|
30
|
-
await navigator.clipboard.writeText(target.textContent.trim());
|
|
31
|
-
const original = button.textContent;
|
|
32
|
-
button.textContent = 'Copied';
|
|
33
|
-
setTimeout(() => { button.textContent = original; }, 1200);
|
|
34
|
-
});
|
|
35
35
|
async function api(path, options = {}) {
|
|
36
36
|
const token = await auth.currentUser.getIdToken();
|
|
37
37
|
const response = await fetch(path, { ...options, headers: { ...(options.headers || {}), authorization: `Bearer ${token}`, 'content-type': 'application/json' } });
|
|
@@ -70,16 +70,17 @@ async function refreshDevices() {
|
|
|
70
70
|
const data = await api('/api/me');
|
|
71
71
|
const root = $('#devices');
|
|
72
72
|
root.replaceChildren();
|
|
73
|
-
if (!data.devices.length) { root.textContent = 'No devices
|
|
73
|
+
if (!data.devices.length) { root.textContent = 'No paired devices.'; return; }
|
|
74
74
|
for (const device of data.devices) root.append(deviceRow(device));
|
|
75
75
|
}
|
|
76
|
+
|
|
76
77
|
$('#pair').onclick = async () => {
|
|
77
78
|
try {
|
|
78
79
|
const pairing = await api('/api/pair/create', { method: 'POST', body: '{}' });
|
|
79
80
|
$('#pairing').classList.remove('hidden');
|
|
80
81
|
$('#pair-command').textContent = pairing.command;
|
|
81
82
|
const expiry = new Intl.DateTimeFormat(undefined, { hour: 'numeric', minute: '2-digit' }).format(new Date(pairing.expiresAt));
|
|
82
|
-
$('#pair-expiry').textContent = `
|
|
83
|
+
$('#pair-expiry').textContent = `One-time command · expires ${expiry}`;
|
|
83
84
|
} catch (error) { showError(error); }
|
|
84
85
|
};
|
|
85
86
|
|
|
@@ -90,6 +91,6 @@ onAuthStateChanged(auth, async user => {
|
|
|
90
91
|
$('#dashboard').classList.toggle('hidden', !signedIn);
|
|
91
92
|
$('#auth-error').textContent = '';
|
|
92
93
|
if (!signedIn) return;
|
|
93
|
-
$('#user-label').textContent = user.email || user.uid;
|
|
94
|
+
$('#user-label').textContent = user.email || user.displayName || user.uid;
|
|
94
95
|
try { await refreshDevices(); } catch (error) { showError(error); }
|
|
95
96
|
});
|
package/public/authorize.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Authorize · ReMCP</title>
|
|
9
9
|
<meta name="description" content="Authorize an MCP client to access computers paired to your ReMCP account.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,29 +28,18 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="oauth-main" class="oauth-shell">
|
|
34
34
|
<section class="oauth-card">
|
|
35
35
|
<div id="oauth-login">
|
|
36
36
|
<p class="eyebrow">Secure authorization</p>
|
|
37
37
|
<h2 id="oauth-title">Sign in to ReMCP</h2>
|
|
38
|
-
<p class="muted">
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<path fill="#FBBC05" d="M3.963 10.705A5.41 5.41 0 0 1 3.682 9c0-.592.102-1.168.281-1.705V4.963H.956A9 9 0 0 0 0 9c0 1.452.347 2.827.956 4.037l3.007-2.332Z"/>
|
|
44
|
-
<path fill="#EA4335" d="M9 3.581c1.321 0 2.507.454 3.441 1.346l2.581-2.581C13.464.892 11.426 0 9 0A9 9 0 0 0 .956 4.963l3.007 2.332C4.672 5.166 6.656 3.581 9 3.581Z"/>
|
|
45
|
-
</svg>
|
|
46
|
-
<span>Continue with Google</span>
|
|
47
|
-
</button>
|
|
48
|
-
<div class="divider"><span>or use email</span></div>
|
|
49
|
-
<label for="email">Email</label>
|
|
50
|
-
<input id="email" name="email" type="email" autocomplete="email" inputmode="email" autocapitalize="none" spellcheck="false">
|
|
51
|
-
<label for="password">Password</label>
|
|
52
|
-
<input id="password" name="password" type="password" autocomplete="current-password">
|
|
53
|
-
<div class="button-row"><button id="email-login" class="button secondary" type="button">Sign In</button><button id="email-register" class="button ghost" type="button">Create Account</button></div>
|
|
38
|
+
<p class="muted">Continue with Google or GitHub, then review the MCP client’s access request.</p>
|
|
39
|
+
<div class="provider-stack">
|
|
40
|
+
<button id="google" class="provider-button google-button" type="button"><svg class="provider-icon" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.205c0-.638-.057-1.252-.164-1.841H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.715v2.259h2.909c1.702-1.567 2.683-3.874 2.683-6.614Z"/><path fill="#34A853" d="M9 18c2.43 0 4.468-.806 5.957-2.181l-2.909-2.259c-.806.54-1.835.859-3.048.859-2.344 0-4.328-1.585-5.037-3.714H.956v2.332A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.963 10.705A5.41 5.41 0 0 1 3.682 9c0-.592.102-1.168.281-1.705V4.963H.956A9 9 0 0 0 0 9c0 1.452.347 2.827.956 4.037l3.007-2.332Z"/><path fill="#EA4335" d="M9 3.581c1.321 0 2.507.454 3.441 1.346l2.581-2.581C13.464.892 11.426 0 9 0A9 9 0 0 0 .956 4.963l3.007 2.332C4.672 5.166 6.656 3.581 9 3.581Z"/></svg><span>Continue with Google</span></button>
|
|
41
|
+
<button id="github" class="provider-button github-button" type="button"><svg class="provider-icon" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 .7a11.5 11.5 0 0 0-3.64 22.41c.58.11.79-.25.79-.56v-2.24c-3.22.7-3.9-1.37-3.9-1.37-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.71.08-.71 1.16.08 1.77 1.19 1.77 1.19 1.04 1.77 2.72 1.26 3.38.96.1-.75.4-1.26.73-1.55-2.57-.29-5.27-1.29-5.27-5.68 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.16 1.18a10.9 10.9 0 0 1 5.76 0c2.19-1.49 3.16-1.18 3.16-1.18.63 1.59.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.4-2.71 5.38-5.29 5.67.42.36.79 1.07.79 2.16v3.21c0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .7Z"/></svg><span>Continue with GitHub</span></button>
|
|
42
|
+
</div>
|
|
54
43
|
</div>
|
|
55
44
|
<div id="oauth-consent" class="hidden">
|
|
56
45
|
<p class="eyebrow">Access request</p>
|
|
@@ -62,9 +51,9 @@
|
|
|
62
51
|
</div>
|
|
63
52
|
<p id="status" class="muted" aria-live="polite"></p>
|
|
64
53
|
<p id="error" class="error" role="alert" aria-live="assertive"></p>
|
|
65
|
-
<p class="footer-mini"><a href="/docs">Docs</a> · <a href="/
|
|
54
|
+
<p class="footer-mini"><a href="/docs">Docs</a> · <a href="/security">Security</a> · <a href="/privacy">Privacy</a> · <a href="/terms">Terms</a></p>
|
|
66
55
|
</section>
|
|
67
56
|
</main>
|
|
68
|
-
<script type="module" src="/oauth-app.js?v=
|
|
57
|
+
<script type="module" src="/oauth-app.js?v=remcp-013"></script>
|
|
69
58
|
</body>
|
|
70
59
|
</html>
|
package/public/copy.js
CHANGED
|
@@ -14,13 +14,7 @@ function legacyCopy(text) {
|
|
|
14
14
|
|
|
15
15
|
async function copyText(text) {
|
|
16
16
|
if (window.isSecureContext && navigator.clipboard?.writeText) {
|
|
17
|
-
try {
|
|
18
|
-
await navigator.clipboard.writeText(text);
|
|
19
|
-
return;
|
|
20
|
-
} catch {
|
|
21
|
-
legacyCopy(text);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
17
|
+
try { await navigator.clipboard.writeText(text); return; } catch {}
|
|
24
18
|
}
|
|
25
19
|
legacyCopy(text);
|
|
26
20
|
}
|
|
@@ -30,20 +24,17 @@ document.addEventListener('click', async event => {
|
|
|
30
24
|
if (!button) return;
|
|
31
25
|
const target = document.querySelector(button.dataset.copy);
|
|
32
26
|
if (!target) return;
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const originalLabel = button.getAttribute('aria-label') || 'Copy command';
|
|
27
|
+
const text = ('value' in target ? target.value : target.textContent).trim();
|
|
28
|
+
const label = button.getAttribute('aria-label') || 'Copy';
|
|
36
29
|
try {
|
|
37
|
-
await copyText(
|
|
38
|
-
button.
|
|
39
|
-
button.setAttribute('aria-label', 'Copied
|
|
30
|
+
await copyText(text);
|
|
31
|
+
button.dataset.copied = 'true';
|
|
32
|
+
button.setAttribute('aria-label', 'Copied');
|
|
40
33
|
} catch {
|
|
41
|
-
button.
|
|
42
|
-
button.setAttribute('aria-label', 'Copy failed. Select the command manually.');
|
|
34
|
+
button.setAttribute('aria-label', 'Copy failed');
|
|
43
35
|
}
|
|
44
|
-
|
|
45
36
|
window.setTimeout(() => {
|
|
46
|
-
button.
|
|
47
|
-
button.setAttribute('aria-label',
|
|
37
|
+
delete button.dataset.copied;
|
|
38
|
+
button.setAttribute('aria-label', label);
|
|
48
39
|
}, 1400);
|
|
49
40
|
});
|
package/public/docs.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Docs · ReMCP</title>
|
|
9
9
|
<meta name="description" content="Connect a computer to ReMCP and configure the hosted MCP endpoint.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,57 +28,56 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs" aria-current="page">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs" aria-current="page">Docs</a><a href="/security">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main" class="doc-shell">
|
|
34
34
|
<aside class="doc-nav" aria-label="Documentation"><a href="/docs" aria-current="page">Setup</a><a href="/docs#install">Install</a><a href="/docs#update">Update</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></aside>
|
|
35
35
|
<article class="prose">
|
|
36
36
|
<p class="eyebrow">Documentation</p>
|
|
37
|
-
<h1>Install
|
|
38
|
-
<p>
|
|
37
|
+
<h1>Install and pair ReMCP.</h1>
|
|
38
|
+
<p>Install the CLI first. Pairing happens from the signed-in workspace, which generates the real one-time command for your computer.</p>
|
|
39
39
|
|
|
40
|
-
<h2 id="requirements">
|
|
41
|
-
<p>
|
|
40
|
+
<h2 id="requirements">Requirements</h2>
|
|
41
|
+
<p>Node.js 22.5 or newer. The computer needs outbound HTTPS/WSS access to <code>remcp.delio24.com</code>. No inbound device port is required.</p>
|
|
42
42
|
|
|
43
|
-
<h2 id="
|
|
44
|
-
<
|
|
43
|
+
<h2 id="install">1. Install the CLI</h2>
|
|
44
|
+
<div class="copy-field"><code id="docs-install">npm install --global @remcp/remcp@latest</code><button class="copy-icon-button" type="button" data-copy="#docs-install" aria-label="Copy install command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
45
|
+
<p>This installs the <code>remcp</code> command. It does not pair a computer and does not contain a placeholder code.</p>
|
|
45
46
|
|
|
46
|
-
<h2 id="
|
|
47
|
-
<
|
|
48
|
-
<
|
|
47
|
+
<h2 id="pair">2. Pair a computer</h2>
|
|
48
|
+
<p>Open the <a href="/#connect">ReMCP workspace</a>, continue with Google or GitHub, and choose <strong>Generate pairing command</strong>. Run that exact generated command on the computer you want to pair.</p>
|
|
49
|
+
<div class="notice"><strong>Use the generated command.</strong><p>Pairing codes are short-lived and single-use. Do not type a made-up code or reuse an expired command.</p></div>
|
|
49
50
|
|
|
50
|
-
<
|
|
51
|
-
<div class="
|
|
52
|
-
remcp status</code></pre><button class="copy-button
|
|
53
|
-
<p><code>status</code> shows the installed CLI version,
|
|
51
|
+
<h2 id="verify">3. Verify</h2>
|
|
52
|
+
<div class="copy-field multiline"><pre><code id="docs-verify">remcp --version
|
|
53
|
+
remcp status</code></pre><button class="copy-icon-button" type="button" data-copy="#docs-verify" aria-label="Copy verification commands"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
54
|
+
<p><code>status</code> shows the installed CLI version, pairing state and server health.</p>
|
|
54
55
|
|
|
55
56
|
<h2 id="mcp">4. Add the MCP endpoint</h2>
|
|
56
|
-
<div class="
|
|
57
|
-
<p>
|
|
57
|
+
<div class="copy-field"><code id="docs-mcp">https://remcp.delio24.com/mcp</code><button class="copy-icon-button" type="button" data-copy="#docs-mcp" aria-label="Copy MCP endpoint"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
58
|
+
<p>Add this endpoint to your MCP client and use OAuth when prompted. ReMCP uses authorization code flow with PKCE and refresh-token rotation.</p>
|
|
58
59
|
|
|
59
|
-
<h2 id="update">Update
|
|
60
|
-
<div class="
|
|
61
|
-
<p>
|
|
60
|
+
<h2 id="update">Update</h2>
|
|
61
|
+
<div class="copy-field"><code id="docs-update">remcp update</code><button class="copy-icon-button" type="button" data-copy="#docs-update" aria-label="Copy update command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
62
|
+
<p>Updates the installed ReMCP CLI and compatible local runtime, then restarts the user service when present.</p>
|
|
62
63
|
|
|
63
64
|
<h2 id="service">Service commands</h2>
|
|
64
|
-
<div class="
|
|
65
|
+
<div class="copy-field multiline"><pre><code id="docs-service">remcp status
|
|
65
66
|
remcp doctor
|
|
66
67
|
remcp install
|
|
67
|
-
remcp start</code></pre><button class="copy-button
|
|
68
|
-
<p><code>
|
|
68
|
+
remcp start</code></pre><button class="copy-icon-button" type="button" data-copy="#docs-service" aria-label="Copy service commands"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
69
|
+
<p><code>install</code> installs or repairs the background user service for an already paired computer. <code>start</code> runs the agent in the foreground.</p>
|
|
69
70
|
|
|
70
71
|
<h2 id="uninstall">Uninstall</h2>
|
|
71
|
-
<div class="
|
|
72
|
-
<p>
|
|
73
|
-
<div class="
|
|
74
|
-
<p><code>--purge</code> also removes the globally installed ReMCP packages. The local pairing configuration remains in <code>~/.config/remcp</code> so it is not silently destroyed.</p>
|
|
72
|
+
<div class="copy-field"><code id="docs-uninstall">remcp uninstall</code><button class="copy-icon-button" type="button" data-copy="#docs-uninstall" aria-label="Copy uninstall command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
73
|
+
<p>Removes the background service. To also remove globally installed ReMCP packages:</p>
|
|
74
|
+
<div class="copy-field"><code id="docs-purge">remcp uninstall --purge</code><button class="copy-icon-button" type="button" data-copy="#docs-purge" aria-label="Copy purge command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
75
75
|
|
|
76
76
|
<h2 id="connection-model">Connection model</h2>
|
|
77
|
-
<p>The device agent
|
|
78
|
-
<div class="notice"><strong>Review mutating actions.</strong><p>Some tools can write files or run processes. Review the action requested by your MCP client before approving it.</p></div>
|
|
77
|
+
<p>The device agent opens an outbound secure WebSocket connection to the relay. MCP clients connect to the HTTPS MCP endpoint through OAuth. Only devices paired to the signed-in account are exposed to that account.</p>
|
|
79
78
|
|
|
80
79
|
<h2 id="self-hosting">Self-hosting</h2>
|
|
81
|
-
<p>The
|
|
80
|
+
<p>The server can be self-hosted with Docker. Keep it behind TLS, persist its data volume, and proxy WebSocket upgrades for the device-agent route. See the repository README for deployment variables.</p>
|
|
82
81
|
</article>
|
|
83
82
|
</main>
|
|
84
83
|
<footer class="site-footer">
|
|
@@ -86,9 +85,9 @@ remcp start</code></pre><button class="copy-button code-copy" type="button" data
|
|
|
86
85
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
87
86
|
<span translate="no">ReMCP</span>
|
|
88
87
|
</div>
|
|
89
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
88
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
90
89
|
<p>Open-source remote MCP infrastructure.</p>
|
|
91
90
|
</footer>
|
|
92
|
-
<script type="module" src="/copy.js?v=remcp-
|
|
91
|
+
<script type="module" src="/copy.js?v=remcp-013"></script>
|
|
93
92
|
</body>
|
|
94
93
|
</html>
|
package/public/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>ReMCP — Your computers over MCP</title>
|
|
9
9
|
<meta name="description" content="Securely pair your own computers and use their files, terminal and processes through authenticated MCP clients.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,17 +28,17 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main">
|
|
34
34
|
<section class="hero">
|
|
35
35
|
<div class="hero-copy">
|
|
36
|
-
<p class="eyebrow">Remote MCP
|
|
37
|
-
<h1>
|
|
38
|
-
<p class="lede">
|
|
36
|
+
<p class="eyebrow">Remote MCP for your computers</p>
|
|
37
|
+
<h1>Use your computers from any MCP client.</h1>
|
|
38
|
+
<p class="lede">ReMCP pairs a computer to one authenticated MCP endpoint. The local agent connects outbound, so the computer does not need a public port.</p>
|
|
39
39
|
<div class="hero-actions">
|
|
40
|
-
<a class="button" href="#connect">
|
|
41
|
-
<a class="text-link" href="/docs">Read
|
|
40
|
+
<a class="button" href="#connect">Open workspace</a>
|
|
41
|
+
<a class="text-link" href="/docs">Read docs <span aria-hidden="true">→</span></a>
|
|
42
42
|
</div>
|
|
43
43
|
</div>
|
|
44
44
|
<div class="hero-visual" role="img" aria-label="ReMCP connection diagram">
|
|
@@ -50,66 +50,52 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
</section>
|
|
52
52
|
|
|
53
|
-
<section class="principles" aria-label="
|
|
54
|
-
<div><span>
|
|
55
|
-
<div><span>
|
|
56
|
-
<div><span>
|
|
53
|
+
<section class="principles" aria-label="Connection facts">
|
|
54
|
+
<div><span>Connection</span><h2>Outbound only</h2><p>The device agent opens the connection to ReMCP. No inbound device port is required.</p></div>
|
|
55
|
+
<div><span>Authentication</span><h2>OAuth + PKCE</h2><p>MCP clients authorize against your ReMCP account. Device credentials are independent and revocable.</p></div>
|
|
56
|
+
<div><span>Control</span><h2>Your paired devices</h2><p>Tool calls are routed only to computers paired with the signed-in account.</p></div>
|
|
57
57
|
</section>
|
|
58
58
|
|
|
59
59
|
<section id="install" class="quickstart">
|
|
60
60
|
<div class="section-heading">
|
|
61
|
-
<p class="eyebrow">
|
|
62
|
-
<h2>
|
|
63
|
-
<p>
|
|
61
|
+
<p class="eyebrow">Setup</p>
|
|
62
|
+
<h2>Install first. Pair from the workspace.</h2>
|
|
63
|
+
<p>The public install command contains no pairing code. Sign in below to generate the exact one-time command for your computer.</p>
|
|
64
64
|
</div>
|
|
65
65
|
<div class="quickstart-grid">
|
|
66
66
|
<article class="command-card">
|
|
67
|
-
<span>01</span><h3>Install
|
|
68
|
-
<div class="
|
|
69
|
-
<p>
|
|
67
|
+
<span>01</span><h3>Install the CLI</h3>
|
|
68
|
+
<div class="copy-field"><code id="install-command">npm install --global @remcp/remcp@latest</code><button class="copy-icon-button" type="button" data-copy="#install-command" aria-label="Copy install command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
69
|
+
<p>Installs the current <code>remcp</code> command globally.</p>
|
|
70
70
|
</article>
|
|
71
71
|
<article class="command-card">
|
|
72
|
-
<span>02</span><h3>
|
|
73
|
-
<
|
|
74
|
-
<p>Confirm the local CLI version, pairing and server health.</p>
|
|
72
|
+
<span>02</span><h3>Pair a computer</h3>
|
|
73
|
+
<p>Sign in to the workspace, choose <strong>Generate pairing command</strong>, then run the generated command on that computer.</p>
|
|
75
74
|
</article>
|
|
76
|
-
<article
|
|
77
|
-
<span>03</span><h3>
|
|
78
|
-
<div class="
|
|
79
|
-
<p>
|
|
75
|
+
<article class="command-card">
|
|
76
|
+
<span>03</span><h3>Verify</h3>
|
|
77
|
+
<div class="copy-field"><code id="status-command">remcp status</code><button class="copy-icon-button" type="button" data-copy="#status-command" aria-label="Copy status command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
78
|
+
<p>Checks the installed version, pairing state and server health.</p>
|
|
80
79
|
</article>
|
|
81
80
|
</div>
|
|
82
|
-
<
|
|
81
|
+
<div class="update-line"><span>Already installed?</span><div class="copy-field compact"><code id="update-command">remcp update</code><button class="copy-icon-button" type="button" data-copy="#update-command" aria-label="Copy update command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div></div>
|
|
82
|
+
<a class="text-link" href="/docs">Installation and CLI reference <span aria-hidden="true">→</span></a>
|
|
83
83
|
</section>
|
|
84
84
|
|
|
85
85
|
<section id="connect" class="workspace">
|
|
86
86
|
<div class="section-heading">
|
|
87
87
|
<p class="eyebrow">Workspace</p>
|
|
88
|
-
<h2>
|
|
89
|
-
<p>Sign in to generate
|
|
88
|
+
<h2>Workspace</h2>
|
|
89
|
+
<p>Sign in with Google or GitHub to generate pairing commands and manage your devices.</p>
|
|
90
90
|
</div>
|
|
91
91
|
<div class="workspace-grid">
|
|
92
92
|
<section class="auth-pane" aria-labelledby="account-title">
|
|
93
93
|
<h3 id="account-title">Account</h3>
|
|
94
94
|
<div id="signed-out" class="stack">
|
|
95
|
-
<p class="muted">Sign in to
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<path fill="#34A853" d="M9 18c2.43 0 4.468-.806 5.957-2.181l-2.909-2.259c-.806.54-1.835.859-3.048.859-2.344 0-4.328-1.585-5.037-3.714H.956v2.332A9 9 0 0 0 9 18Z"/>
|
|
100
|
-
<path fill="#FBBC05" d="M3.963 10.705A5.41 5.41 0 0 1 3.682 9c0-.592.102-1.168.281-1.705V4.963H.956A9 9 0 0 0 0 9c0 1.452.347 2.827.956 4.037l3.007-2.332Z"/>
|
|
101
|
-
<path fill="#EA4335" d="M9 3.581c1.321 0 2.507.454 3.441 1.346l2.581-2.581C13.464.892 11.426 0 9 0A9 9 0 0 0 .956 4.963l3.007 2.332C4.672 5.166 6.656 3.581 9 3.581Z"/>
|
|
102
|
-
</svg>
|
|
103
|
-
<span>Continue with Google</span>
|
|
104
|
-
</button>
|
|
105
|
-
<div class="divider"><span>or use email</span></div>
|
|
106
|
-
<label for="email">Email</label>
|
|
107
|
-
<input id="email" name="email" type="email" autocomplete="email" inputmode="email" autocapitalize="none" spellcheck="false">
|
|
108
|
-
<label for="password">Password</label>
|
|
109
|
-
<input id="password" name="password" type="password" autocomplete="current-password">
|
|
110
|
-
<div class="button-row">
|
|
111
|
-
<button id="email-login" class="button secondary" type="button">Sign In</button>
|
|
112
|
-
<button id="email-register" class="button ghost" type="button">Create Account</button>
|
|
95
|
+
<p class="muted">Sign in to manage your paired computers.</p>
|
|
96
|
+
<div class="provider-stack">
|
|
97
|
+
<button id="google" class="provider-button google-button" type="button"><svg class="provider-icon" viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.205c0-.638-.057-1.252-.164-1.841H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.715v2.259h2.909c1.702-1.567 2.683-3.874 2.683-6.614Z"/><path fill="#34A853" d="M9 18c2.43 0 4.468-.806 5.957-2.181l-2.909-2.259c-.806.54-1.835.859-3.048.859-2.344 0-4.328-1.585-5.037-3.714H.956v2.332A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.963 10.705A5.41 5.41 0 0 1 3.682 9c0-.592.102-1.168.281-1.705V4.963H.956A9 9 0 0 0 0 9c0 1.452.347 2.827.956 4.037l3.007-2.332Z"/><path fill="#EA4335" d="M9 3.581c1.321 0 2.507.454 3.441 1.346l2.581-2.581C13.464.892 11.426 0 9 0A9 9 0 0 0 .956 4.963l3.007 2.332C4.672 5.166 6.656 3.581 9 3.581Z"/></svg><span>Continue with Google</span></button>
|
|
98
|
+
<button id="github" class="provider-button github-button" type="button"><svg class="provider-icon" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 .7a11.5 11.5 0 0 0-3.64 22.41c.58.11.79-.25.79-.56v-2.24c-3.22.7-3.9-1.37-3.9-1.37-.53-1.34-1.29-1.7-1.29-1.7-1.05-.72.08-.71.08-.71 1.16.08 1.77 1.19 1.77 1.19 1.04 1.77 2.72 1.26 3.38.96.1-.75.4-1.26.73-1.55-2.57-.29-5.27-1.29-5.27-5.68 0-1.26.45-2.29 1.19-3.1-.12-.29-.52-1.47.11-3.06 0 0 .97-.31 3.16 1.18a10.9 10.9 0 0 1 5.76 0c2.19-1.49 3.16-1.18 3.16-1.18.63 1.59.23 2.77.11 3.06.74.81 1.19 1.84 1.19 3.1 0 4.4-2.71 5.38-5.29 5.67.42.36.79 1.07.79 2.16v3.21c0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .7Z"/></svg><span>Continue with GitHub</span></button>
|
|
113
99
|
</div>
|
|
114
100
|
<p id="auth-error" class="error" role="alert" aria-live="polite"></p>
|
|
115
101
|
</div>
|
|
@@ -120,35 +106,29 @@
|
|
|
120
106
|
</section>
|
|
121
107
|
<section class="endpoint-pane" aria-labelledby="endpoint-title">
|
|
122
108
|
<div><h3 id="endpoint-title">MCP endpoint</h3><p class="muted">Use this HTTPS endpoint when adding ReMCP to an MCP client.</p></div>
|
|
123
|
-
<div class="
|
|
109
|
+
<div class="copy-field"><code id="mcp-url">https://remcp.delio24.com/mcp</code><button class="copy-icon-button" type="button" data-copy="#mcp-url" aria-label="Copy MCP endpoint"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
124
110
|
<dl class="endpoint-facts"><div><dt>Transport</dt><dd>Streamable HTTP</dd></div><div><dt>Authentication</dt><dd>OAuth 2.1 + PKCE</dd></div></dl>
|
|
125
111
|
</section>
|
|
126
112
|
</div>
|
|
127
113
|
<section id="dashboard" class="hidden device-workspace" aria-label="Device management">
|
|
128
114
|
<div class="pair-panel">
|
|
129
|
-
<div><p class="eyebrow">Add a computer</p><h3>Generate
|
|
130
|
-
<button id="pair" class="button" type="button">Generate
|
|
131
|
-
<div id="pairing" class="hidden pairing-output"><code id="pair-command"></code><button class="copy-button" type="button" data-copy="#pair-command"
|
|
115
|
+
<div><p class="eyebrow">Add a computer</p><h3>Generate pairing command</h3><p class="muted">The generated command contains a short-lived one-time code. Run it only on the computer you want to pair.</p></div>
|
|
116
|
+
<button id="pair" class="button" type="button">Generate pairing command</button>
|
|
117
|
+
<div id="pairing" class="hidden pairing-output"><div class="copy-field"><code id="pair-command"></code><button class="copy-icon-button" type="button" data-copy="#pair-command" aria-label="Copy pairing command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div><p id="pair-expiry" class="muted"></p></div>
|
|
132
118
|
</div>
|
|
133
119
|
<div class="devices-panel"><div class="panel-title"><h3>Paired devices</h3><span class="muted">Online state updates when the page refreshes.</span></div><div id="devices" class="device-list" aria-live="polite">No devices yet.</div></div>
|
|
134
120
|
</section>
|
|
135
121
|
</section>
|
|
136
|
-
|
|
137
|
-
<section class="final-cta">
|
|
138
|
-
<p class="eyebrow">Self-hostable architecture</p>
|
|
139
|
-
<h2>Keep the relay yours.</h2>
|
|
140
|
-
<p>ReMCP can run as a small Docker service while each computer runs its own local agent.</p>
|
|
141
|
-
<a class="text-link" href="/security">Review the Security Model <span aria-hidden="true">→</span></a>
|
|
142
|
-
</section>
|
|
143
122
|
</main>
|
|
144
123
|
<footer class="site-footer">
|
|
145
124
|
<div class="wordmark">
|
|
146
125
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
147
126
|
<span translate="no">ReMCP</span>
|
|
148
127
|
</div>
|
|
149
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
128
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
150
129
|
<p>Open-source remote MCP infrastructure.</p>
|
|
151
130
|
</footer>
|
|
152
|
-
<script type="module" src="/
|
|
131
|
+
<script type="module" src="/copy.js?v=remcp-013"></script>
|
|
132
|
+
<script type="module" src="/app.js?v=remcp-013"></script>
|
|
153
133
|
</body>
|
|
154
134
|
</html>
|
package/public/oauth-app.js
CHANGED
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-app.js';
|
|
2
|
-
import { getAuth, GoogleAuthProvider, onAuthStateChanged, signInWithPopup
|
|
2
|
+
import { getAuth, GoogleAuthProvider, GithubAuthProvider, onAuthStateChanged, signInWithPopup } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-auth.js';
|
|
3
3
|
|
|
4
4
|
const cfg = await fetch(`/api/config?fresh=${Date.now()}`, { cache: 'no-store' }).then(r => r.json());
|
|
5
5
|
const auth = getAuth(initializeApp(cfg.firebase));
|
|
6
6
|
const query = new URLSearchParams(location.search);
|
|
7
7
|
const $ = selector => document.querySelector(selector);
|
|
8
|
-
const
|
|
8
|
+
const googleProvider = new GoogleAuthProvider();
|
|
9
|
+
const githubProvider = new GithubAuthProvider();
|
|
10
|
+
googleProvider.setCustomParameters({ prompt: 'select_account' });
|
|
9
11
|
let currentUser = null;
|
|
10
12
|
let completing = false;
|
|
11
|
-
const googleProvider = new GoogleAuthProvider();
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const showError = error => {
|
|
15
|
+
const code = error?.code || '';
|
|
16
|
+
if (code === 'auth/popup-closed-by-user' || code === 'auth/cancelled-popup-request') return;
|
|
17
|
+
$('#error').textContent = code === 'auth/account-exists-with-different-credential'
|
|
18
|
+
? 'This email is already linked to another sign-in provider.'
|
|
19
|
+
: error?.message || String(error);
|
|
20
|
+
};
|
|
21
|
+
async function signIn(button, provider, idleLabel) {
|
|
16
22
|
const label = button.querySelector('span');
|
|
17
23
|
button.disabled = true;
|
|
18
24
|
$('#error').textContent = '';
|
|
19
|
-
label.textContent = 'Opening
|
|
20
|
-
try { await signInWithPopup(auth,
|
|
25
|
+
label.textContent = 'Opening…';
|
|
26
|
+
try { await signInWithPopup(auth, provider); }
|
|
21
27
|
catch (error) { showError(error); }
|
|
22
|
-
finally { button.disabled = false; label.textContent =
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
$('#
|
|
28
|
+
finally { button.disabled = false; label.textContent = idleLabel; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
$('#client-id').textContent = query.get('client_id') || 'MCP client';
|
|
32
|
+
$('#google').onclick = () => signIn($('#google'), googleProvider, 'Continue with Google');
|
|
33
|
+
$('#github').onclick = () => signIn($('#github'), githubProvider, 'Continue with GitHub');
|
|
26
34
|
|
|
27
35
|
onAuthStateChanged(auth, user => {
|
|
28
36
|
currentUser = user;
|
|
29
37
|
$('#oauth-login').classList.toggle('hidden', Boolean(user));
|
|
30
38
|
$('#oauth-consent').classList.toggle('hidden', !user);
|
|
31
|
-
$('#status').textContent = user ? `Signed in as ${user.email || 'ReMCP user'}
|
|
39
|
+
$('#status').textContent = user ? `Signed in as ${user.email || user.displayName || 'ReMCP user'}.` : '';
|
|
32
40
|
});
|
|
41
|
+
|
|
33
42
|
$('#authorize').onclick = async () => {
|
|
34
43
|
if (!currentUser || completing) return;
|
|
35
44
|
completing = true;
|
package/public/privacy.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Privacy Policy · ReMCP</title>
|
|
9
9
|
<meta name="description" content="How ReMCP processes account, device, OAuth and remote-computer data.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,24 +28,44 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main" class="doc-shell">
|
|
34
34
|
<aside class="doc-nav" aria-label="Documentation"><a href="/docs">Setup</a><a href="/docs#install">Install</a><a href="/docs#update">Update</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy" aria-current="page">Privacy</a><a href="/terms">Terms</a></aside>
|
|
35
35
|
<article class="prose">
|
|
36
36
|
<p class="eyebrow">Privacy</p>
|
|
37
37
|
<h1>Privacy Policy</h1>
|
|
38
|
-
<p><strong>Effective September 16, 2026.</strong> This policy
|
|
39
|
-
|
|
40
|
-
<h2>Account
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<h2>
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
<h2>
|
|
47
|
-
<
|
|
48
|
-
|
|
38
|
+
<p><strong>Effective September 16, 2026.</strong> This policy covers the hosted ReMCP service at <code>remcp.delio24.com</code>. Self-hosted deployments are controlled by their own operators.</p>
|
|
39
|
+
|
|
40
|
+
<h2>Account data</h2>
|
|
41
|
+
<p>Hosted sign-in is provided by Firebase Authentication using Google or GitHub. ReMCP may receive your authentication user id, email address, email-verification status and display name. These data are used to authenticate you and separate your devices and OAuth grants from other accounts.</p>
|
|
42
|
+
|
|
43
|
+
<h2>Google and GitHub</h2>
|
|
44
|
+
<p>ReMCP uses Google and GitHub only as sign-in providers through Firebase Authentication. The hosted ReMCP application does not use Google access to read Gmail, Drive, Calendar or Contacts, and it does not use GitHub provider tokens to read repositories or perform GitHub actions.</p>
|
|
45
|
+
|
|
46
|
+
<h2>Device and OAuth metadata</h2>
|
|
47
|
+
<p>ReMCP stores device identifiers, device names, basic platform metadata, one-way hashes of device credentials, pairing records, OAuth client metadata and one-way hashes of refresh credentials. Raw reusable device credentials are not stored in plaintext by the relay.</p>
|
|
48
|
+
|
|
49
|
+
<h2>Files, commands and tool results</h2>
|
|
50
|
+
<p>When you invoke an MCP tool, the request and result pass through the relay to the selected device. This can include paths, file contents, command output and process information you asked ReMCP to handle. ReMCP does not intentionally retain MCP tool payloads as product data.</p>
|
|
51
|
+
|
|
52
|
+
<h2>Use and sharing</h2>
|
|
53
|
+
<p>Data are used to provide authentication, pairing, OAuth authorization, request routing, abuse prevention, security and reliability. ReMCP does not sell personal information and does not serve advertising. Infrastructure and authentication providers process data only as needed to operate the service.</p>
|
|
54
|
+
|
|
55
|
+
<h2>Retention and control</h2>
|
|
56
|
+
<p>Pairing codes expire after 10 minutes by default. MCP access tokens expire after 1 hour by default. Refresh credentials expire after 30 days by default and rotate on use. Device records remain until revoked or removed. Hosted Nginx access and error logs rotate daily with 14 rotated copies. Application container logs are limited to three files of at most 50 MB each. You can revoke paired devices from the workspace.</p>
|
|
57
|
+
|
|
58
|
+
<h2>Restricted data</h2>
|
|
59
|
+
<p>Do not send passwords, MFA or OTP codes, API/private keys, payment-card data, protected health information or government identifiers through ReMCP tool calls.</p>
|
|
60
|
+
|
|
61
|
+
<h2>Security and international processing</h2>
|
|
62
|
+
<p>ReMCP uses TLS for network transport and one-way hashes for reusable server-side credentials. Internet infrastructure and authentication providers may process data in more than one country. See the <a href="/security">Security page</a> for the current model.</p>
|
|
63
|
+
|
|
64
|
+
<h2>Children</h2>
|
|
65
|
+
<p>ReMCP is a developer and systems-administration tool and is not directed to children under 13.</p>
|
|
66
|
+
|
|
67
|
+
<h2>Changes and requests</h2>
|
|
68
|
+
<p>Material changes are published at this URL with an updated effective date. Account-data or deletion requests can be made through the <a href="/support">Support page</a>.</p>
|
|
49
69
|
</article>
|
|
50
70
|
</main>
|
|
51
71
|
<footer class="site-footer">
|
|
@@ -53,7 +73,7 @@
|
|
|
53
73
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
54
74
|
<span translate="no">ReMCP</span>
|
|
55
75
|
</div>
|
|
56
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
76
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
57
77
|
<p>Open-source remote MCP infrastructure.</p>
|
|
58
78
|
</footer>
|
|
59
79
|
</body>
|
package/public/security.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Security · ReMCP</title>
|
|
9
9
|
<meta name="description" content="How ReMCP isolates accounts, devices, credentials and remote MCP tool access.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,21 +28,34 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security" aria-current="page">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main" class="doc-shell">
|
|
34
34
|
<aside class="doc-nav" aria-label="Documentation"><a href="/docs">Setup</a><a href="/docs#install">Install</a><a href="/docs#update">Update</a><a href="/security" aria-current="page">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></aside>
|
|
35
35
|
<article class="prose">
|
|
36
36
|
<p class="eyebrow">Security</p>
|
|
37
|
-
<h1>
|
|
38
|
-
<p>ReMCP
|
|
39
|
-
|
|
40
|
-
<h2>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<h2>
|
|
44
|
-
<
|
|
45
|
-
|
|
37
|
+
<h1>Security model.</h1>
|
|
38
|
+
<p>ReMCP is remote access infrastructure. Account identity, device credentials and tool risk are kept separate so each layer can be revoked independently.</p>
|
|
39
|
+
|
|
40
|
+
<h2>Account identity</h2>
|
|
41
|
+
<p>The hosted service uses Firebase Authentication with Google and GitHub sign-in. ReMCP does not provide hosted email/password sign-in. MCP authorization is scoped to the authenticated ReMCP account.</p>
|
|
42
|
+
|
|
43
|
+
<h2>Device pairing</h2>
|
|
44
|
+
<p>Pairing commands contain short-lived, single-use codes. A successfully paired computer receives its own random device credential; the server stores only a one-way hash of that credential.</p>
|
|
45
|
+
|
|
46
|
+
<h2>Network model</h2>
|
|
47
|
+
<p>The local agent opens an outbound WSS connection to the relay. The computer does not need a public IP address or inbound listening port.</p>
|
|
48
|
+
|
|
49
|
+
<h2>MCP authorization</h2>
|
|
50
|
+
<p>The public MCP endpoint uses OAuth authorization code flow with PKCE S256. Access tokens are short-lived and refresh credentials rotate on use.</p>
|
|
51
|
+
|
|
52
|
+
<h2>Tool risk</h2>
|
|
53
|
+
<p>MCP tool descriptors declare read-only, destructive and open-world hints. File writes, configuration changes and process execution can change local state; terminal commands can also reach external systems.</p>
|
|
54
|
+
|
|
55
|
+
<h2>Revocation</h2>
|
|
56
|
+
<p>Revoke a paired device from the workspace if it is lost, retired or no longer trusted. Revoked device credentials cannot reconnect.</p>
|
|
57
|
+
|
|
58
|
+
<div class="notice"><strong>Relay operator trust.</strong><p>A hosted relay can observe requests while routing them. For the highest infrastructure control, self-host ReMCP and secure that deployment as privileged infrastructure.</p></div>
|
|
46
59
|
</article>
|
|
47
60
|
</main>
|
|
48
61
|
<footer class="site-footer">
|
|
@@ -50,7 +63,7 @@
|
|
|
50
63
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
51
64
|
<span translate="no">ReMCP</span>
|
|
52
65
|
</div>
|
|
53
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
66
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
54
67
|
<p>Open-source remote MCP infrastructure.</p>
|
|
55
68
|
</footer>
|
|
56
69
|
</body>
|
package/public/style.css
CHANGED
|
@@ -46,7 +46,7 @@ img, svg { display: block; }
|
|
|
46
46
|
.site-header nav a[aria-current="page"] { font-weight: 680; }
|
|
47
47
|
|
|
48
48
|
main { display: block; }
|
|
49
|
-
.hero { max-width: var(--container); min-height:
|
|
49
|
+
.hero { max-width: var(--container); min-height: 560px; margin: 0 auto; padding: clamp(64px, 8vw, 92px) 20px; display: grid; grid-template-columns: minmax(0, 1.03fr) minmax(360px, .97fr); align-items: center; gap: clamp(48px, 7vw, 96px); }
|
|
50
50
|
.hero-copy { max-width: 650px; }
|
|
51
51
|
.eyebrow { margin: 0 0 16px; color: var(--accent); font-size: 12px; font-weight: 760; letter-spacing: .13em; text-transform: uppercase; }
|
|
52
52
|
.hero h1, .section-heading h2, .final-cta h2, .prose h1 { text-wrap: balance; }
|
|
@@ -64,10 +64,14 @@ main { display: block; }
|
|
|
64
64
|
.text-link { display: inline-flex; align-items: center; gap: 6px; padding: 7px 0; color: var(--ink); font-weight: 650; border-bottom: 1px solid var(--line-strong); }
|
|
65
65
|
.text-link:hover { border-color: var(--ink); }
|
|
66
66
|
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.
|
|
67
|
+
.provider-stack { width: min(100%, 400px); display: grid; gap: 10px; margin-top: 4px; }
|
|
68
|
+
.provider-button { position: relative; width: 100%; min-height: 46px; display: flex; align-items: center; justify-content: center; padding: 10px 16px 10px 48px; border-radius: 7px; font-size: 14px; font-weight: 600; line-height: 1; text-align: center; box-shadow: none; }
|
|
69
|
+
.provider-button:active { transform: none; }
|
|
70
|
+
.provider-icon { position: absolute; left: 14px; top: 50%; width: 20px; height: 20px; transform: translateY(-50%); }
|
|
71
|
+
.google-button { border: 1px solid #747775; background: #fff; color: #1f1f1f; font-family: Roboto, Arial, sans-serif; font-weight: 500; }
|
|
72
|
+
.google-button:hover { border-color: #5f6368; background: #f8fafd; color: #1f1f1f; }
|
|
73
|
+
.github-button { border: 1px solid #1f2328; background: #24292f; color: #fff; }
|
|
74
|
+
.github-button:hover { border-color: #1f2328; background: #1f2328; color: #fff; }
|
|
71
75
|
|
|
72
76
|
.hero-visual { width: 100%; max-width: 520px; margin-left: auto; }
|
|
73
77
|
.node { min-height: 62px; display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 17px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
|
|
@@ -96,7 +100,6 @@ main { display: block; }
|
|
|
96
100
|
.command-card > span { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
|
|
97
101
|
.command-card h3 { margin: 18px 0 8px; font-size: 20px; letter-spacing: -.025em; }
|
|
98
102
|
.command-card p { margin: 12px 0 0; color: var(--muted); font-size: 14px; }
|
|
99
|
-
.command-card .command-row { margin-top: 14px; }
|
|
100
103
|
.site-header nav { min-width: 0; overflow-x: auto; scrollbar-width: none; }
|
|
101
104
|
.site-header nav::-webkit-scrollbar { display: none; }
|
|
102
105
|
|
|
@@ -112,32 +115,35 @@ main { display: block; }
|
|
|
112
115
|
.auth-pane h3, .endpoint-pane h3, .pair-panel h3, .devices-panel h3, .oauth-card h2 { margin: 0 0 9px; font-size: 20px; line-height: 1.25; letter-spacing: -.025em; }
|
|
113
116
|
.stack { display: flex; flex-direction: column; gap: 10px; }
|
|
114
117
|
.muted { color: var(--muted); }
|
|
115
|
-
label { display: block; margin: 10px 0 6px; color: #343438; font-size: 13px; font-weight: 650; }
|
|
116
|
-
.stack label { margin: 3px 0 -4px; }
|
|
117
|
-
input { width: 100%; min-height: 44px; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--surface); color: var(--ink); transition: border-color 140ms ease, box-shadow 140ms ease; }
|
|
118
|
-
input:hover { border-color: #b9b9b2; }
|
|
119
|
-
input:focus-visible { border-color: var(--accent); }
|
|
120
|
-
.button-row { display: flex; gap: 9px; margin-top: 5px; }
|
|
121
|
-
.divider { display: flex; align-items: center; gap: 11px; margin: 7px 0; color: var(--muted); font-size: 12px; }
|
|
122
|
-
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--line); }
|
|
123
118
|
.error { margin: 2px 0 0; color: var(--danger); font-size: 13px; }
|
|
124
119
|
p:empty, .error:empty, #status:empty { display: none; }
|
|
125
120
|
.identity { display: flex; align-items: center; gap: 11px; }
|
|
126
121
|
.identity small { display: block; color: var(--muted); }
|
|
127
122
|
.status-dot { width: 9px; height: 9px; flex: 0 0 9px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 4px var(--ok-soft); }
|
|
128
123
|
|
|
129
|
-
.
|
|
130
|
-
.
|
|
131
|
-
.copy-
|
|
132
|
-
.copy-
|
|
124
|
+
.copy-field { position: relative; min-width: 0; display: flex; align-items: center; margin-top: 14px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--surface); overflow: hidden; }
|
|
125
|
+
.copy-field code { min-width: 0; flex: 1; overflow-x: auto; padding: 12px 48px 12px 13px; color: #2e2e33; font: 12.5px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: pre; scrollbar-width: thin; }
|
|
126
|
+
.copy-field pre { min-width: 0; flex: 1; margin: 0; overflow: auto; }
|
|
127
|
+
.copy-field pre code { display: block; }
|
|
128
|
+
.copy-field.multiline { align-items: stretch; }
|
|
129
|
+
.copy-field.compact { width: min(100%, 300px); margin-top: 0; }
|
|
130
|
+
.copy-icon-button { position: absolute; top: 50%; right: 6px; width: 34px; height: 34px; display: grid; place-items: center; padding: 0; transform: translateY(-50%); border: 0; border-radius: 7px; background: transparent; color: #65656b; }
|
|
131
|
+
.copy-icon-button:hover { background: var(--surface-subtle); color: var(--ink); }
|
|
132
|
+
.copy-icon-button svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
|
133
|
+
.copy-icon-button .icon-check { display: none; }
|
|
134
|
+
.copy-icon-button[data-copied="true"] { color: var(--ok); }
|
|
135
|
+
.copy-icon-button[data-copied="true"] .icon-copy { display: none; }
|
|
136
|
+
.copy-icon-button[data-copied="true"] .icon-check { display: block; }
|
|
137
|
+
.pairing-output { grid-column: 1 / -1; margin-top: 4px; }
|
|
138
|
+
.pairing-output .copy-field { width: 100%; }
|
|
139
|
+
.pairing-output p { margin: 8px 0 0; }
|
|
140
|
+
.update-line { display: flex; align-items: center; gap: 14px; margin: 20px 0 24px; color: var(--muted); font-size: 13px; }
|
|
133
141
|
.endpoint-facts { margin: 28px 0 0; border-top: 1px solid var(--line); }
|
|
134
142
|
.endpoint-facts div { display: flex; justify-content: space-between; gap: 20px; padding: 12px 0; border-bottom: 1px solid var(--line); }
|
|
135
143
|
.endpoint-facts dt { color: var(--muted); }
|
|
136
144
|
.endpoint-facts dd { margin: 0; text-align: right; font-weight: 650; }
|
|
137
145
|
.device-workspace { margin-top: 52px; }
|
|
138
146
|
.pair-panel { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 20px; align-items: center; padding-bottom: 34px; border-bottom: 1px solid var(--line); }
|
|
139
|
-
.pairing-output { grid-column: 1 / -1; }
|
|
140
|
-
.pairing-output p { grid-column: 1 / -1; margin: 0; }
|
|
141
147
|
.devices-panel { padding-top: 34px; }
|
|
142
148
|
.panel-title { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; }
|
|
143
149
|
.device-list { margin-top: 14px; border-top: 1px solid var(--line); }
|
|
@@ -168,10 +174,9 @@ p:empty, .error:empty, #status:empty { display: none; }
|
|
|
168
174
|
.prose p { margin: 0 0 12px; }
|
|
169
175
|
.prose a { color: #3538ae; text-decoration: underline; text-decoration-color: #a5a7e9; text-underline-offset: 3px; }
|
|
170
176
|
.prose a:hover { text-decoration-color: #3538ae; }
|
|
171
|
-
.prose pre {
|
|
172
|
-
.prose .
|
|
173
|
-
.prose .
|
|
174
|
-
.prose .code-row .code-copy:hover { border-color: #66666d; background: #38383d; }
|
|
177
|
+
.prose pre { margin: 0; }
|
|
178
|
+
.prose .copy-field { margin: 12px 0 16px; background: #fbfbfa; }
|
|
179
|
+
.prose .copy-field code { font-size: 12.5px; }
|
|
175
180
|
.prose code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .9em; }
|
|
176
181
|
.prose :not(pre) > code { padding: 2px 5px; border-radius: 5px; background: var(--surface-subtle); color: #34343a; }
|
|
177
182
|
.prose hr { margin: 46px 0; border: 0; border-top: 1px solid var(--line); }
|
|
@@ -182,7 +187,7 @@ p:empty, .error:empty, #status:empty { display: none; }
|
|
|
182
187
|
.oauth-card { width: min(100%, 520px); padding: 30px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); }
|
|
183
188
|
.oauth-card .eyebrow { margin-bottom: 11px; }
|
|
184
189
|
.oauth-card > p:first-child { margin-top: 0; }
|
|
185
|
-
.oauth-card .
|
|
190
|
+
.oauth-card .provider-stack { width: 100%; margin-top: 20px; }
|
|
186
191
|
.scope-list { margin: 24px 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
|
|
187
192
|
.scope-list li { display: flex; justify-content: space-between; gap: 20px; padding: 13px 0; border-bottom: 1px solid var(--line); }
|
|
188
193
|
.scope-list strong { color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; font-weight: 600; }
|
|
@@ -229,13 +234,13 @@ input:focus-visible, button:focus-visible, a:focus-visible { outline: 3px solid
|
|
|
229
234
|
.section-heading { margin-bottom: 30px; }
|
|
230
235
|
.section-heading h2, .final-cta h2 { font-size: 36px; }
|
|
231
236
|
.section-heading > p:last-child, .final-cta > p { margin-top: 12px; font-size: 16px; }
|
|
232
|
-
.
|
|
233
|
-
.
|
|
237
|
+
.oauth-actions { flex-direction: column; }
|
|
238
|
+
.oauth-actions .button { width: 100%; }
|
|
239
|
+
.update-line { align-items: stretch; flex-direction: column; gap: 8px; }
|
|
240
|
+
.copy-field.compact { width: 100%; }
|
|
234
241
|
.pair-panel { grid-template-columns: 1fr; }
|
|
235
242
|
.pair-panel .button { justify-self: start; }
|
|
236
243
|
.panel-title { align-items: flex-start; flex-direction: column; }
|
|
237
|
-
.command-row, .pairing-output { grid-template-columns: minmax(0, 1fr) auto; }
|
|
238
|
-
.copy-button { justify-self: stretch; }
|
|
239
244
|
.endpoint-facts div { align-items: flex-start; flex-direction: column; gap: 2px; }
|
|
240
245
|
.endpoint-facts dd { text-align: left; }
|
|
241
246
|
.site-footer { padding: 24px 18px; }
|
|
@@ -245,9 +250,6 @@ input:focus-visible, button:focus-visible, a:focus-visible { outline: 3px solid
|
|
|
245
250
|
.prose h2 { margin-top: 28px; font-size: 21px; }
|
|
246
251
|
.prose h3 { margin-top: 21px; }
|
|
247
252
|
.prose p, .prose li { font-size: 15px; }
|
|
248
|
-
.prose .code-row { margin: 10px 0 14px; }
|
|
249
|
-
.prose .code-row pre { padding: 12px 10px 12px 13px; }
|
|
250
|
-
.prose .code-row .code-copy { margin-right: 7px; }
|
|
251
253
|
.oauth-shell { min-height: calc(100svh - 62px); padding: 28px 14px 60px; place-items: start center; }
|
|
252
254
|
.oauth-card { padding: 22px 18px; }
|
|
253
255
|
.scope-list li { align-items: flex-start; flex-direction: column; gap: 4px; }
|
package/public/support.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Support · ReMCP</title>
|
|
9
9
|
<meta name="description" content="Troubleshoot ReMCP sign-in, device pairing, agent connectivity and MCP authorization.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,22 +28,38 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support" aria-current="page">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main" class="doc-shell">
|
|
34
34
|
<aside class="doc-nav" aria-label="Documentation"><a href="/docs">Setup</a><a href="/docs#install">Install</a><a href="/docs#update">Update</a><a href="/security">Security</a><a href="/support" aria-current="page">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></aside>
|
|
35
35
|
<article class="prose">
|
|
36
36
|
<p class="eyebrow">Support</p>
|
|
37
|
-
<h1>
|
|
38
|
-
<p>
|
|
39
|
-
|
|
40
|
-
<h2>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<h2>
|
|
44
|
-
remcp
|
|
45
|
-
<
|
|
46
|
-
|
|
37
|
+
<h1>Troubleshooting.</h1>
|
|
38
|
+
<p>Check the layer that is failing: sign-in, pairing, the local agent, or MCP authorization.</p>
|
|
39
|
+
|
|
40
|
+
<h2>Sign-in does not open</h2>
|
|
41
|
+
<p>Use <strong>Continue with Google</strong> or <strong>Continue with GitHub</strong>. ReMCP does not use email/password sign-in on the hosted site. If a popup is blocked, allow popups for <code>remcp.delio24.com</code> and try again.</p>
|
|
42
|
+
|
|
43
|
+
<h2>The <code>remcp</code> command is missing</h2>
|
|
44
|
+
<div class="copy-field"><code id="support-install">npm install --global @remcp/remcp@latest</code><button class="copy-icon-button" type="button" data-copy="#support-install" aria-label="Copy install command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
45
|
+
<p>After installation, pair the computer from the signed-in workspace. The public install command alone does not pair a device.</p>
|
|
46
|
+
|
|
47
|
+
<h2>Pairing command expired</h2>
|
|
48
|
+
<p>Open the workspace and generate a new command. Each pairing command contains a one-time code and expires automatically.</p>
|
|
49
|
+
|
|
50
|
+
<h2>Device shows offline</h2>
|
|
51
|
+
<div class="copy-field"><code id="support-status">remcp status</code><button class="copy-icon-button" type="button" data-copy="#support-status" aria-label="Copy status command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
52
|
+
<p>Confirm the user service is running and outbound HTTPS/WSS access to <code>remcp.delio24.com</code> is allowed. Re-pair only if the device credential was revoked or the local pairing state was removed.</p>
|
|
53
|
+
|
|
54
|
+
<h2>OAuth does not complete</h2>
|
|
55
|
+
<p>Return to the authorization page, sign in with the intended ReMCP account, review the requested scopes, and choose <strong>Authorize ReMCP Access</strong>.</p>
|
|
56
|
+
|
|
57
|
+
<h2>MCP tool cannot run</h2>
|
|
58
|
+
<p>Confirm the target device is online. A device tool needs the current ReMCP device id; clients can obtain it with <code>list_devices</code>.</p>
|
|
59
|
+
|
|
60
|
+
<h2>Update or repair</h2>
|
|
61
|
+
<div class="copy-field"><code id="support-update">remcp update</code><button class="copy-icon-button" type="button" data-copy="#support-update" aria-label="Copy update command"><svg class="icon-copy" viewBox="0 0 24 24" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3"/></svg><svg class="icon-check" viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg></button></div>
|
|
62
|
+
<p>If the CLI is paired but its background service is missing, run <code>remcp install</code>.</p>
|
|
47
63
|
</article>
|
|
48
64
|
</main>
|
|
49
65
|
<footer class="site-footer">
|
|
@@ -51,9 +67,9 @@ remcp status</code></pre><button class="copy-button code-copy" type="button" dat
|
|
|
51
67
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
52
68
|
<span translate="no">ReMCP</span>
|
|
53
69
|
</div>
|
|
54
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
70
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
55
71
|
<p>Open-source remote MCP infrastructure.</p>
|
|
56
72
|
</footer>
|
|
57
|
-
<script type="module" src="/copy.js?v=remcp-
|
|
73
|
+
<script type="module" src="/copy.js?v=remcp-013"></script>
|
|
58
74
|
</body>
|
|
59
75
|
</html>
|
package/public/terms.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Terms of Service · ReMCP</title>
|
|
9
9
|
<meta name="description" content="Terms for using the hosted ReMCP service and its remote-computer capabilities.">
|
|
10
10
|
<link rel="preconnect" href="https://www.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/style.css?v=remcp-
|
|
11
|
+
<link rel="stylesheet" href="/style.css?v=remcp-013">
|
|
12
12
|
<meta property="og:site_name" content="ReMCP">
|
|
13
13
|
<meta property="og:image" content="https://remcp.delio24.com/assets/og-remcp.png">
|
|
14
14
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
@@ -28,24 +28,41 @@
|
|
|
28
28
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
29
29
|
<span translate="no">ReMCP</span>
|
|
30
30
|
</a>
|
|
31
|
-
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/
|
|
31
|
+
<nav aria-label="Primary"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a></nav>
|
|
32
32
|
</header>
|
|
33
33
|
<main id="main" class="doc-shell">
|
|
34
34
|
<aside class="doc-nav" aria-label="Documentation"><a href="/docs">Setup</a><a href="/docs#install">Install</a><a href="/docs#update">Update</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms" aria-current="page">Terms</a></aside>
|
|
35
35
|
<article class="prose">
|
|
36
36
|
<p class="eyebrow">Legal</p>
|
|
37
37
|
<h1>Terms of Service</h1>
|
|
38
|
-
<p><strong>Effective September 16, 2026.</strong> These Terms apply to the hosted ReMCP service at remcp.delio24.com
|
|
39
|
-
|
|
40
|
-
<h2>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<h2>
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
<h2>
|
|
47
|
-
<
|
|
48
|
-
|
|
38
|
+
<p><strong>Effective September 16, 2026.</strong> These Terms apply to the hosted ReMCP service at <code>remcp.delio24.com</code>. The open-source software can also be self-hosted under its software licenses.</p>
|
|
39
|
+
|
|
40
|
+
<h2>Authorized systems only</h2>
|
|
41
|
+
<p>You may pair and control only computers and accounts that you own or are authorized to administer. You are responsible for protecting your sign-in account and revoking devices or OAuth grants you no longer trust.</p>
|
|
42
|
+
|
|
43
|
+
<h2>Remote actions</h2>
|
|
44
|
+
<p>ReMCP can read and modify files and can start, interact with or terminate processes. Some commands can affect external systems. Review consequential actions and maintain appropriate backups and operating-system permissions.</p>
|
|
45
|
+
|
|
46
|
+
<h2>Acceptable use</h2>
|
|
47
|
+
<p>Do not use ReMCP to access systems without authorization, steal credentials, distribute malware, evade security controls, interfere with other users, or violate applicable law or third-party rights.</p>
|
|
48
|
+
|
|
49
|
+
<h2>Sign-in providers</h2>
|
|
50
|
+
<p>The hosted service uses Firebase Authentication with Google and GitHub sign-in. Those providers and other infrastructure dependencies are governed by their own terms. ReMCP does not grant rights to third-party systems accessible from a paired computer.</p>
|
|
51
|
+
|
|
52
|
+
<h2>Service operation</h2>
|
|
53
|
+
<p>The hosted service may be updated, rate-limited, suspended or discontinued for security, abuse prevention, maintenance or legal reasons. Uninterrupted availability is not guaranteed. Self-hosted deployments are operated and secured by their administrators.</p>
|
|
54
|
+
|
|
55
|
+
<h2>Open-source software</h2>
|
|
56
|
+
<p>ReMCP and its dependencies include open-source software. Their license notices govern those software components independently of these hosted-service Terms.</p>
|
|
57
|
+
|
|
58
|
+
<h2>No warranty</h2>
|
|
59
|
+
<p>To the maximum extent permitted by applicable law, the service and software are provided “as is” and “as available,” without warranties of uninterrupted operation or fitness for a particular purpose. Rights that cannot legally be excluded remain unaffected.</p>
|
|
60
|
+
|
|
61
|
+
<h2>Responsibility for actions</h2>
|
|
62
|
+
<p>You are responsible for commands and changes made through devices you authorize. To the maximum extent permitted by law, ReMCP is not responsible for indirect or consequential loss arising from device changes, lost data, third-party systems or service interruption.</p>
|
|
63
|
+
|
|
64
|
+
<h2>Termination and changes</h2>
|
|
65
|
+
<p>You may stop using the service and revoke devices at any time. Access may be suspended for security, abuse or legal reasons. Material changes to these Terms will be published at this URL with a new effective date.</p>
|
|
49
66
|
</article>
|
|
50
67
|
</main>
|
|
51
68
|
<footer class="site-footer">
|
|
@@ -53,7 +70,7 @@
|
|
|
53
70
|
<img class="brand-mark" src="/android-chrome-192x192.png" width="30" height="30" alt="" aria-hidden="true">
|
|
54
71
|
<span translate="no">ReMCP</span>
|
|
55
72
|
</div>
|
|
56
|
-
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/
|
|
73
|
+
<nav aria-label="Footer"><a href="/docs">Docs</a><a href="/security">Security</a><a href="/support">Support</a><a href="/privacy">Privacy</a><a href="/terms">Terms</a></nav>
|
|
57
74
|
<p>Open-source remote MCP infrastructure.</p>
|
|
58
75
|
</footer>
|
|
59
76
|
</body>
|