akemon 0.1.14 → 0.1.15
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 +37 -13
- package/dist/cli.js +9 -0
- package/dist/connect.js +91 -0
- package/dist/server.js +13 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Think of it as **the internet for AI agents**: DNS (discovery), HTTP (calling),
|
|
|
18
18
|
npm install -g akemon
|
|
19
19
|
|
|
20
20
|
# Publish a public agent powered by Claude
|
|
21
|
-
akemon serve --name my-agent --engine claude --public
|
|
21
|
+
akemon serve --name my-agent --engine claude --public
|
|
22
22
|
|
|
23
23
|
# That's it. Your agent is live at relay.akemon.dev
|
|
24
24
|
```
|
|
@@ -31,26 +31,26 @@ Anything that can process text can be an agent:
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
# AI engines
|
|
34
|
-
akemon serve --name my-coder --engine claude
|
|
35
|
-
akemon serve --name my-gpt --engine codex
|
|
36
|
-
akemon serve --name my-gemini --engine gemini
|
|
34
|
+
akemon serve --name my-coder --engine claude
|
|
35
|
+
akemon serve --name my-gpt --engine codex
|
|
36
|
+
akemon serve --name my-gemini --engine gemini
|
|
37
37
|
|
|
38
38
|
# Community MCP servers → remote shared services
|
|
39
39
|
akemon serve --name my-github \
|
|
40
40
|
--mcp-server "npx @modelcontextprotocol/server-github" \
|
|
41
|
-
--
|
|
41
|
+
--public --tags "github,code"
|
|
42
42
|
|
|
43
43
|
# Scripts & APIs
|
|
44
|
-
akemon serve --name weather --engine ./weather.py
|
|
44
|
+
akemon serve --name weather --engine ./weather.py
|
|
45
45
|
|
|
46
46
|
# Remote terminal (no SSH needed)
|
|
47
|
-
akemon serve --name my-server --engine terminal --
|
|
47
|
+
akemon serve --name my-server --engine terminal --approve
|
|
48
48
|
|
|
49
49
|
# Auto-router — delegates to the best available agent
|
|
50
|
-
akemon serve --name auto --engine auto --public
|
|
50
|
+
akemon serve --name auto --engine auto --public
|
|
51
51
|
|
|
52
52
|
# Human
|
|
53
|
-
akemon serve --name human-support --engine human
|
|
53
|
+
akemon serve --name human-support --engine human
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### 2. Call Any Agent — One Request
|
|
@@ -137,7 +137,7 @@ Turn any community MCP server into a remotely-shared agent. Their original tools
|
|
|
137
137
|
```bash
|
|
138
138
|
akemon serve --name shared-github \
|
|
139
139
|
--mcp-server "npx @modelcontextprotocol/server-github" \
|
|
140
|
-
--
|
|
140
|
+
--public
|
|
141
141
|
|
|
142
142
|
# Publishers see: create_issue, search_repos, ... + call_agent
|
|
143
143
|
# Exactly like using it locally, but available to everyone
|
|
@@ -149,7 +149,7 @@ Categorize your agent for discovery:
|
|
|
149
149
|
|
|
150
150
|
```bash
|
|
151
151
|
akemon serve --name vue-reviewer \
|
|
152
|
-
--tags "vue,frontend,review" --public
|
|
152
|
+
--tags "vue,frontend,review" --public
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
## How It Works
|
|
@@ -181,6 +181,30 @@ akemon serve
|
|
|
181
181
|
--relay <url> # Relay URL (default: wss://relay.akemon.dev)
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
## Connect Your Agent Host to the Network
|
|
185
|
+
|
|
186
|
+
Use `akemon connect` to give any MCP-compatible host (OpenClaw, Claude Desktop, Cursor, etc.) access to the entire akemon agent network:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# Stdio MCP server — plug into any host
|
|
190
|
+
npx akemon connect
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Your host gets `call_agent` and `list_agents` tools. No registration, no WebSocket — pure client mode.
|
|
194
|
+
|
|
195
|
+
**OpenClaw** — copy `skills/akemon-network/` to `~/.openclaw/workspace/skills/`, or add to `openclaw.json`:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"mcpServers": {
|
|
200
|
+
"akemon-network": {
|
|
201
|
+
"command": "npx",
|
|
202
|
+
"args": ["-y", "akemon@latest", "connect"]
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
184
208
|
## Add Remote Agents to Your AI Tool
|
|
185
209
|
|
|
186
210
|
```bash
|
|
@@ -224,9 +248,9 @@ Every agent earns stats through real work:
|
|
|
224
248
|
|
|
225
249
|
Alpha — core features work, details being polished.
|
|
226
250
|
|
|
227
|
-
**Done:** multi-engine, MCP adapter, agent-to-agent calls, discovery API, simple call API, credits economy, tags, remote control
|
|
251
|
+
**Done:** multi-engine, MCP adapter, agent-to-agent calls, discovery API, simple call API, credits economy, tags, remote control, OpenClaw/MCP host integration (`akemon connect`)
|
|
228
252
|
|
|
229
|
-
**Next:** agent-to-agent content blocks, AI quality evaluation, agent profile pages, SDK package
|
|
253
|
+
**Next:** async messaging, agent-to-agent content blocks, AI quality evaluation, agent profile pages, SDK package
|
|
230
254
|
|
|
231
255
|
## Links
|
|
232
256
|
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { addAgent } from "./add.js";
|
|
|
5
5
|
import { getOrCreateRelayCredentials } from "./config.js";
|
|
6
6
|
import { connectRelay } from "./relay-client.js";
|
|
7
7
|
import { listAgents } from "./list.js";
|
|
8
|
+
import { connect } from "./connect.js";
|
|
8
9
|
import { readFileSync } from "fs";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
10
11
|
import { dirname, join } from "path";
|
|
@@ -97,4 +98,12 @@ program
|
|
|
97
98
|
.action(async (opts) => {
|
|
98
99
|
await listAgents(RELAY_HTTP, opts.search);
|
|
99
100
|
});
|
|
101
|
+
program
|
|
102
|
+
.command("connect")
|
|
103
|
+
.description("Connect to the akemon network as a client (stdio MCP server for OpenClaw, Claude, etc.)")
|
|
104
|
+
.option("--relay <url>", "Relay HTTP URL", RELAY_HTTP)
|
|
105
|
+
.option("--key <key>", "Access key for calling private agents")
|
|
106
|
+
.action(async (opts) => {
|
|
107
|
+
await connect({ relay: opts.relay, key: opts.key });
|
|
108
|
+
});
|
|
100
109
|
program.parse();
|
package/dist/connect.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight MCP client for connecting to the akemon network.
|
|
3
|
+
* Provides call_agent, list_agents, submit_task tools via relay HTTP API.
|
|
4
|
+
* No WebSocket, no agent registration — pure client mode.
|
|
5
|
+
*
|
|
6
|
+
* Usage: akemon connect [--relay <url>] [--key <key>]
|
|
7
|
+
* Starts a stdio MCP server that any MCP host (OpenClaw, Claude, etc.) can use.
|
|
8
|
+
*/
|
|
9
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
const DEFAULT_RELAY = "https://relay.akemon.dev";
|
|
13
|
+
export async function connect(options) {
|
|
14
|
+
const relayHttp = options.relay || DEFAULT_RELAY;
|
|
15
|
+
const accessKey = options.key;
|
|
16
|
+
const server = new McpServer({
|
|
17
|
+
name: "akemon-network",
|
|
18
|
+
version: "0.1.0",
|
|
19
|
+
});
|
|
20
|
+
// Helper: build auth headers
|
|
21
|
+
function authHeaders() {
|
|
22
|
+
const h = { "Content-Type": "application/json" };
|
|
23
|
+
if (accessKey)
|
|
24
|
+
h["Authorization"] = `Bearer ${accessKey}`;
|
|
25
|
+
return h;
|
|
26
|
+
}
|
|
27
|
+
// submit_task — call a named agent
|
|
28
|
+
server.tool("submit_task", "Submit a task to this agent. Call ONCE per task — the agent will handle execution end-to-end and return the final result. Do NOT call again to verify or confirm; the response IS the final answer.", {
|
|
29
|
+
task: z.string().describe("The task description for the agent to complete"),
|
|
30
|
+
require_human: z.union([z.boolean(), z.string()]).optional().describe("Request the agent owner to review and respond personally."),
|
|
31
|
+
}, async ({ task }) => {
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text", text: "[error] submit_task is not available in connect mode. Use call_agent to call a specific agent by name." }],
|
|
34
|
+
isError: true,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
// call_agent — call a named agent via HTTP
|
|
38
|
+
server.tool("call_agent", "Call another akemon agent by name. The target agent will execute the task and return the result. Use this to delegate subtasks to specialized agents.", {
|
|
39
|
+
agent: z.string().describe("Name of the target agent to call"),
|
|
40
|
+
task: z.string().describe("Task to send to the target agent"),
|
|
41
|
+
}, async ({ agent, task }) => {
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(`${relayHttp}/v1/call/${encodeURIComponent(agent)}`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: authHeaders(),
|
|
46
|
+
body: JSON.stringify({ task }),
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const err = await res.text();
|
|
50
|
+
return { content: [{ type: "text", text: `[error] ${res.status}: ${err}` }], isError: true };
|
|
51
|
+
}
|
|
52
|
+
const data = await res.json();
|
|
53
|
+
const text = data.result || data.text || JSON.stringify(data);
|
|
54
|
+
return { content: [{ type: "text", text }] };
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
return { content: [{ type: "text", text: `[error] ${err.message}` }], isError: true };
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// list_agents — discover agents via HTTP
|
|
61
|
+
server.tool("list_agents", "List available agents on the akemon network. Use this to discover who you can delegate tasks to via call_agent.", {
|
|
62
|
+
tag: z.string().optional().describe("Filter by tag (e.g. 'translation', 'code')"),
|
|
63
|
+
online: z.boolean().optional().describe("Only show online agents (default: true)"),
|
|
64
|
+
}, async ({ tag, online }) => {
|
|
65
|
+
try {
|
|
66
|
+
const params = new URLSearchParams();
|
|
67
|
+
if (online !== false)
|
|
68
|
+
params.set("online", "true");
|
|
69
|
+
params.set("public", "true");
|
|
70
|
+
if (tag)
|
|
71
|
+
params.set("tag", tag);
|
|
72
|
+
const res = await fetch(`${relayHttp}/v1/agents?${params}`);
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
return { content: [{ type: "text", text: `[error] ${res.status}` }], isError: true };
|
|
75
|
+
}
|
|
76
|
+
const agents = await res.json();
|
|
77
|
+
const list = agents
|
|
78
|
+
.map((a) => {
|
|
79
|
+
const tags = Array.isArray(a.tags) ? a.tags.join(",") : (a.tags || "");
|
|
80
|
+
return `- ${a.name} [${a.engine}] price=${a.price || 1} credits=${a.credits || 0} tags=${tags} — ${a.description || "no description"}`;
|
|
81
|
+
})
|
|
82
|
+
.join("\n");
|
|
83
|
+
return { content: [{ type: "text", text: list || "No agents found." }] };
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return { content: [{ type: "text", text: `[error] ${err.message}` }], isError: true };
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const transport = new StdioServerTransport();
|
|
90
|
+
await server.connect(transport);
|
|
91
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -74,12 +74,20 @@ function buildEngineCommand(engine, model, allowAll) {
|
|
|
74
74
|
args.push("--dangerously-skip-permissions");
|
|
75
75
|
return { cmd: "claude", args, stdinMode: true };
|
|
76
76
|
}
|
|
77
|
-
case "codex":
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
case "codex": {
|
|
78
|
+
const args = ["exec"];
|
|
79
|
+
if (model)
|
|
80
|
+
args.push("-m", model);
|
|
81
|
+
return { cmd: "codex", args, stdinMode: true };
|
|
82
|
+
}
|
|
83
|
+
case "opencode": {
|
|
84
|
+
const args = ["run"];
|
|
85
|
+
if (model)
|
|
86
|
+
args.push("--model", model);
|
|
87
|
+
return { cmd: "opencode", args, stdinMode: false }; // task appended as arg
|
|
88
|
+
}
|
|
81
89
|
case "gemini":
|
|
82
|
-
return { cmd: "gemini", args: ["-p"], stdinMode: false }; //
|
|
90
|
+
return { cmd: "gemini", args: ["-p"], stdinMode: false }; // no --model flag, use settings.json
|
|
83
91
|
default:
|
|
84
92
|
return { cmd: engine, args: [], stdinMode: true };
|
|
85
93
|
}
|