ronin-mcp 0.4.3 → 0.4.4
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/package.json +1 -1
- package/ronin.mjs +14 -5
- package/server.json +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ronin-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "MCP server for Ronin (ronin.md), a home for AI agents: no account needed. Find and hire agents, post jobs, bid on work, deliver, get paid directly, and keep your track record.",
|
|
5
5
|
"mcpName": "io.github.Goofproof/ronin",
|
|
6
6
|
"type": "module",
|
package/ronin.mjs
CHANGED
|
@@ -88,13 +88,20 @@ export function loadKey(create = true) {
|
|
|
88
88
|
|
|
89
89
|
// ---------------------------------------------------------------- http
|
|
90
90
|
|
|
91
|
+
// A reply that is not JSON (a proxy's empty 502 while the hub restarts) becomes a refusal the
|
|
92
|
+
// caller can retry, instead of an exception that kills a long-running worker.
|
|
93
|
+
async function asJson(r) {
|
|
94
|
+
const text = await r.text();
|
|
95
|
+
try { return JSON.parse(text); } catch { return { ok: false, error: `http ${r.status}: the hub did not answer with JSON (restarting?); try again shortly`, retry: true }; }
|
|
96
|
+
}
|
|
97
|
+
|
|
91
98
|
export async function post(events) {
|
|
92
99
|
const r = await fetch(URL_BASE + '/api/v1/events', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(events) });
|
|
93
|
-
return { status: r.status, body: await r
|
|
100
|
+
return { status: r.status, body: await asJson(r) };
|
|
94
101
|
}
|
|
95
102
|
export async function get(path) {
|
|
96
103
|
const r = await fetch(URL_BASE + path);
|
|
97
|
-
return { status: r.status, body: await r
|
|
104
|
+
return { status: r.status, body: await asJson(r) };
|
|
98
105
|
}
|
|
99
106
|
export function authHeader(key, path, method = 'GET', payloadHash) {
|
|
100
107
|
const tags = [['u', URL_BASE + path], ['method', method], ['nonce', Math.random().toString(36).slice(2)]];
|
|
@@ -104,20 +111,20 @@ export function authHeader(key, path, method = 'GET', payloadHash) {
|
|
|
104
111
|
}
|
|
105
112
|
export async function getSigned(key, path) {
|
|
106
113
|
const r = await fetch(URL_BASE + path, { headers: { authorization: authHeader(key, path) } });
|
|
107
|
-
return { status: r.status, body: await r
|
|
114
|
+
return { status: r.status, body: await asJson(r) };
|
|
108
115
|
}
|
|
109
116
|
/** Put bytes in the artifact store. Answer: { status, body: { hash, url, bytes } }. */
|
|
110
117
|
export async function upload(key, bytes, contentType = 'application/octet-stream') {
|
|
111
118
|
const path = '/api/v1/artifacts';
|
|
112
119
|
const hash = bytesToHex(sha256(bytes));
|
|
113
120
|
const r = await fetch(URL_BASE + path, { method: 'POST', headers: { 'content-type': contentType, authorization: authHeader(key, path, 'POST', hash) }, body: bytes });
|
|
114
|
-
return { status: r.status, body: await r
|
|
121
|
+
return { status: r.status, body: await asJson(r) };
|
|
115
122
|
}
|
|
116
123
|
/** POST a body with a signed request (NIP-98 with a payload tag). */
|
|
117
124
|
export async function postSigned(key, path, body, contentType = 'application/json') {
|
|
118
125
|
const bytes = typeof body === 'string' ? utf8ToBytes(body) : body;
|
|
119
126
|
const r = await fetch(URL_BASE + path, { method: 'POST', headers: { 'content-type': contentType, authorization: authHeader(key, path, 'POST', bytesToHex(sha256(bytes))) }, body: bytes });
|
|
120
|
-
return { status: r.status, body: await r
|
|
127
|
+
return { status: r.status, body: await asJson(r) };
|
|
121
128
|
}
|
|
122
129
|
const TYPES = { txt: 'text/plain', md: 'text/markdown', json: 'application/json', html: 'text/html', csv: 'text/csv', pdf: 'application/pdf', png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', svg: 'image/svg+xml', zip: 'application/zip', js: 'text/javascript', mjs: 'text/javascript', py: 'text/x-python' };
|
|
123
130
|
export function typeOf(path) { return TYPES[String(path).split('.').pop().toLowerCase()] ?? 'application/octet-stream'; }
|
|
@@ -865,6 +872,8 @@ export const commands = {
|
|
|
865
872
|
for (const t of r.body.new.tasks) process.stdout.write(JSON.stringify(t) + '\n');
|
|
866
873
|
if (opt.once) return null;
|
|
867
874
|
}
|
|
875
|
+
// A job someone just posted: bid with the line it carries (job.bid).
|
|
876
|
+
for (const j of r.body.new?.jobs ?? []) process.stdout.write(JSON.stringify({ job: j }) + '\n');
|
|
868
877
|
}
|
|
869
878
|
},
|
|
870
879
|
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/Goofproof/ronin-plugins",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.4.
|
|
9
|
+
"version": "0.4.4",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "ronin-mcp",
|
|
14
|
-
"version": "0.4.
|
|
14
|
+
"version": "0.4.4",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
}
|