@silver886/mcp-proxy 0.2.4 → 0.2.6
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 +2 -1
- package/dist/host/agent.d.ts +2 -0
- package/dist/host/agent.js +135 -22
- package/dist/host/session.js +31 -2
- package/dist/proxy/core/constants.d.ts +4 -0
- package/dist/proxy/core/constants.js +46 -1
- package/dist/proxy/discovery/client.js +24 -11
- package/dist/proxy/pairing/config.js +13 -11
- package/dist/proxy/pairing/controller.d.ts +3 -0
- package/dist/proxy/pairing/controller.js +59 -6
- package/dist/proxy/pairing/http.js +11 -0
- package/dist/proxy/runtime/forwarder.js +22 -0
- package/dist/proxy/runtime/handlers.d.ts +5 -3
- package/dist/proxy/runtime/handlers.js +68 -12
- package/dist/proxy/runtime/restart.d.ts +17 -0
- package/dist/proxy/runtime/restart.js +119 -0
- package/dist/proxy/runtime/sse.js +6 -0
- package/dist/proxy/runtime/upstream-bridge.js +9 -3
- package/dist/proxy/server.js +13 -1
- package/dist/shared/protocol.d.ts +7 -0
- package/dist/shared/protocol.js +44 -0
- package/package.json +10 -3
- package/static/setup.js +86 -25
package/static/setup.js
CHANGED
|
@@ -92,22 +92,37 @@
|
|
|
92
92
|
const row = document.createElement('div');
|
|
93
93
|
row.className = 'host-row';
|
|
94
94
|
row.dataset.uid = host.uid;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
95
|
+
|
|
96
|
+
const head = document.createElement('div');
|
|
97
|
+
head.className = 'host-head';
|
|
98
|
+
const title = document.createElement('div');
|
|
99
|
+
title.className = 'host-id';
|
|
100
|
+
title.dataset.role = 'title';
|
|
101
|
+
title.textContent = `Host ${host.id || '(unnamed)'}`;
|
|
102
|
+
head.appendChild(title);
|
|
103
|
+
const removeBtn = document.createElement('button');
|
|
104
|
+
removeBtn.type = 'button';
|
|
105
|
+
removeBtn.className = 'host-remove';
|
|
106
|
+
removeBtn.dataset.action = 'remove';
|
|
107
|
+
removeBtn.textContent = 'Remove';
|
|
108
|
+
head.appendChild(removeBtn);
|
|
109
|
+
row.appendChild(head);
|
|
110
|
+
|
|
111
|
+
appendHostField(row, host.uid, 'id', 'text', host.id, 'Host ID', 'dev-laptop', {
|
|
112
|
+
pattern: '(?!.*__)[A-Za-z0-9._\\-]+',
|
|
113
|
+
title: "Letters, digits, '.', '_', '-'. Must not contain '__' and must be unique across hosts.",
|
|
114
|
+
});
|
|
115
|
+
appendHostField(row, host.uid, 'tunnelUrl', 'url', host.tunnelUrl, 'Tunnel URL', 'https://abc-xyz.trycloudflare.com');
|
|
116
|
+
appendHostField(row, host.uid, 'authToken', 'text', host.authToken, 'Auth Token', 'Paste token from host agent');
|
|
117
|
+
|
|
118
|
+
const status = document.createElement('div');
|
|
119
|
+
const statusClass = host.status.startsWith('Error') ? 'error'
|
|
120
|
+
: host.status.startsWith('Partial') ? 'partial'
|
|
121
|
+
: host.status ? 'ok' : '';
|
|
122
|
+
status.className = statusClass ? `host-status ${statusClass}` : 'host-status';
|
|
123
|
+
status.textContent = host.status;
|
|
124
|
+
row.appendChild(status);
|
|
125
|
+
|
|
111
126
|
container.appendChild(row);
|
|
112
127
|
}
|
|
113
128
|
// Hide remove button when there's only one row.
|
|
@@ -119,6 +134,28 @@
|
|
|
119
134
|
validateHostIdUniqueness();
|
|
120
135
|
}
|
|
121
136
|
|
|
137
|
+
// Build a label + input pair via DOM properties so user-supplied values
|
|
138
|
+
// can't escape attribute context. Template-literal interpolation with
|
|
139
|
+
// esc() escapes <, >, & only — quotes and apostrophes pass through and
|
|
140
|
+
// would let an upstream-supplied token break out of value="…".
|
|
141
|
+
function appendHostField(row, uid, field, type, value, labelText, placeholder, extras) {
|
|
142
|
+
const id = `${field}-${uid}`;
|
|
143
|
+
const label = document.createElement('label');
|
|
144
|
+
label.htmlFor = id;
|
|
145
|
+
label.textContent = labelText;
|
|
146
|
+
row.appendChild(label);
|
|
147
|
+
const input = document.createElement('input');
|
|
148
|
+
input.id = id;
|
|
149
|
+
input.type = type;
|
|
150
|
+
input.dataset.field = field;
|
|
151
|
+
input.value = value;
|
|
152
|
+
input.placeholder = placeholder;
|
|
153
|
+
input.required = true;
|
|
154
|
+
if (extras?.pattern) input.pattern = extras.pattern;
|
|
155
|
+
if (extras?.title) input.title = extras.title;
|
|
156
|
+
row.appendChild(input);
|
|
157
|
+
}
|
|
158
|
+
|
|
122
159
|
document.getElementById('hosts-container').addEventListener('input', (e) => {
|
|
123
160
|
const row = e.target.closest('.host-row');
|
|
124
161
|
if (!row) return;
|
|
@@ -583,15 +620,39 @@
|
|
|
583
620
|
const checked = honorPriors && priorSelections.selectedTools
|
|
584
621
|
? priorSelections.selectedTools.has(toolKey)
|
|
585
622
|
: true;
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
623
|
+
|
|
624
|
+
// Build via DOM properties so tool.name (sourced from an upstream
|
|
625
|
+
// MCP server, untrusted) can't escape attribute context. esc() only
|
|
626
|
+
// covers text-node escaping; a quote in tool.name would break out
|
|
627
|
+
// of data-tool="…" / id="…" / for="…" if interpolated as HTML.
|
|
628
|
+
const checkWrap = document.createElement('div');
|
|
629
|
+
checkWrap.className = 'tool-check';
|
|
630
|
+
const cb = document.createElement('input');
|
|
631
|
+
cb.type = 'checkbox';
|
|
632
|
+
cb.id = cbId;
|
|
633
|
+
cb.dataset.role = 'tool';
|
|
634
|
+
cb.dataset.host = hostId;
|
|
635
|
+
cb.dataset.server = serverName;
|
|
636
|
+
cb.dataset.tool = tool.name;
|
|
637
|
+
cb.checked = checked;
|
|
638
|
+
checkWrap.appendChild(cb);
|
|
639
|
+
item.appendChild(checkWrap);
|
|
640
|
+
|
|
641
|
+
const label = document.createElement('label');
|
|
642
|
+
label.className = 'tool-label';
|
|
643
|
+
label.htmlFor = cbId;
|
|
644
|
+
const nameSpan = document.createElement('span');
|
|
645
|
+
nameSpan.className = 'tool-name';
|
|
646
|
+
nameSpan.textContent = tool.name;
|
|
647
|
+
label.appendChild(nameSpan);
|
|
648
|
+
if (tool.description) {
|
|
649
|
+
const descSpan = document.createElement('span');
|
|
650
|
+
descSpan.className = 'tool-desc';
|
|
651
|
+
descSpan.textContent = tool.description;
|
|
652
|
+
label.appendChild(descSpan);
|
|
653
|
+
}
|
|
654
|
+
item.appendChild(label);
|
|
655
|
+
|
|
595
656
|
list.appendChild(item);
|
|
596
657
|
}
|
|
597
658
|
wrapper.appendChild(list);
|