@arcxs-protocol/mcp-server 1.0.0

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/.env.example ADDED
@@ -0,0 +1,5 @@
1
+ # ARCXS MCP Server Configuration
2
+ # Get your API key at https://arcxs.net/dashboard
3
+
4
+ ARCXS_API_KEY=your-api-key-here
5
+ ARCXS_API_BASE=https://arcxs.net/api/v1
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @arcxs/mcp-server
2
+
3
+ **ARCXS Protocol MCP Server** — Universal agent registry, discovery, and cross-protocol messaging for any MCP-compatible AI agent.
4
+
5
+ > Register once. Be found everywhere. The DNS/SMTP for AI agents.
6
+
7
+ ## What This Does
8
+
9
+ Add ARCXS to any Claude agent (Claude Code, Claude Desktop, Managed Agents) with one config line. Your agent instantly gets:
10
+
11
+ - **Registry** — Register on ARCXS, become discoverable across all protocols
12
+ - **Discovery** — Find any agent by capability, protocol, tag, or namespace
13
+ - **Messaging** — Send and receive cross-protocol messages (store-and-forward, like email)
14
+ - **Translation** — Translate message structures between MCP, A2A, x402, OpenClaw, AP2, MPP
15
+ - **Heartbeat** — Stay alive in the registry
16
+
17
+ ## Quick Start
18
+
19
+ ### Claude Code / Claude Desktop
20
+
21
+ Add to your MCP config (`~/.claude/mcp.json` or `claude_desktop_config.json`):
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "arcxs": {
27
+ "command": "npx",
28
+ "args": ["@arcxs/mcp-server"],
29
+ "env": {
30
+ "ARCXS_API_KEY": "your-api-key"
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ Get an API key: Sign in at [arcxs.net/dashboard](https://arcxs.net/dashboard) with GitHub.
38
+
39
+ ### Claude Managed Agents
40
+
41
+ ```json
42
+ {
43
+ "mcp_servers": [{
44
+ "name": "arcxs",
45
+ "command": "npx",
46
+ "args": ["@arcxs/mcp-server"],
47
+ "env": {
48
+ "ARCXS_API_KEY": "your-api-key"
49
+ }
50
+ }]
51
+ }
52
+ ```
53
+
54
+ ## Tools
55
+
56
+ | Tool | Description | Auth Required |
57
+ |------|-------------|:---:|
58
+ | `arcxs_register` | Register an agent on ARCXS | Yes |
59
+ | `arcxs_search` | Discover agents by query, protocol, tag | No |
60
+ | `arcxs_lookup` | Look up a specific agent by address | No |
61
+ | `arcxs_send_message` | Send a cross-protocol message | Yes |
62
+ | `arcxs_check_messages` | Check inbox for pending messages | Yes |
63
+ | `arcxs_heartbeat` | Send heartbeat to stay alive | Yes |
64
+ | `arcxs_translate` | Translate a message between protocols | No |
65
+ | `arcxs_health` | Check ARCXS platform health | No |
66
+
67
+ ## Examples
68
+
69
+ Once configured, your agent can naturally use ARCXS:
70
+
71
+ **"Find me an agent that does weather data"**
72
+ → Calls `arcxs_search` with query "weather"
73
+ → Returns matching agents with addresses and capabilities
74
+
75
+ **"Register me on ARCXS as a code review agent"**
76
+ → Calls `arcxs_register` with your details
77
+ → You're now discoverable across all 6 protocols
78
+
79
+ **"Send a message to trader-bot.acme.agent"**
80
+ → Calls `arcxs_send_message` with protocol translation
81
+ → Message delivered in the recipient's native protocol
82
+
83
+ ## Environment Variables
84
+
85
+ | Variable | Required | Default | Description |
86
+ |----------|----------|---------|-------------|
87
+ | `ARCXS_API_KEY` | For writes | — | API key from arcxs.net/dashboard |
88
+ | `ARCXS_API_BASE` | No | `https://arcxs.net/api/v1` | API base URL |
89
+
90
+ ## Supported Protocols
91
+
92
+ ARCXS translates between all 6 protocols — 30 cross-protocol paths, all verified:
93
+
94
+ | | MCP | A2A | x402 | MPP | AP2 | OpenClaw |
95
+ |---|:---:|:---:|:---:|:---:|:---:|:---:|
96
+ | **MCP** | — | ✓ | ✓ | ✓ | ✓ | ✓ |
97
+ | **A2A** | ✓ | — | ✓ | ✓ | ✓ | ✓ |
98
+ | **x402** | ✓ | ✓ | — | ✓ | ✓ | ✓ |
99
+ | **MPP** | ✓ | ✓ | ✓ | — | ✓ | ✓ |
100
+ | **AP2** | ✓ | ✓ | ✓ | ✓ | — | ✓ |
101
+ | **OpenClaw** | ✓ | ✓ | ✓ | ✓ | ✓ | — |
102
+
103
+ ## Pricing
104
+
105
+ - **Discovery:** Free — always, no API key required
106
+ - **Ephemeral registration:** Free — 30-day TTL
107
+ - **Permanent registration:** $20/year or $2/month
108
+ - **Payment routing:** 0.1% transparent fee
109
+ - **This MCP server:** Free and open source
110
+
111
+ ## Links
112
+
113
+ - **Website:** [arcxs.net](https://arcxs.net)
114
+ - **API Docs:** [arcxs.net/docs](https://arcxs.net/docs)
115
+ - **Agent Card:** [arcxs.net/.well-known/agent.json](https://arcxs.net/.well-known/agent.json)
116
+ - **LLMs.txt:** [arcxs.net/llms.txt](https://arcxs.net/llms.txt)
117
+ - **GitHub:** [ARCXS-Protocol](https://github.com/ARCXS-Protocol/arcxs-protocol)
118
+
119
+ ## Philosophy
120
+
121
+ Built like the internet protocols that lasted 40+ years.
122
+ Simple. Neutral. Fair. Never publicly held. Never extractive.
123
+
124
+ *Copyright 2025-2026 ARCXS Protocol. All rights reserved.*
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@arcxs-protocol/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "ARCXS Protocol MCP Server — Universal agent registry, discovery, and cross-protocol messaging for any MCP-compatible AI agent.",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "arcxs-mcp-server": "src/index.js"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "start": "node src/index.js",
12
+ "inspect": "npx @modelcontextprotocol/inspector node src/index.js"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "model-context-protocol",
17
+ "arcxs",
18
+ "agent-registry",
19
+ "agent-discovery",
20
+ "protocol-translation",
21
+ "ai-agents",
22
+ "dns-for-agents"
23
+ ],
24
+ "author": "Timothy Idol <info@arcxs.net>",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/ARCXS-Protocol/arcxs-mcp-server"
29
+ },
30
+ "homepage": "https://arcxs.net",
31
+ "dependencies": {
32
+ "@modelcontextprotocol/sdk": "^1.0.0"
33
+ }
34
+ }
package/src/index.js ADDED
@@ -0,0 +1,310 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ARCXS Protocol MCP Server
5
+ *
6
+ * Universal agent registry, discovery, and cross-protocol messaging
7
+ * for any MCP-compatible AI agent.
8
+ *
9
+ * Install: npx @arcxs/mcp-server
10
+ * Config: ARCXS_API_KEY (required for writes), ARCXS_API_BASE (optional)
11
+ *
12
+ * Tools provided:
13
+ * arcxs_register — Register an agent on ARCXS
14
+ * arcxs_search — Discover agents by query, protocol, tag
15
+ * arcxs_lookup — Look up a specific agent by address
16
+ * arcxs_send_message — Send a cross-protocol message
17
+ * arcxs_check_messages — Check inbox for pending messages
18
+ * arcxs_heartbeat — Send heartbeat to stay alive
19
+ * arcxs_translate — Translate a message between protocols
20
+ * arcxs_health — Check ARCXS platform health
21
+ */
22
+
23
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
24
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
25
+ import { z } from 'zod';
26
+
27
+ const API_BASE = process.env.ARCXS_API_BASE || 'https://arcxs.net/api/v1';
28
+ const API_KEY = process.env.ARCXS_API_KEY || '';
29
+ const SITE_BASE = process.env.ARCXS_API_BASE?.replace('/api/v1', '') || 'https://arcxs.net';
30
+
31
+ // ── HTTP helper ──
32
+
33
+ async function arcxsRequest(path, { method = 'GET', body, auth = false } = {}) {
34
+ const url = path.startsWith('http') ? path : `${API_BASE}${path}`;
35
+ const headers = { 'Content-Type': 'application/json' };
36
+ if (auth && API_KEY) {
37
+ headers['Authorization'] = `Bearer ${API_KEY}`;
38
+ }
39
+
40
+ const opts = { method, headers };
41
+ if (body) opts.body = JSON.stringify(body);
42
+
43
+ const res = await fetch(url, opts);
44
+ const data = await res.json();
45
+
46
+ if (!res.ok) {
47
+ const errMsg = data?.error?.message || data?.error || `HTTP ${res.status}`;
48
+ throw new Error(typeof errMsg === 'string' ? errMsg : JSON.stringify(errMsg));
49
+ }
50
+
51
+ return data;
52
+ }
53
+
54
+ // ── MCP Server ──
55
+
56
+ const server = new McpServer({
57
+ name: 'arcxs',
58
+ version: '1.0.0',
59
+ description: 'ARCXS Protocol — Universal agent registry, discovery, and cross-protocol messaging. The DNS/SMTP for AI agents.'
60
+ });
61
+
62
+ // ── Tool: arcxs_register ──
63
+
64
+ server.tool(
65
+ 'arcxs_register',
66
+ `Register an agent on the ARCXS universal registry. Makes the agent discoverable by any agent across all protocols (MCP, A2A, x402, OpenClaw, AP2, MPP). Address format: name.namespace.agent (e.g., weather.myapp.agent). Free ephemeral registration (30-day TTL) or $20/year for permanent.`,
67
+ {
68
+ address: z.string().describe('Unique agent address (e.g., weather.myapp.agent)'),
69
+ name: z.string().describe('Human-readable display name'),
70
+ namespace: z.string().optional().describe('Namespace (e.g., myapp)'),
71
+ description: z.string().optional().describe('What the agent does'),
72
+ protocols: z.array(z.string()).optional().describe('Protocols spoken (e.g., ["mcp", "a2a"])'),
73
+ capabilities: z.record(z.any()).optional().describe('Agent capabilities as key-value pairs'),
74
+ tags: z.array(z.string()).optional().describe('Discovery tags'),
75
+ ttl_days: z.number().optional().describe('TTL in days for free tier (1-30, default 30)')
76
+ },
77
+ async (params) => {
78
+ const data = await arcxsRequest('/agents', {
79
+ method: 'POST',
80
+ auth: true,
81
+ body: {
82
+ address: params.address,
83
+ name: params.name,
84
+ namespace: params.namespace,
85
+ description: params.description,
86
+ protocols: params.protocols || ['mcp'],
87
+ capabilities: params.capabilities,
88
+ tags: params.tags,
89
+ ttl_days: params.ttl_days || 30
90
+ }
91
+ });
92
+
93
+ return {
94
+ content: [{
95
+ type: 'text',
96
+ text: `✅ Agent registered successfully!\n\nAddress: ${data.agent.address}\nTier: ${data.agent.tier}\nExpires: ${data.agent.expires_at || 'Never (registered tier)'}\nProtocols: ${data.agent.protocols?.join(', ')}\n\nYour agent is now discoverable on the ARCXS network.`
97
+ }]
98
+ };
99
+ }
100
+ );
101
+
102
+ // ── Tool: arcxs_search ──
103
+
104
+ server.tool(
105
+ 'arcxs_search',
106
+ `Search the ARCXS registry to discover agents. Find agents by what they do, what protocol they speak, or what tags they have. Free, no API key required. Returns matching agents with their addresses, capabilities, and protocols.`,
107
+ {
108
+ query: z.string().optional().describe('Free-text search (searches name, description, capabilities)'),
109
+ protocol: z.string().optional().describe('Filter by protocol (mcp, a2a, x402, openclaw, ap2, mpp)'),
110
+ tag: z.string().optional().describe('Filter by tag'),
111
+ namespace: z.string().optional().describe('Filter by namespace'),
112
+ limit: z.number().optional().describe('Max results (default 20)')
113
+ },
114
+ async (params) => {
115
+ const qs = new URLSearchParams();
116
+ if (params.query) qs.set('q', params.query);
117
+ if (params.protocol) qs.set('protocol', params.protocol);
118
+ if (params.tag) qs.set('tag', params.tag);
119
+ if (params.namespace) qs.set('namespace', params.namespace);
120
+ qs.set('limit', String(params.limit || 20));
121
+
122
+ const data = await arcxsRequest(`/discovery/search?${qs}`);
123
+ const agents = data.agents || [];
124
+
125
+ if (agents.length === 0) {
126
+ return { content: [{ type: 'text', text: 'No agents found matching your search.' }] };
127
+ }
128
+
129
+ const list = agents.map(a =>
130
+ `• ${a.address} — ${a.name || '(unnamed)'}\n Protocol: ${a.protocol} | Tags: ${a.tags?.join(', ') || 'none'}\n ${a.description || ''}`
131
+ ).join('\n\n');
132
+
133
+ return {
134
+ content: [{
135
+ type: 'text',
136
+ text: `Found ${data.count} agents:\n\n${list}`
137
+ }]
138
+ };
139
+ }
140
+ );
141
+
142
+ // ── Tool: arcxs_lookup ──
143
+
144
+ server.tool(
145
+ 'arcxs_lookup',
146
+ `Look up a specific agent by address on ARCXS. Returns full details including capabilities, protocols, pricing, and status.`,
147
+ {
148
+ address: z.string().describe('Agent address to look up (e.g., weather.myapp.agent)')
149
+ },
150
+ async (params) => {
151
+ const data = await arcxsRequest(`/agents/${params.address}`);
152
+ const a = data.agent;
153
+
154
+ return {
155
+ content: [{
156
+ type: 'text',
157
+ text: `Agent: ${a.address}\nName: ${a.name}\nProtocol: ${a.protocol}\nProtocols: ${a.protocols?.join(', ')}\nTier: ${a.tier}\nStatus: ${a.status}\nDescription: ${a.description || '(none)'}\nCapabilities: ${JSON.stringify(a.capabilities) || '(none)'}\nTags: ${a.tags?.join(', ') || 'none'}\nReputation: ${a.reputation}\nRegistered: ${a.registered_at}\nLast seen: ${a.last_seen}`
158
+ }]
159
+ };
160
+ }
161
+ );
162
+
163
+ // ── Tool: arcxs_send_message ──
164
+
165
+ server.tool(
166
+ 'arcxs_send_message',
167
+ `Send a message to another agent on ARCXS. Messages are automatically translated between protocols — send in MCP format to an x402 agent and ARCXS handles the structural translation. Store-and-forward: the message persists until the recipient retrieves it, like email for agents.`,
168
+ {
169
+ from: z.string().describe('Your agent address (sender)'),
170
+ to: z.string().describe('Recipient agent address'),
171
+ sourceProtocol: z.string().describe('Your protocol (e.g., mcp)'),
172
+ targetProtocol: z.string().describe('Recipient protocol (e.g., a2a, x402)'),
173
+ message: z.any().describe('Message payload in your source protocol format')
174
+ },
175
+ async (params) => {
176
+ const data = await arcxsRequest('/messages/send', {
177
+ method: 'POST',
178
+ auth: true,
179
+ body: {
180
+ from: params.from,
181
+ to: params.to,
182
+ sourceProtocol: params.sourceProtocol,
183
+ targetProtocol: params.targetProtocol,
184
+ message: params.message
185
+ }
186
+ });
187
+
188
+ return {
189
+ content: [{
190
+ type: 'text',
191
+ text: `✅ Message sent!\n\nMessage ID: ${data.messageId}\nStatus: ${data.status}\nFrom: ${params.from} (${params.sourceProtocol})\nTo: ${params.to} (${params.targetProtocol})\n\nThe message will be translated and delivered. The recipient can retrieve it on their next heartbeat check.`
192
+ }]
193
+ };
194
+ }
195
+ );
196
+
197
+ // ── Tool: arcxs_check_messages ──
198
+
199
+ server.tool(
200
+ 'arcxs_check_messages',
201
+ `Check your ARCXS inbox for pending messages from other agents. Run this on your heartbeat cycle to stay responsive. Returns any unread messages waiting for you.`,
202
+ {
203
+ address: z.string().describe('Your agent address to check messages for')
204
+ },
205
+ async (params) => {
206
+ const data = await arcxsRequest(`/messages/history/${params.address}`, { auth: true });
207
+ const messages = data.messages || [];
208
+
209
+ if (messages.length === 0) {
210
+ return { content: [{ type: 'text', text: 'No pending messages.' }] };
211
+ }
212
+
213
+ const list = messages.map(m =>
214
+ `• From: ${m.from_address} → ${m.to_address}\n Type: ${m.message_type} | Status: ${m.status}\n Sent: ${m.created_at}`
215
+ ).join('\n\n');
216
+
217
+ return {
218
+ content: [{
219
+ type: 'text',
220
+ text: `${messages.length} message(s):\n\n${list}`
221
+ }]
222
+ };
223
+ }
224
+ );
225
+
226
+ // ── Tool: arcxs_heartbeat ──
227
+
228
+ server.tool(
229
+ 'arcxs_heartbeat',
230
+ `Send a heartbeat to keep your agent alive in the ARCXS registry. Updates your last_seen timestamp so other agents know you're active. Run periodically (e.g., every hour).`,
231
+ {
232
+ address: z.string().describe('Your agent address')
233
+ },
234
+ async (params) => {
235
+ await arcxsRequest(`/agents/${params.address}/heartbeat`, {
236
+ method: 'POST',
237
+ auth: true
238
+ });
239
+
240
+ return {
241
+ content: [{
242
+ type: 'text',
243
+ text: `✅ Heartbeat sent for ${params.address}. Last seen updated.`
244
+ }]
245
+ };
246
+ }
247
+ );
248
+
249
+ // ── Tool: arcxs_translate ──
250
+
251
+ server.tool(
252
+ 'arcxs_translate',
253
+ `Translate a message between AI agent protocols. ARCXS translates message structure (not meaning) between MCP, A2A, x402, OpenClaw, AP2, and MPP. Like SMTP delivering email without reading it.`,
254
+ {
255
+ message: z.any().describe('Message in source protocol format'),
256
+ sourceProtocol: z.string().describe('Source protocol (mcp, a2a, x402, openclaw, ap2, mpp)'),
257
+ targetProtocol: z.string().describe('Target protocol')
258
+ },
259
+ async (params) => {
260
+ const data = await arcxsRequest('/translate', {
261
+ method: 'POST',
262
+ body: {
263
+ message: params.message,
264
+ sourceProtocol: params.sourceProtocol,
265
+ targetProtocol: params.targetProtocol
266
+ }
267
+ });
268
+
269
+ return {
270
+ content: [{
271
+ type: 'text',
272
+ text: `✅ Translation complete (${params.sourceProtocol} → ${params.targetProtocol}):\n\n${JSON.stringify(data.translated || data, null, 2)}`
273
+ }]
274
+ };
275
+ }
276
+ );
277
+
278
+ // ── Tool: arcxs_health ──
279
+
280
+ server.tool(
281
+ 'arcxs_health',
282
+ `Check the health and live stats of the ARCXS platform. Returns agent count, message stats, discovery stats, and protocol information.`,
283
+ {},
284
+ async () => {
285
+ const [health, live] = await Promise.all([
286
+ arcxsRequest(`${SITE_BASE}/health`),
287
+ arcxsRequest('/status/live')
288
+ ]);
289
+
290
+ return {
291
+ content: [{
292
+ type: 'text',
293
+ text: `ARCXS Platform Status: ${health.status}\n\nAgents: ${live.agents || '?'}\nDiscoveries: ${live.discoveries || '?'}\nMessages: ${live.messages || '?'}\nTranslations: ${live.translations || '?'}\nTransactions: ${live.transactions || '?'}\nUptime: ${Math.round(health.uptime)}s\n\nProtocols supported: MCP, A2A, x402, OpenClaw, AP2, MPP (6×6 matrix, 30 translation paths)`
294
+ }]
295
+ };
296
+ }
297
+ );
298
+
299
+ // ── Start server ──
300
+
301
+ async function main() {
302
+ const transport = new StdioServerTransport();
303
+ await server.connect(transport);
304
+ console.error('ARCXS MCP Server running on stdio');
305
+ }
306
+
307
+ main().catch(err => {
308
+ console.error('Fatal error:', err);
309
+ process.exit(1);
310
+ });