epistery 1.3.6 → 1.3.7
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/cli/epistery.mjs +130 -0
- package/default.ini +2 -19
- package/package.json +1 -1
package/cli/epistery.mjs
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Usage:
|
|
7
7
|
* epistery initialize <domain> Initialize domain with wallet
|
|
8
8
|
* epistery curl [options] <url> Make authenticated HTTP request
|
|
9
|
+
* epistery mcp [options] <url> Stdio MCP bridge with bot-auth
|
|
9
10
|
* epistery info [domain] Show domain information
|
|
10
11
|
* epistery set-default <domain> Set default domain for CLI
|
|
11
12
|
*
|
|
@@ -164,6 +165,9 @@ function showHelp() {
|
|
|
164
165
|
console.log(
|
|
165
166
|
" epistery initialize <domain> Initialize domain with wallet",
|
|
166
167
|
);
|
|
168
|
+
console.log(
|
|
169
|
+
" epistery mcp [-w domain] <url> Stdio MCP bridge with bot-auth",
|
|
170
|
+
);
|
|
167
171
|
console.log(
|
|
168
172
|
" epistery curl [options] <url> Make authenticated HTTP request",
|
|
169
173
|
);
|
|
@@ -225,6 +229,11 @@ function showHelp() {
|
|
|
225
229
|
" -p, --port <port> Server port (for localhost development)",
|
|
226
230
|
);
|
|
227
231
|
console.log("");
|
|
232
|
+
console.log("mcp options:");
|
|
233
|
+
console.log(
|
|
234
|
+
" -w, --wallet <domain> Use specific domain wallet (overrides default)",
|
|
235
|
+
);
|
|
236
|
+
console.log("");
|
|
228
237
|
console.log("curl options:");
|
|
229
238
|
console.log(
|
|
230
239
|
" -w, --wallet <domain> Use specific domain wallet (overrides default)",
|
|
@@ -261,6 +270,9 @@ function showHelp() {
|
|
|
261
270
|
console.log(" epistery approve localhost channel::premium 0x1234... member -p 3001");
|
|
262
271
|
console.log(" epistery deny localhost channel::premium 0x5678... -p 3001");
|
|
263
272
|
console.log("");
|
|
273
|
+
console.log(" # MCP bridge (use with Claude Code or any MCP client)");
|
|
274
|
+
console.log(" claude mcp add --transport stdio geist-social -- epistery mcp https://geist.social");
|
|
275
|
+
console.log("");
|
|
264
276
|
console.log(" # Make authenticated requests");
|
|
265
277
|
console.log(" epistery curl https://example.com/api/data");
|
|
266
278
|
console.log(' epistery curl --bot -X POST -d \'{"title":"Test"}\' <url>');
|
|
@@ -976,6 +988,112 @@ async function performCurl(options) {
|
|
|
976
988
|
}
|
|
977
989
|
}
|
|
978
990
|
|
|
991
|
+
/**
|
|
992
|
+
* MCP stdio bridge — reads JSON-RPC from stdin, POSTs to remote /mcp
|
|
993
|
+
* with bot-auth, writes responses to stdout.
|
|
994
|
+
*
|
|
995
|
+
* Usage: epistery mcp [-w domain] <url>
|
|
996
|
+
* claude mcp add --transport stdio my-site -- epistery mcp https://my-site.example
|
|
997
|
+
*/
|
|
998
|
+
async function performMcp(args) {
|
|
999
|
+
// Parse args: [-w domain] <url>
|
|
1000
|
+
let domain = null;
|
|
1001
|
+
let url = null;
|
|
1002
|
+
|
|
1003
|
+
for (let i = 0; i < args.length; i++) {
|
|
1004
|
+
const arg = args[i];
|
|
1005
|
+
if (arg === '-w' || arg === '--wallet') {
|
|
1006
|
+
domain = args[++i];
|
|
1007
|
+
} else if (!arg.startsWith('-')) {
|
|
1008
|
+
url = arg;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
if (!url) {
|
|
1013
|
+
console.error('Error: URL required');
|
|
1014
|
+
console.error('Usage: epistery mcp [-w domain] <url>');
|
|
1015
|
+
process.exit(1);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// Ensure URL ends without trailing slash, append /mcp if not present
|
|
1019
|
+
const mcpUrl = url.replace(/\/+$/, '').endsWith('/mcp')
|
|
1020
|
+
? url.replace(/\/+$/, '')
|
|
1021
|
+
: url.replace(/\/+$/, '') + '/mcp';
|
|
1022
|
+
|
|
1023
|
+
const wallet = CliWallet.load(domain);
|
|
1024
|
+
const fetch = (await import('node-fetch')).default;
|
|
1025
|
+
|
|
1026
|
+
// All log output to stderr so stdout stays clean for MCP JSON-RPC
|
|
1027
|
+
process.stderr.write(`[epistery-mcp] Bridge: ${wallet.address} -> ${mcpUrl}\n`);
|
|
1028
|
+
|
|
1029
|
+
const readline = await import('readline');
|
|
1030
|
+
const rl = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
1031
|
+
|
|
1032
|
+
for await (const line of rl) {
|
|
1033
|
+
if (!line.trim()) continue;
|
|
1034
|
+
|
|
1035
|
+
let msg;
|
|
1036
|
+
try {
|
|
1037
|
+
msg = JSON.parse(line);
|
|
1038
|
+
} catch {
|
|
1039
|
+
// Not valid JSON — ignore
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
const isNotification = msg.id === undefined || msg.id === null;
|
|
1044
|
+
|
|
1045
|
+
try {
|
|
1046
|
+
// Fresh bot-auth header per request (timestamp-based replay protection)
|
|
1047
|
+
const authHeader = await wallet.createBotAuthHeader();
|
|
1048
|
+
|
|
1049
|
+
const res = await fetch(mcpUrl, {
|
|
1050
|
+
method: 'POST',
|
|
1051
|
+
headers: {
|
|
1052
|
+
'Authorization': authHeader,
|
|
1053
|
+
'Content-Type': 'application/json',
|
|
1054
|
+
'Accept': 'application/json'
|
|
1055
|
+
},
|
|
1056
|
+
body: JSON.stringify(msg)
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
if (res.status === 204) {
|
|
1060
|
+
// No content (notification acknowledged) — nothing to write
|
|
1061
|
+
continue;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
const body = await res.text();
|
|
1065
|
+
|
|
1066
|
+
if (!res.ok) {
|
|
1067
|
+
// Server error — wrap in JSON-RPC error if this was a request
|
|
1068
|
+
if (!isNotification) {
|
|
1069
|
+
const errResponse = {
|
|
1070
|
+
jsonrpc: '2.0',
|
|
1071
|
+
error: { code: -32000, message: `HTTP ${res.status}: ${body}` },
|
|
1072
|
+
id: msg.id
|
|
1073
|
+
};
|
|
1074
|
+
process.stdout.write(JSON.stringify(errResponse) + '\n');
|
|
1075
|
+
}
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
if (body) {
|
|
1080
|
+
process.stdout.write(body.trim() + '\n');
|
|
1081
|
+
}
|
|
1082
|
+
} catch (err) {
|
|
1083
|
+
// Network error
|
|
1084
|
+
if (!isNotification) {
|
|
1085
|
+
const errResponse = {
|
|
1086
|
+
jsonrpc: '2.0',
|
|
1087
|
+
error: { code: -32000, message: err.message },
|
|
1088
|
+
id: msg.id
|
|
1089
|
+
};
|
|
1090
|
+
process.stdout.write(JSON.stringify(errResponse) + '\n');
|
|
1091
|
+
}
|
|
1092
|
+
process.stderr.write(`[epistery-mcp] Error: ${err.message}\n`);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
979
1097
|
async function main() {
|
|
980
1098
|
const command = process.argv[2];
|
|
981
1099
|
const rawArgs = process.argv.slice(3);
|
|
@@ -996,6 +1114,18 @@ async function main() {
|
|
|
996
1114
|
await initializeDomain(args[0]);
|
|
997
1115
|
break;
|
|
998
1116
|
|
|
1117
|
+
case "mcp":
|
|
1118
|
+
if (rawArgs.length === 0) {
|
|
1119
|
+
console.error("Error: URL required");
|
|
1120
|
+
console.error("Usage: epistery mcp [-w domain] <url>");
|
|
1121
|
+
console.error("");
|
|
1122
|
+
console.error("Stdio MCP bridge with bot-auth. Register with Claude Code:");
|
|
1123
|
+
console.error(" claude mcp add --transport stdio my-site -- epistery mcp https://my-site.example");
|
|
1124
|
+
process.exit(1);
|
|
1125
|
+
}
|
|
1126
|
+
await performMcp(rawArgs);
|
|
1127
|
+
break;
|
|
1128
|
+
|
|
999
1129
|
case "curl":
|
|
1000
1130
|
if (rawArgs.length === 0) {
|
|
1001
1131
|
console.error("Error: URL required");
|
package/default.ini
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[profile]
|
|
2
|
-
name=
|
|
3
|
-
email=
|
|
2
|
+
name=Rootz Corp
|
|
3
|
+
email=support@rootz.global
|
|
4
4
|
|
|
5
5
|
[ipfs]
|
|
6
6
|
url=https://rootz.digital/api/v0
|
|
@@ -12,20 +12,3 @@ rpc=https://eth.llamarpc.com
|
|
|
12
12
|
nativeCurrencyName=Ether
|
|
13
13
|
nativeCurrencySymbol=ETH
|
|
14
14
|
nativeCurrencyDecimals=18
|
|
15
|
-
|
|
16
|
-
; Additional supported chains:
|
|
17
|
-
; Polygon Mainnet (POL):
|
|
18
|
-
; chainId=137
|
|
19
|
-
; name=Polygon Mainnet
|
|
20
|
-
; rpc=https://polygon-rpc.com
|
|
21
|
-
; nativeCurrencyName=POL
|
|
22
|
-
; nativeCurrencySymbol=POL
|
|
23
|
-
; nativeCurrencyDecimals=18
|
|
24
|
-
;
|
|
25
|
-
; Japan Open Chain (JOC):
|
|
26
|
-
; chainId=81
|
|
27
|
-
; name=Japan Open Chain
|
|
28
|
-
; rpc=https://rpc-2.japanopenchain.org:8545
|
|
29
|
-
; nativeCurrencyName=Japan Open Chain Token
|
|
30
|
-
; nativeCurrencySymbol=JOC
|
|
31
|
-
; nativeCurrencyDecimals=18
|
package/package.json
CHANGED