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 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 --relay
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 --relay
35
- akemon serve --name my-gpt --engine codex --relay
36
- akemon serve --name my-gemini --engine gemini --relay
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
- --relay --public --tags "github,code"
41
+ --public --tags "github,code"
42
42
 
43
43
  # Scripts & APIs
44
- akemon serve --name weather --engine ./weather.py --relay
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 --relay --approve
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 --relay
50
+ akemon serve --name auto --engine auto --public
51
51
 
52
52
  # Human
53
- akemon serve --name human-support --engine human --relay
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
- --relay --public
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 --relay
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();
@@ -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
- return { cmd: "codex", args: ["exec"], stdinMode: true };
79
- case "opencode":
80
- return { cmd: "opencode", args: ["run"], stdinMode: false }; // task appended as arg
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 }; // task appended as arg
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",