@agentdomain/mcp-server 0.6.0 → 0.7.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/dist/index.js CHANGED
@@ -15,26 +15,28 @@
15
15
  * "args": ["-y", "@agentdomain/mcp-server"],
16
16
  * "env": {
17
17
  * "AGENTDOMAIN_API_URL": "https://agentdomain.app/api/v1",
18
- * "AGENT_PRIVATE_KEY": "0x..."
18
+ * "AGENT_PRIVATE_KEY": "0x...",
19
+ * "AGENTDOMAIN_BUILDER_CODE": "your_builder_code"
19
20
  * }
20
21
  * }
21
22
  * }
22
23
  * }
23
24
  */
24
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
25
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
26
- import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
27
- import { z } from "zod";
28
- import { AgentDomain } from "@agentdomain/sdk";
29
- import { DNS_RECORD_TYPES, dnsRecordSchema, dnsRecordObjectSchema, } from "@agentdomain/shared";
30
- import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_FRAMEWORKS, SUPPORTED_TLDS, } from "@agentdomain/shared/constants";
31
- import { createPublicClient, createWalletClient, http, } from "viem";
32
- import { privateKeyToAccount } from "viem/accounts";
33
- import { base, baseSepolia } from "viem/chains";
25
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
26
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
27
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
28
+ import { z } from 'zod';
29
+ import { AgentDomain, validateBuilderCode } from '@agentdomain/sdk';
30
+ import { DNS_RECORD_TYPES, dnsRecordSchema, dnsRecordObjectSchema, } from '@agentdomain/shared';
31
+ import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_FRAMEWORKS, SUPPORTED_TLDS, } from '@agentdomain/shared/constants';
32
+ import { createPublicClient, createWalletClient, http } from 'viem';
33
+ import { privateKeyToAccount } from 'viem/accounts';
34
+ import { base, baseSepolia } from 'viem/chains';
34
35
  const API_URL = process.env.AGENTDOMAIN_API_URL ?? AGENTDOMAIN_API_BASE_URL;
35
- const NETWORK = (process.env.AGENTDOMAIN_NETWORK ?? "base");
36
+ const NETWORK = (process.env.AGENTDOMAIN_NETWORK ?? 'base');
36
37
  const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
37
38
  const AGENTDOMAIN_API_KEY = process.env.AGENTDOMAIN_API_KEY;
39
+ const AGENTDOMAIN_BUILDER_CODE = process.env.AGENTDOMAIN_BUILDER_CODE;
38
40
  const RENEWAL_VAULT_ADDRESS = process.env.RENEWAL_VAULT_ADDRESS;
39
41
  function getClient() {
40
42
  const config = {
@@ -42,578 +44,523 @@ function getClient() {
42
44
  apiKey: AGENTDOMAIN_API_KEY,
43
45
  network: NETWORK,
44
46
  renewalVaultAddress: RENEWAL_VAULT_ADDRESS,
47
+ builderCode: AGENTDOMAIN_BUILDER_CODE,
45
48
  };
46
49
  if (AGENT_PRIVATE_KEY) {
47
50
  const account = privateKeyToAccount(AGENT_PRIVATE_KEY);
48
- const chain = NETWORK === "base" ? base : baseSepolia;
49
- const rpc = NETWORK === "base"
50
- ? "https://mainnet.base.org"
51
- : "https://sepolia.base.org";
51
+ const chain = NETWORK === 'base' ? base : baseSepolia;
52
+ const rpc = NETWORK === 'base' ? 'https://mainnet.base.org' : 'https://sepolia.base.org';
52
53
  // Cast: viem's deeply-generic types do not always match cleanly across
53
54
  // duplicated installs in monorepos. Behaviour is identical at runtime.
54
- config.walletClient = createWalletClient({
55
- account,
56
- chain,
57
- transport: http(rpc),
58
- });
59
- config.publicClient = createPublicClient({
60
- chain,
61
- transport: http(rpc),
62
- });
55
+ config.walletClient = createWalletClient({ account, chain, transport: http(rpc) });
56
+ config.publicClient = createPublicClient({ chain, transport: http(rpc) });
63
57
  }
64
58
  return new AgentDomain(config);
65
59
  }
66
- const server = new Server({ name: "agentdomain-mcp", version: "0.2.1" }, { capabilities: { tools: {} } });
60
+ const server = new Server({ name: 'agentdomain-mcp', version: '0.2.1' }, { capabilities: { tools: {} } });
67
61
  // ----------------------------------------------------------------------
68
62
  // TOOL DEFINITIONS
69
63
  // ----------------------------------------------------------------------
70
64
  const TOOLS = [
71
65
  {
72
- name: "check_domain_availability",
73
- description: "Check whether an agent domain (name + tld) is available for registration. Returns availability status and pricing.",
66
+ name: 'check_domain_availability',
67
+ description: 'Check whether an agent domain (name + tld) is available for registration. Returns availability status and pricing.',
74
68
  inputSchema: {
75
- type: "object",
69
+ type: 'object',
76
70
  properties: {
77
- name: {
78
- type: "string",
79
- description: 'The desired label, e.g. "myagent"',
80
- },
71
+ name: { type: 'string', description: 'The desired label, e.g. "myagent"' },
81
72
  tld: {
82
- type: "string",
73
+ type: 'string',
83
74
  enum: SUPPORTED_TLDS,
84
- description: "TLD",
75
+ description: 'TLD',
85
76
  },
86
77
  },
87
- required: ["name"],
78
+ required: ['name'],
88
79
  },
89
80
  },
90
81
  {
91
- name: "quote_registration",
92
- description: "Get a price quote for registering an agent identity bundle. Domain, DNS, email, SSL, AgentID NFT orchestration, and platform fee are included by default. Basename and ENS are optional.",
82
+ name: 'quote_registration',
83
+ description: 'Get a price quote for registering an agent identity bundle. Domain, DNS, email, SSL, AgentID NFT orchestration, and platform fee are included by default. Basename and ENS are optional.',
93
84
  inputSchema: {
94
- type: "object",
85
+ type: 'object',
95
86
  properties: {
96
- preferredName: { type: "string" },
97
- tld: { type: "string", enum: SUPPORTED_TLDS },
87
+ preferredName: { type: 'string' },
88
+ tld: { type: 'string', enum: SUPPORTED_TLDS },
98
89
  registerBasename: {
99
- type: "boolean",
100
- description: "Set false to skip Basename registration and cost.",
90
+ type: 'boolean',
91
+ description: 'Set false to skip Basename registration and cost.',
101
92
  default: true,
102
93
  },
103
94
  registerEns: {
104
- type: "boolean",
105
- description: "Set true to add ENS; false skips ENS cost.",
95
+ type: 'boolean',
96
+ description: 'Set true to add ENS; false skips ENS cost.',
106
97
  default: false,
107
98
  },
108
99
  emailEnabled: {
109
- type: "boolean",
110
- description: "Deprecated compatibility flag. Email is now always included.",
100
+ type: 'boolean',
101
+ description: 'Deprecated compatibility flag. Email is now always included.',
111
102
  default: true,
112
103
  },
113
104
  emailUsername: {
114
- type: "string",
115
- description: "Primary email username. Defaults to agent, producing agent@domain.",
116
- default: "agent",
105
+ type: 'string',
106
+ description: 'Primary email username. Defaults to agent, producing agent@domain.',
107
+ default: 'agent',
117
108
  },
118
109
  premiumPlan: {
119
- type: "string",
110
+ type: 'string',
120
111
  enum: SERVICE_PLAN_KEYS,
121
- default: "included",
122
- description: "Premium Plan to buy with registration.",
112
+ default: 'included',
113
+ description: 'Premium Plan to buy with registration.',
123
114
  },
124
- years: { type: "integer", default: 1, minimum: 1, maximum: 10 },
115
+ years: { type: 'integer', default: 1, minimum: 1, maximum: 10 },
125
116
  },
126
- required: ["preferredName"],
117
+ required: ['preferredName'],
127
118
  },
128
119
  },
129
120
  {
130
- name: "register_agent_identity",
131
- description: "Register a complete agent identity bundle. Domain, DNS, email, SSL, AgentID NFT orchestration, and platform fee are included by default. Basename and ENS are optional. Pays in USDC on Base. Requires AGENT_PRIVATE_KEY env var.",
121
+ name: 'register_agent_identity',
122
+ description: 'Register a complete agent identity bundle. Domain, DNS, email, SSL, AgentID NFT orchestration, and platform fee are included by default. Basename and ENS are optional. Pays in USDC on Base. Requires AGENT_PRIVATE_KEY env var.',
132
123
  inputSchema: {
133
- type: "object",
124
+ type: 'object',
134
125
  properties: {
135
- preferredName: { type: "string" },
136
- tld: { type: "string", enum: SUPPORTED_TLDS },
126
+ preferredName: { type: 'string' },
127
+ tld: { type: 'string', enum: SUPPORTED_TLDS },
137
128
  registerBasename: {
138
- type: "boolean",
139
- description: "Set false to skip Basename registration and cost.",
129
+ type: 'boolean',
130
+ description: 'Set false to skip Basename registration and cost.',
140
131
  default: true,
141
132
  },
142
- basenameLabel: {
143
- type: "string",
144
- description: "Optional alternate Basename label",
145
- },
133
+ basenameLabel: { type: 'string', description: 'Optional alternate Basename label' },
146
134
  registerEns: {
147
- type: "boolean",
148
- description: "Set true to add ENS; false skips ENS cost.",
135
+ type: 'boolean',
136
+ description: 'Set true to add ENS; false skips ENS cost.',
149
137
  default: false,
150
138
  },
151
- ensLabel: {
152
- type: "string",
153
- description: "Optional alternate ENS label",
154
- },
139
+ ensLabel: { type: 'string', description: 'Optional alternate ENS label' },
155
140
  ownerAddress: {
156
- type: "string",
157
- description: "Optional EVM address to receive NFT ownership",
141
+ type: 'string',
142
+ description: 'Optional EVM address to receive NFT ownership',
158
143
  },
159
144
  emailEnabled: {
160
- type: "boolean",
161
- description: "Deprecated compatibility flag. Email is now always included.",
145
+ type: 'boolean',
146
+ description: 'Deprecated compatibility flag. Email is now always included.',
162
147
  default: true,
163
148
  },
164
149
  emailUsername: {
165
- type: "string",
166
- description: "Primary email username. Defaults to agent, producing agent@domain.",
167
- default: "agent",
150
+ type: 'string',
151
+ description: 'Primary email username. Defaults to agent, producing agent@domain.',
152
+ default: 'agent',
168
153
  },
169
154
  premiumPlan: {
170
- type: "string",
155
+ type: 'string',
171
156
  enum: SERVICE_PLAN_KEYS,
172
- default: "included",
173
- description: "Premium Plan to buy with registration.",
174
- },
175
- years: { type: "integer", default: 1, minimum: 1, maximum: 10 },
176
- autoRenew: { type: "boolean", default: false },
177
- dnsTarget: {
178
- type: "string",
179
- description: "URL or IP to point the domain at",
157
+ default: 'included',
158
+ description: 'Premium Plan to buy with registration.',
180
159
  },
160
+ years: { type: 'integer', default: 1, minimum: 1, maximum: 10 },
161
+ autoRenew: { type: 'boolean', default: false },
162
+ dnsTarget: { type: 'string', description: 'URL or IP to point the domain at' },
181
163
  metadata: {
182
- type: "object",
164
+ type: 'object',
183
165
  properties: {
184
- name: { type: "string" },
185
- description: { type: "string" },
186
- capabilities: { type: "array", items: { type: "string" } },
187
- framework: { type: "string", enum: SUPPORTED_FRAMEWORKS },
188
- x402Endpoint: { type: "string" },
166
+ name: { type: 'string' },
167
+ description: { type: 'string' },
168
+ capabilities: { type: 'array', items: { type: 'string' } },
169
+ framework: { type: 'string', enum: SUPPORTED_FRAMEWORKS },
170
+ x402Endpoint: { type: 'string' },
189
171
  },
190
172
  },
191
173
  },
192
- required: ["preferredName"],
174
+ required: ['preferredName'],
193
175
  },
194
176
  },
195
177
  {
196
- name: "lookup_agent",
197
- description: "Look up agent identities by wallet address.",
178
+ name: 'lookup_agent',
179
+ description: 'Look up agent identities by wallet address.',
198
180
  inputSchema: {
199
- type: "object",
181
+ type: 'object',
200
182
  properties: {
201
- wallet: { type: "string", description: "0x wallet address" },
183
+ wallet: { type: 'string', description: '0x wallet address' },
202
184
  },
203
- required: ["wallet"],
185
+ required: ['wallet'],
204
186
  },
205
187
  },
206
188
  {
207
- name: "get_agent",
208
- description: "Get one agent identity by AgentDomain agent ID. Works with an agent-scoped API key.",
189
+ name: 'get_agent',
190
+ description: 'Get one agent identity by AgentDomain agent ID. Works with an agent-scoped API key.',
209
191
  inputSchema: {
210
- type: "object",
192
+ type: 'object',
211
193
  properties: {
212
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
194
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
213
195
  },
214
- required: ["agentId"],
196
+ required: ['agentId'],
215
197
  },
216
198
  },
217
199
  {
218
- name: "search_agents",
219
- description: "Search the public agent registry by name, capability, or framework.",
200
+ name: 'search_agents',
201
+ description: 'Search the public agent registry by name, capability, or framework.',
220
202
  inputSchema: {
221
- type: "object",
203
+ type: 'object',
222
204
  properties: {
223
- q: { type: "string", description: "Free-text query" },
224
- capability: { type: "string" },
205
+ q: { type: 'string', description: 'Free-text query' },
206
+ capability: { type: 'string' },
225
207
  framework: {
226
- type: "string",
208
+ type: 'string',
227
209
  enum: SUPPORTED_FRAMEWORKS,
228
210
  },
229
- limit: { type: "number", default: 20 },
211
+ limit: { type: 'number', default: 20 },
230
212
  },
231
213
  },
232
214
  },
233
215
  {
234
- name: "send_agent_email",
216
+ name: 'send_agent_email',
235
217
  description: "Send an email from an agent's address (requires email-enabled identity).",
236
218
  inputSchema: {
237
- type: "object",
219
+ type: 'object',
238
220
  properties: {
239
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
240
- to: { type: "string" },
241
- subject: { type: "string" },
242
- text: { type: "string" },
221
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
222
+ to: { type: 'string' },
223
+ subject: { type: 'string' },
224
+ text: { type: 'string' },
243
225
  fromAddress: {
244
- type: "string",
245
- description: "Optional primary or active alias address to send from.",
226
+ type: 'string',
227
+ description: 'Optional primary or active alias address to send from.',
246
228
  },
247
229
  },
248
- required: ["agentId", "to", "subject"],
230
+ required: ['agentId', 'to', 'subject'],
249
231
  },
250
232
  },
251
233
  {
252
- name: "update_primary_email",
253
- description: "Change the primary email username for an agent. The old primary address stops receiving new mail.",
234
+ name: 'update_primary_email',
235
+ description: 'Change the primary email username for an agent. The old primary address stops receiving new mail.',
254
236
  inputSchema: {
255
- type: "object",
237
+ type: 'object',
256
238
  properties: {
257
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
258
- username: {
259
- type: "string",
260
- description: "New primary local-part, e.g. agent or support",
261
- },
239
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
240
+ username: { type: 'string', description: 'New primary local-part, e.g. agent or support' },
262
241
  },
263
- required: ["agentId", "username"],
242
+ required: ['agentId', 'username'],
264
243
  },
265
244
  },
266
245
  {
267
- name: "send_agent_email_batch",
268
- description: "Queue up to 100 emails in one request; each recipient counts toward monthly usage.",
246
+ name: 'send_agent_email_batch',
247
+ description: 'Queue up to 100 emails in one request; each recipient counts toward monthly usage.',
269
248
  inputSchema: {
270
- type: "object",
249
+ type: 'object',
271
250
  properties: {
272
- agentId: { type: "string" },
251
+ agentId: { type: 'string' },
273
252
  messages: {
274
- type: "array",
253
+ type: 'array',
275
254
  maxItems: 100,
276
255
  items: {
277
- type: "object",
256
+ type: 'object',
278
257
  properties: {
279
- to: { type: "string" },
280
- subject: { type: "string" },
281
- text: { type: "string" },
282
- fromAddress: { type: "string" },
258
+ to: { type: 'string' },
259
+ subject: { type: 'string' },
260
+ text: { type: 'string' },
261
+ fromAddress: { type: 'string' },
283
262
  },
284
- required: ["to", "subject", "text"],
263
+ required: ['to', 'subject', 'text'],
285
264
  },
286
265
  },
287
- idempotencyKey: { type: "string" },
266
+ idempotencyKey: { type: 'string' },
288
267
  },
289
- required: ["agentId", "messages"],
268
+ required: ['agentId', 'messages'],
290
269
  },
291
270
  },
292
271
  {
293
- name: "get_agent_email_usage",
294
- description: "Get combined sent and received monthly quota usage and reset date.",
272
+ name: 'get_agent_email_usage',
273
+ description: 'Get combined sent and received monthly quota usage and reset date.',
295
274
  inputSchema: {
296
- type: "object",
297
- properties: { agentId: { type: "string" } },
298
- required: ["agentId"],
275
+ type: 'object',
276
+ properties: { agentId: { type: 'string' } },
277
+ required: ['agentId'],
299
278
  },
300
279
  },
301
280
  {
302
- name: "configure_email_webhook",
303
- description: "Configure the signed email.received webhook for an agent.",
281
+ name: 'configure_email_webhook',
282
+ description: 'Configure the signed email.received webhook for an agent.',
304
283
  inputSchema: {
305
- type: "object",
284
+ type: 'object',
306
285
  properties: {
307
- agentId: { type: "string" },
308
- url: { type: "string" },
309
- payloadMode: { type: "string", enum: ["metadata", "inline_text"] },
310
- enabled: { type: "boolean" },
286
+ agentId: { type: 'string' },
287
+ url: { type: 'string' },
288
+ payloadMode: { type: 'string', enum: ['metadata', 'inline_text'] },
289
+ enabled: { type: 'boolean' },
311
290
  },
312
- required: ["agentId", "url"],
291
+ required: ['agentId', 'url'],
313
292
  },
314
293
  },
315
294
  {
316
- name: "create_email_alias",
317
- description: "Create an extra receive-and-send email alias. Requires paid-plan alias capacity.",
295
+ name: 'create_email_alias',
296
+ description: 'Create an extra receive-and-send email alias. Requires paid-plan alias capacity.',
318
297
  inputSchema: {
319
- type: "object",
298
+ type: 'object',
320
299
  properties: {
321
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
322
- username: {
323
- type: "string",
324
- description: "Alias local-part, e.g. billing",
325
- },
300
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
301
+ username: { type: 'string', description: 'Alias local-part, e.g. billing' },
326
302
  },
327
- required: ["agentId", "username"],
303
+ required: ['agentId', 'username'],
328
304
  },
329
305
  },
330
306
  {
331
- name: "delete_email_alias",
332
- description: "Delete an active email alias from an agent.",
307
+ name: 'delete_email_alias',
308
+ description: 'Delete an active email alias from an agent.',
333
309
  inputSchema: {
334
- type: "object",
310
+ type: 'object',
335
311
  properties: {
336
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
337
- emailAddress: {
338
- type: "string",
339
- description: "Full alias address to delete",
340
- },
312
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
313
+ emailAddress: { type: 'string', description: 'Full alias address to delete' },
341
314
  },
342
- required: ["agentId", "emailAddress"],
315
+ required: ['agentId', 'emailAddress'],
343
316
  },
344
317
  },
345
318
  {
346
- name: "list_agent_email",
347
- description: "List received/sent text-only email messages for an email-enabled agent, including extracted verification codes.",
319
+ name: 'list_agent_email',
320
+ description: 'List received/sent text-only email messages for an email-enabled agent, including extracted verification codes.',
348
321
  inputSchema: {
349
- type: "object",
322
+ type: 'object',
350
323
  properties: {
351
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
352
- limit: { type: "number", default: 20 },
324
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
325
+ limit: { type: 'number', default: 20 },
353
326
  },
354
- required: ["agentId"],
327
+ required: ['agentId'],
355
328
  },
356
329
  },
357
330
  {
358
- name: "delete_agent_email",
359
- description: "Permanently delete one email message from an agent inbox.",
331
+ name: 'delete_agent_email',
332
+ description: 'Permanently delete one email message from an agent inbox.',
360
333
  inputSchema: {
361
- type: "object",
334
+ type: 'object',
362
335
  properties: {
363
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
364
- messageId: { type: "string", description: "Email message ID (UUID)" },
336
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
337
+ messageId: { type: 'string', description: 'Email message ID (UUID)' },
365
338
  },
366
- required: ["agentId", "messageId"],
339
+ required: ['agentId', 'messageId'],
367
340
  },
368
341
  },
369
342
  {
370
- name: "get_dns_capabilities",
371
- description: "Get the machine-readable Spaceship DNS types, fields, limits, and safety warnings supported by AgentDomain.",
343
+ name: 'get_dns_capabilities',
344
+ description: 'Get the machine-readable Spaceship DNS types, fields, limits, and safety warnings supported by AgentDomain.',
372
345
  inputSchema: {
373
- type: "object",
374
- properties: {
375
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
376
- },
377
- required: ["agentId"],
346
+ type: 'object',
347
+ properties: { agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' } },
348
+ required: ['agentId'],
378
349
  },
379
350
  },
380
351
  {
381
- name: "list_dns_records",
382
- description: "List Spaceship-backed DNS records for an agent domain.",
352
+ name: 'list_dns_records',
353
+ description: 'List Spaceship-backed DNS records for an agent domain.',
383
354
  inputSchema: {
384
- type: "object",
355
+ type: 'object',
385
356
  properties: {
386
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
357
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
387
358
  },
388
- required: ["agentId"],
359
+ required: ['agentId'],
389
360
  },
390
361
  },
391
362
  {
392
- name: "create_dns_record",
393
- description: "Create a user-managed DNS record and sync the full DNS state to Spaceship.",
363
+ name: 'create_dns_record',
364
+ description: 'Create a user-managed DNS record and sync the full DNS state to Spaceship.',
394
365
  inputSchema: {
395
- type: "object",
366
+ type: 'object',
396
367
  properties: {
397
- agentId: { type: "string" },
398
- type: { type: "string", enum: DNS_RECORD_TYPES },
399
- name: { type: "string" },
400
- value: {
401
- type: "string",
402
- description: "Legacy format; structured data is preferred",
403
- },
404
- data: {
405
- type: "object",
406
- description: "Type-specific structured DNS record data",
407
- },
408
- ttl: { type: "number", default: 3600 },
409
- priority: { type: "number" },
368
+ agentId: { type: 'string' },
369
+ type: { type: 'string', enum: DNS_RECORD_TYPES },
370
+ name: { type: 'string' },
371
+ value: { type: 'string', description: 'Legacy format; structured data is preferred' },
372
+ data: { type: 'object', description: 'Type-specific structured DNS record data' },
373
+ ttl: { type: 'number', default: 3600 },
374
+ priority: { type: 'number' },
410
375
  },
411
- required: ["agentId", "type", "name"],
376
+ required: ['agentId', 'type', 'name'],
412
377
  },
413
378
  },
414
379
  {
415
- name: "update_dns_record",
416
- description: "Update a user-managed DNS record and sync the DNS state to Spaceship.",
380
+ name: 'update_dns_record',
381
+ description: 'Update a user-managed DNS record and sync the DNS state to Spaceship.',
417
382
  inputSchema: {
418
- type: "object",
383
+ type: 'object',
419
384
  properties: {
420
- agentId: { type: "string" },
421
- recordId: { type: "string" },
422
- type: { type: "string", enum: DNS_RECORD_TYPES },
423
- name: { type: "string" },
424
- value: { type: "string" },
425
- data: {
426
- type: "object",
427
- description: "Type-specific structured DNS record data",
428
- },
429
- ttl: { type: "number" },
430
- priority: { type: "number" },
385
+ agentId: { type: 'string' },
386
+ recordId: { type: 'string' },
387
+ type: { type: 'string', enum: DNS_RECORD_TYPES },
388
+ name: { type: 'string' },
389
+ value: { type: 'string' },
390
+ data: { type: 'object', description: 'Type-specific structured DNS record data' },
391
+ ttl: { type: 'number' },
392
+ priority: { type: 'number' },
431
393
  },
432
- required: ["agentId", "recordId"],
394
+ required: ['agentId', 'recordId'],
433
395
  },
434
396
  },
435
397
  {
436
- name: "delete_dns_record",
437
- description: "Delete a user-managed DNS record and sync the DNS state to Spaceship.",
398
+ name: 'delete_dns_record',
399
+ description: 'Delete a user-managed DNS record and sync the DNS state to Spaceship.',
438
400
  inputSchema: {
439
- type: "object",
401
+ type: 'object',
440
402
  properties: {
441
- agentId: { type: "string" },
442
- recordId: { type: "string" },
403
+ agentId: { type: 'string' },
404
+ recordId: { type: 'string' },
443
405
  },
444
- required: ["agentId", "recordId"],
406
+ required: ['agentId', 'recordId'],
445
407
  },
446
408
  },
447
409
  {
448
- name: "change_dns_records",
449
- description: "Preview or apply an atomic DNS merge/replace batch. Apply requires the baseRevision returned by preview.",
410
+ name: 'change_dns_records',
411
+ description: 'Preview or apply an atomic DNS merge/replace batch. Apply requires the baseRevision returned by preview.',
450
412
  inputSchema: {
451
- type: "object",
413
+ type: 'object',
452
414
  properties: {
453
- agentId: { type: "string" },
454
- records: { type: "array", maxItems: 200, items: { type: "object" } },
455
- mode: { type: "string", enum: ["merge", "replace"], default: "merge" },
456
- dryRun: { type: "boolean", default: true },
457
- baseRevision: {
458
- type: "string",
459
- description: "Required when dryRun is false",
460
- },
415
+ agentId: { type: 'string' },
416
+ records: { type: 'array', maxItems: 200, items: { type: 'object' } },
417
+ mode: { type: 'string', enum: ['merge', 'replace'], default: 'merge' },
418
+ dryRun: { type: 'boolean', default: true },
419
+ baseRevision: { type: 'string', description: 'Required when dryRun is false' },
461
420
  },
462
- required: ["agentId", "records"],
421
+ required: ['agentId', 'records'],
463
422
  },
464
423
  },
465
424
  {
466
- name: "import_dns_zone",
467
- description: "Preview or apply a BIND zone import. System-managed records remain protected.",
425
+ name: 'import_dns_zone',
426
+ description: 'Preview or apply a BIND zone import. System-managed records remain protected.',
468
427
  inputSchema: {
469
- type: "object",
428
+ type: 'object',
470
429
  properties: {
471
- agentId: { type: "string" },
472
- zoneFile: {
473
- type: "string",
474
- description: "BIND zone text, maximum 256 KiB",
475
- },
476
- mode: { type: "string", enum: ["merge", "replace"], default: "merge" },
477
- dryRun: { type: "boolean", default: true },
478
- baseRevision: {
479
- type: "string",
480
- description: "Required when dryRun is false",
481
- },
430
+ agentId: { type: 'string' },
431
+ zoneFile: { type: 'string', description: 'BIND zone text, maximum 256 KiB' },
432
+ mode: { type: 'string', enum: ['merge', 'replace'], default: 'merge' },
433
+ dryRun: { type: 'boolean', default: true },
434
+ baseRevision: { type: 'string', description: 'Required when dryRun is false' },
482
435
  },
483
- required: ["agentId", "zoneFile"],
436
+ required: ['agentId', 'zoneFile'],
484
437
  },
485
438
  },
486
439
  {
487
- name: "export_dns_zone",
488
- description: "Export user-managed or permitted complete DNS state as a standard BIND zone file.",
440
+ name: 'export_dns_zone',
441
+ description: 'Export user-managed or permitted complete DNS state as a standard BIND zone file.',
489
442
  inputSchema: {
490
- type: "object",
443
+ type: 'object',
491
444
  properties: {
492
- agentId: { type: "string" },
493
- scope: { type: "string", enum: ["user", "all"], default: "user" },
445
+ agentId: { type: 'string' },
446
+ scope: { type: 'string', enum: ['user', 'all'], default: 'user' },
494
447
  },
495
- required: ["agentId"],
448
+ required: ['agentId'],
496
449
  },
497
450
  },
498
451
  {
499
- name: "reconfigure_ssl",
500
- description: "Rebuild the Cloudflare SaaS SSL hostname and sync required DNS validation records.",
452
+ name: 'reconfigure_ssl',
453
+ description: 'Rebuild the Cloudflare SaaS SSL hostname and sync required DNS validation records.',
501
454
  inputSchema: {
502
- type: "object",
455
+ type: 'object',
503
456
  properties: {
504
- agentId: { type: "string" },
457
+ agentId: { type: 'string' },
505
458
  },
506
- required: ["agentId"],
459
+ required: ['agentId'],
507
460
  },
508
461
  },
509
462
  {
510
- name: "fund_renewal_vault",
463
+ name: 'fund_renewal_vault',
511
464
  description: "Deposit USDC into an agent's renewal vault to keep its domain alive.",
512
465
  inputSchema: {
513
- type: "object",
466
+ type: 'object',
514
467
  properties: {
515
- agentId: { type: "string" },
516
- amountUsdc: {
517
- type: "string",
518
- description: 'USDC amount, e.g. "10.00"',
519
- },
468
+ agentId: { type: 'string' },
469
+ amountUsdc: { type: 'string', description: 'USDC amount, e.g. "10.00"' },
520
470
  },
521
- required: ["agentId", "amountUsdc"],
471
+ required: ['agentId', 'amountUsdc'],
522
472
  },
523
473
  },
524
474
  {
525
- name: "withdraw_renewal_vault",
526
- description: "Build the owner-signed withdrawal transaction for unused funds in an AgentID renewal vault.",
475
+ name: 'withdraw_renewal_vault',
476
+ description: 'Build the owner-signed withdrawal transaction for unused funds in an AgentID renewal vault.',
527
477
  inputSchema: {
528
- type: "object",
478
+ type: 'object',
529
479
  properties: {
530
- agentId: { type: "string" },
531
- amountUsdc: { type: "string", description: 'USDC amount, e.g. "5.00"' },
480
+ agentId: { type: 'string' },
481
+ amountUsdc: { type: 'string', description: 'USDC amount, e.g. "5.00"' },
532
482
  },
533
- required: ["agentId", "amountUsdc"],
483
+ required: ['agentId', 'amountUsdc'],
534
484
  },
535
485
  },
536
486
  {
537
- name: "get_renewal_status",
538
- description: "Get renewal vault status for an agent, including exact renewal amount, vault balance, missing deposit, expiry, and auto-renew readiness.",
487
+ name: 'get_renewal_status',
488
+ description: 'Get renewal vault status for an agent, including exact renewal amount, vault balance, missing deposit, expiry, and auto-renew readiness.',
539
489
  inputSchema: {
540
- type: "object",
490
+ type: 'object',
541
491
  properties: {
542
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
492
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
543
493
  },
544
- required: ["agentId"],
494
+ required: ['agentId'],
545
495
  },
546
496
  },
547
497
  {
548
- name: "get_service_plan",
549
- description: "Get the current AgentDomain Premium Plan, entitlement limits, billing interval, registry privacy, and recent purchases for one agent.",
498
+ name: 'get_service_plan',
499
+ description: 'Get the current AgentDomain Premium Plan, entitlement limits, billing interval, registry privacy, and recent purchases for one agent.',
550
500
  inputSchema: {
551
- type: "object",
501
+ type: 'object',
552
502
  properties: {
553
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
503
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
554
504
  },
555
- required: ["agentId"],
505
+ required: ['agentId'],
556
506
  },
557
507
  },
558
508
  {
559
- name: "purchase_service_plan",
560
- description: "Upgrade one agent to Starter, Pro, or Enterprise with x402 USDC. Requires AGENT_PRIVATE_KEY for the owner wallet.",
509
+ name: 'purchase_service_plan',
510
+ description: 'Upgrade one agent to Starter, Pro, or Enterprise with x402 USDC. Requires AGENT_PRIVATE_KEY for the owner wallet.',
561
511
  inputSchema: {
562
- type: "object",
512
+ type: 'object',
563
513
  properties: {
564
- agentId: { type: "string" },
565
- plan: { type: "string", enum: ["starter", "pro", "enterprise"] },
514
+ agentId: { type: 'string' },
515
+ plan: { type: 'string', enum: ['starter', 'pro', 'enterprise'] },
566
516
  planSku: {
567
- type: "string",
568
- description: "For Enterprise, e.g. enterprise-100000 through enterprise-5000000.",
517
+ type: 'string',
518
+ description: 'For Enterprise, e.g. enterprise-100000 through enterprise-5000000.',
569
519
  },
570
520
  },
571
- required: ["agentId", "plan"],
521
+ required: ['agentId', 'plan'],
572
522
  },
573
523
  },
574
524
  {
575
- name: "set_registry_visibility",
576
- description: "Hide or show one agent in the public AgentDomain registry. Hiding requires an active paid Premium Plan.",
525
+ name: 'set_registry_visibility',
526
+ description: 'Hide or show one agent in the public AgentDomain registry. Hiding requires an active paid Premium Plan.',
577
527
  inputSchema: {
578
- type: "object",
528
+ type: 'object',
579
529
  properties: {
580
- agentId: { type: "string" },
530
+ agentId: { type: 'string' },
581
531
  registryHidden: {
582
- type: "boolean",
583
- description: "true hides the agent from public registry/search; false makes it public",
532
+ type: 'boolean',
533
+ description: 'true hides the agent from public registry/search; false makes it public',
584
534
  },
585
535
  },
586
- required: ["agentId", "registryHidden"],
536
+ required: ['agentId', 'registryHidden'],
587
537
  },
588
538
  },
589
539
  {
590
- name: "schedule_service_plan_renewal",
591
- description: "Choose the exact Premium Plan SKU to charge at the next identity renewal, including any Enterprise email tier.",
540
+ name: 'schedule_service_plan_renewal',
541
+ description: 'Choose the exact Premium Plan SKU to charge at the next identity renewal, including any Enterprise email tier.',
592
542
  inputSchema: {
593
- type: "object",
543
+ type: 'object',
594
544
  properties: {
595
- agentId: { type: "string" },
596
- plan: {
597
- type: "string",
598
- enum: ["included", "starter", "pro", "enterprise"],
599
- },
545
+ agentId: { type: 'string' },
546
+ plan: { type: 'string', enum: ['included', 'starter', 'pro', 'enterprise'] },
600
547
  planSku: {
601
- type: "string",
602
- description: "Exact SKU; Enterprise examples range from enterprise-100000 to enterprise-5000000.",
548
+ type: 'string',
549
+ description: 'Exact SKU; Enterprise examples range from enterprise-100000 to enterprise-5000000.',
603
550
  },
604
551
  },
605
- required: ["agentId", "plan", "planSku"],
552
+ required: ['agentId', 'plan', 'planSku'],
606
553
  },
607
554
  },
608
555
  {
609
- name: "enable_auto_renew",
610
- description: "Enable on-chain auto-renew for an agent. Requires the owner wallet private key and the RenewalVault contract address.",
556
+ name: 'enable_auto_renew',
557
+ description: 'Enable on-chain auto-renew for an agent. Requires the owner wallet private key and the RenewalVault contract address.',
611
558
  inputSchema: {
612
- type: "object",
559
+ type: 'object',
613
560
  properties: {
614
- agentId: { type: "string", description: "AgentDomain agent ID (UUID)" },
561
+ agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' },
615
562
  },
616
- required: ["agentId"],
563
+ required: ['agentId'],
617
564
  },
618
565
  },
619
566
  ];
@@ -628,43 +575,36 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
628
575
  const client = getClient();
629
576
  try {
630
577
  switch (name) {
631
- case "check_domain_availability": {
578
+ case 'check_domain_availability': {
632
579
  const a = z
633
- .object({
634
- name: z.string(),
635
- tld: z.enum(SUPPORTED_TLDS).default("xyz"),
636
- })
580
+ .object({ name: z.string(), tld: z.enum(SUPPORTED_TLDS).default('xyz') })
637
581
  .parse(args);
638
582
  const result = await client.checkAvailability(a.name, { tld: a.tld });
639
- return {
640
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
641
- };
583
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
642
584
  }
643
- case "quote_registration": {
585
+ case 'quote_registration': {
644
586
  const a = z
645
587
  .object({
646
588
  preferredName: z.string(),
647
- tld: z.enum(SUPPORTED_TLDS).default("xyz"),
589
+ tld: z.enum(SUPPORTED_TLDS).default('xyz'),
648
590
  registerBasename: z.boolean().default(true),
649
591
  registerEns: z.boolean().default(false),
650
592
  emailEnabled: z.boolean().default(true),
651
593
  emailUsername: z.string().optional(),
652
- premiumPlan: z.enum(SERVICE_PLAN_KEYS).default("included"),
594
+ premiumPlan: z.enum(SERVICE_PLAN_KEYS).default('included'),
653
595
  years: z.number().int().min(1).max(10).default(1),
654
596
  })
655
597
  .parse(args);
656
598
  const result = await client.quote(a);
657
- return {
658
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
659
- };
599
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
660
600
  }
661
- case "register_agent_identity": {
601
+ case 'register_agent_identity': {
662
602
  if (!AGENT_PRIVATE_KEY) {
663
603
  return {
664
604
  isError: true,
665
605
  content: [
666
606
  {
667
- type: "text",
607
+ type: 'text',
668
608
  text: "AGENT_PRIVATE_KEY env var is required for registration. Set it to your agent's wallet private key.",
669
609
  },
670
610
  ],
@@ -673,7 +613,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
673
613
  const a = z
674
614
  .object({
675
615
  preferredName: z.string(),
676
- tld: z.enum(SUPPORTED_TLDS).default("xyz"),
616
+ tld: z.enum(SUPPORTED_TLDS).default('xyz'),
677
617
  registerBasename: z.boolean().default(true),
678
618
  basenameLabel: z.string().optional(),
679
619
  registerEns: z.boolean().default(false),
@@ -684,7 +624,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
684
624
  .optional(),
685
625
  emailEnabled: z.boolean().default(true),
686
626
  emailUsername: z.string().optional(),
687
- premiumPlan: z.enum(SERVICE_PLAN_KEYS).default("included"),
627
+ premiumPlan: z.enum(SERVICE_PLAN_KEYS).default('included'),
688
628
  years: z.number().int().min(1).max(10).default(1),
689
629
  autoRenew: z.boolean().default(false),
690
630
  dnsTarget: z.string().optional(),
@@ -698,25 +638,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
698
638
  ownerAddress: a.ownerAddress,
699
639
  metadata: a.metadata,
700
640
  });
701
- return {
702
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
703
- };
641
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
704
642
  }
705
- case "lookup_agent": {
643
+ case 'lookup_agent': {
706
644
  const a = z.object({ wallet: z.string() }).parse(args);
707
645
  const result = await client.getAgentsByWallet(a.wallet);
708
- return {
709
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
710
- };
646
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
711
647
  }
712
- case "get_agent": {
648
+ case 'get_agent': {
713
649
  const a = z.object({ agentId: z.string() }).parse(args);
714
650
  const result = await client.getAgentById(a.agentId);
715
- return {
716
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
717
- };
651
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
718
652
  }
719
- case "search_agents": {
653
+ case 'search_agents': {
720
654
  const a = z
721
655
  .object({
722
656
  q: z.string().optional(),
@@ -726,11 +660,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
726
660
  })
727
661
  .parse(args);
728
662
  const result = await client.search(a);
729
- return {
730
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
731
- };
663
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
732
664
  }
733
- case "send_agent_email": {
665
+ case 'send_agent_email': {
734
666
  const a = z
735
667
  .object({
736
668
  agentId: z.string(),
@@ -746,29 +678,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
746
678
  subject: a.subject,
747
679
  text: a.text,
748
680
  });
749
- return {
750
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
751
- };
681
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
752
682
  }
753
- case "list_agent_email": {
754
- const a = z
755
- .object({ agentId: z.string(), limit: z.number().default(20) })
756
- .parse(args);
683
+ case 'list_agent_email': {
684
+ const a = z.object({ agentId: z.string(), limit: z.number().default(20) }).parse(args);
757
685
  const result = await client.listEmail(a.agentId, { limit: a.limit });
758
- return {
759
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
760
- };
686
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
761
687
  }
762
- case "delete_agent_email": {
688
+ case 'delete_agent_email': {
763
689
  const a = z
764
690
  .object({ agentId: z.string().uuid(), messageId: z.string().uuid() })
765
691
  .parse(args);
766
692
  const result = await client.deleteEmailMessage(a.agentId, a.messageId);
767
- return {
768
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
769
- };
693
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
770
694
  }
771
- case "send_agent_email_batch": {
695
+ case 'send_agent_email_batch': {
772
696
  const a = z
773
697
  .object({
774
698
  agentId: z.string(),
@@ -787,75 +711,51 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
787
711
  messages: a.messages,
788
712
  idempotencyKey: a.idempotencyKey,
789
713
  });
790
- return {
791
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
792
- };
714
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
793
715
  }
794
- case "get_agent_email_usage": {
716
+ case 'get_agent_email_usage': {
795
717
  const a = z.object({ agentId: z.string() }).parse(args);
796
718
  const result = await client.getEmailUsage(a.agentId);
797
- return {
798
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
799
- };
719
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
800
720
  }
801
- case "configure_email_webhook": {
721
+ case 'configure_email_webhook': {
802
722
  const a = z
803
723
  .object({
804
724
  agentId: z.string(),
805
725
  url: z.string().url(),
806
- payloadMode: z
807
- .enum(["metadata", "inline_text"])
808
- .default("metadata"),
726
+ payloadMode: z.enum(['metadata', 'inline_text']).default('metadata'),
809
727
  enabled: z.boolean().default(true),
810
728
  })
811
729
  .parse(args);
812
730
  const result = await client.setEmailWebhook(a.agentId, a);
813
- return {
814
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
815
- };
731
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
816
732
  }
817
- case "update_primary_email": {
818
- const a = z
819
- .object({ agentId: z.string(), username: z.string() })
820
- .parse(args);
733
+ case 'update_primary_email': {
734
+ const a = z.object({ agentId: z.string(), username: z.string() }).parse(args);
821
735
  const result = await client.updatePrimaryEmail(a.agentId, a.username);
822
- return {
823
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
824
- };
736
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
825
737
  }
826
- case "create_email_alias": {
827
- const a = z
828
- .object({ agentId: z.string(), username: z.string() })
829
- .parse(args);
738
+ case 'create_email_alias': {
739
+ const a = z.object({ agentId: z.string(), username: z.string() }).parse(args);
830
740
  const result = await client.createEmailAlias(a.agentId, a.username);
831
- return {
832
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
833
- };
741
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
834
742
  }
835
- case "delete_email_alias": {
836
- const a = z
837
- .object({ agentId: z.string(), emailAddress: z.string().email() })
838
- .parse(args);
743
+ case 'delete_email_alias': {
744
+ const a = z.object({ agentId: z.string(), emailAddress: z.string().email() }).parse(args);
839
745
  const result = await client.deleteEmailAlias(a.agentId, a.emailAddress);
840
- return {
841
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
842
- };
746
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
843
747
  }
844
- case "get_dns_capabilities": {
748
+ case 'get_dns_capabilities': {
845
749
  const a = z.object({ agentId: z.string() }).parse(args);
846
750
  const result = await client.getDnsCapabilities(a.agentId);
847
- return {
848
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
849
- };
751
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
850
752
  }
851
- case "list_dns_records": {
753
+ case 'list_dns_records': {
852
754
  const a = z.object({ agentId: z.string() }).parse(args);
853
755
  const result = await client.listDnsRecords(a.agentId);
854
- return {
855
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
856
- };
756
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
857
757
  }
858
- case "create_dns_record": {
758
+ case 'create_dns_record': {
859
759
  const a = z
860
760
  .object({
861
761
  agentId: z.string(),
@@ -869,11 +769,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
869
769
  .parse(args);
870
770
  const { agentId, ...record } = a;
871
771
  const result = await client.createDnsRecord(agentId, dnsRecordSchema.parse(record));
872
- return {
873
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
874
- };
772
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
875
773
  }
876
- case "update_dns_record": {
774
+ case 'update_dns_record': {
877
775
  const a = z
878
776
  .object({
879
777
  agentId: z.string(),
@@ -887,28 +785,20 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
887
785
  })
888
786
  .parse(args);
889
787
  const { agentId, recordId, ...record } = a;
890
- const result = await client.updateDnsRecord(agentId, recordId, dnsRecordObjectSchema
891
- .partial()
892
- .parse(record));
893
- return {
894
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
895
- };
788
+ const result = await client.updateDnsRecord(agentId, recordId, dnsRecordObjectSchema.partial().parse(record));
789
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
896
790
  }
897
- case "delete_dns_record": {
898
- const a = z
899
- .object({ agentId: z.string(), recordId: z.string() })
900
- .parse(args);
791
+ case 'delete_dns_record': {
792
+ const a = z.object({ agentId: z.string(), recordId: z.string() }).parse(args);
901
793
  const result = await client.deleteDnsRecord(a.agentId, a.recordId);
902
- return {
903
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
904
- };
794
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
905
795
  }
906
- case "change_dns_records": {
796
+ case 'change_dns_records': {
907
797
  const a = z
908
798
  .object({
909
799
  agentId: z.string(),
910
800
  records: z.array(dnsRecordSchema).min(1).max(200),
911
- mode: z.enum(["merge", "replace"]).default("merge"),
801
+ mode: z.enum(['merge', 'replace']).default('merge'),
912
802
  dryRun: z.boolean().default(true),
913
803
  baseRevision: z.string().length(64).optional(),
914
804
  })
@@ -916,16 +806,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
916
806
  const result = a.dryRun
917
807
  ? await client.previewDnsBatch(a.agentId, a.records, a.mode)
918
808
  : await client.applyDnsBatch(a.agentId, a.records, requireDnsRevision(a.baseRevision), a.mode);
919
- return {
920
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
921
- };
809
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
922
810
  }
923
- case "import_dns_zone": {
811
+ case 'import_dns_zone': {
924
812
  const a = z
925
813
  .object({
926
814
  agentId: z.string(),
927
815
  zoneFile: z.string().min(1).max(262_144),
928
- mode: z.enum(["merge", "replace"]).default("merge"),
816
+ mode: z.enum(['merge', 'replace']).default('merge'),
929
817
  dryRun: z.boolean().default(true),
930
818
  baseRevision: z.string().length(64).optional(),
931
819
  })
@@ -933,67 +821,49 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
933
821
  const result = a.dryRun
934
822
  ? await client.previewDnsImport(a.agentId, a.zoneFile, a.mode)
935
823
  : await client.applyDnsImport(a.agentId, a.zoneFile, requireDnsRevision(a.baseRevision), a.mode);
936
- return {
937
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
938
- };
824
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
939
825
  }
940
- case "export_dns_zone": {
826
+ case 'export_dns_zone': {
941
827
  const a = z
942
- .object({
943
- agentId: z.string(),
944
- scope: z.enum(["user", "all"]).default("user"),
945
- })
828
+ .object({ agentId: z.string(), scope: z.enum(['user', 'all']).default('user') })
946
829
  .parse(args);
947
830
  const result = await client.exportDnsZone(a.agentId, a.scope);
948
- return { content: [{ type: "text", text: result }] };
831
+ return { content: [{ type: 'text', text: result }] };
949
832
  }
950
- case "reconfigure_ssl": {
833
+ case 'reconfigure_ssl': {
951
834
  const a = z.object({ agentId: z.string() }).parse(args);
952
835
  const result = await client.reconfigureSsl(a.agentId);
953
- return {
954
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
955
- };
836
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
956
837
  }
957
- case "fund_renewal_vault": {
958
- const a = z
959
- .object({ agentId: z.string(), amountUsdc: z.string() })
960
- .parse(args);
838
+ case 'fund_renewal_vault': {
839
+ const a = z.object({ agentId: z.string(), amountUsdc: z.string() }).parse(args);
961
840
  const result = await client.fundRenewalVault(a.agentId, a.amountUsdc);
962
- return {
963
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
964
- };
841
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
965
842
  }
966
- case "withdraw_renewal_vault": {
967
- const a = z
968
- .object({ agentId: z.string(), amountUsdc: z.string() })
969
- .parse(args);
843
+ case 'withdraw_renewal_vault': {
844
+ requireDirectBaseWriteBuilderCode('withdraw_renewal_vault');
845
+ const a = z.object({ agentId: z.string(), amountUsdc: z.string() }).parse(args);
970
846
  const result = await client.withdrawFromVault(a.agentId, a.amountUsdc);
971
- return {
972
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
973
- };
847
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
974
848
  }
975
- case "get_renewal_status": {
849
+ case 'get_renewal_status': {
976
850
  const a = z.object({ agentId: z.string() }).parse(args);
977
851
  const result = await client.getRenewalStatus(a.agentId);
978
- return {
979
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
980
- };
852
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
981
853
  }
982
- case "get_service_plan": {
854
+ case 'get_service_plan': {
983
855
  const a = z.object({ agentId: z.string() }).parse(args);
984
856
  const result = await client.getServicePlan(a.agentId);
985
- return {
986
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
987
- };
857
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
988
858
  }
989
- case "purchase_service_plan": {
859
+ case 'purchase_service_plan': {
990
860
  if (!AGENT_PRIVATE_KEY) {
991
861
  return {
992
862
  isError: true,
993
863
  content: [
994
864
  {
995
- type: "text",
996
- text: "AGENT_PRIVATE_KEY env var is required to purchase a Premium Plan.",
865
+ type: 'text',
866
+ text: 'AGENT_PRIVATE_KEY env var is required to purchase a Premium Plan.',
997
867
  },
998
868
  ],
999
869
  };
@@ -1001,31 +871,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1001
871
  const a = z
1002
872
  .object({
1003
873
  agentId: z.string(),
1004
- plan: z.enum(["starter", "pro", "enterprise"]),
1005
- planSku: z
1006
- .custom()
1007
- .optional(),
874
+ plan: z.enum(['starter', 'pro', 'enterprise']),
875
+ planSku: z.custom().optional(),
1008
876
  })
1009
877
  .parse(args);
1010
878
  const result = await client.purchaseServicePlan(a);
1011
- return {
1012
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
1013
- };
879
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1014
880
  }
1015
- case "set_registry_visibility": {
1016
- const a = z
1017
- .object({ agentId: z.string(), registryHidden: z.boolean() })
1018
- .parse(args);
881
+ case 'set_registry_visibility': {
882
+ const a = z.object({ agentId: z.string(), registryHidden: z.boolean() }).parse(args);
1019
883
  const result = await client.setRegistryVisibility(a.agentId, a.registryHidden);
1020
- return {
1021
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
1022
- };
884
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1023
885
  }
1024
- case "schedule_service_plan_renewal": {
886
+ case 'schedule_service_plan_renewal': {
1025
887
  const a = z
1026
888
  .object({
1027
889
  agentId: z.string().uuid(),
1028
- plan: z.enum(["included", "starter", "pro", "enterprise"]),
890
+ plan: z.enum(['included', 'starter', 'pro', 'enterprise']),
1029
891
  planSku: z.custom(),
1030
892
  })
1031
893
  .parse(args);
@@ -1033,18 +895,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1033
895
  plan: a.plan,
1034
896
  planSku: a.planSku,
1035
897
  });
1036
- return {
1037
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
1038
- };
898
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1039
899
  }
1040
- case "enable_auto_renew": {
900
+ case 'enable_auto_renew': {
1041
901
  if (!AGENT_PRIVATE_KEY) {
1042
902
  return {
1043
903
  isError: true,
1044
904
  content: [
1045
905
  {
1046
- type: "text",
1047
- text: "AGENT_PRIVATE_KEY env var is required to enable auto-renew. Use the owner wallet private key.",
906
+ type: 'text',
907
+ text: 'AGENT_PRIVATE_KEY env var is required to enable auto-renew. Use the owner wallet private key.',
1048
908
  },
1049
909
  ],
1050
910
  };
@@ -1054,34 +914,28 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1054
914
  isError: true,
1055
915
  content: [
1056
916
  {
1057
- type: "text",
1058
- text: "RENEWAL_VAULT_ADDRESS env var is required to enable auto-renew on-chain.",
917
+ type: 'text',
918
+ text: 'RENEWAL_VAULT_ADDRESS env var is required to enable auto-renew on-chain.',
1059
919
  },
1060
920
  ],
1061
921
  };
1062
922
  }
923
+ requireDirectBaseWriteBuilderCode('enable_auto_renew');
1063
924
  const a = z.object({ agentId: z.string() }).parse(args);
1064
- const result = await client.setAutoRenew(a.agentId, true);
1065
- return {
1066
- content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
1067
- };
925
+ const result = await client.setAutoRenew(a.agentId, true, { waitForReceipt: true });
926
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
1068
927
  }
1069
928
  default:
1070
929
  return {
1071
930
  isError: true,
1072
- content: [{ type: "text", text: `Unknown tool: ${name}` }],
931
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
1073
932
  };
1074
933
  }
1075
934
  }
1076
935
  catch (e) {
1077
936
  return {
1078
937
  isError: true,
1079
- content: [
1080
- {
1081
- type: "text",
1082
- text: `Error: ${e instanceof Error ? e.message : String(e)}`,
1083
- },
1084
- ],
938
+ content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }],
1085
939
  };
1086
940
  }
1087
941
  });
@@ -1090,15 +944,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1090
944
  // ----------------------------------------------------------------------
1091
945
  function requireDnsRevision(value) {
1092
946
  if (!value)
1093
- throw new Error("Apply requires baseRevision from a fresh DNS dry-run preview.");
947
+ throw new Error('Apply requires baseRevision from a fresh DNS dry-run preview.');
1094
948
  return value;
1095
949
  }
950
+ function requireDirectBaseWriteBuilderCode(toolName) {
951
+ if (!AGENTDOMAIN_BUILDER_CODE) {
952
+ throw new Error(`${toolName} requires AGENTDOMAIN_BUILDER_CODE so its direct Base transaction includes ERC-8021 attribution.`);
953
+ }
954
+ try {
955
+ return validateBuilderCode(AGENTDOMAIN_BUILDER_CODE);
956
+ }
957
+ catch (error) {
958
+ throw new Error(`AGENTDOMAIN_BUILDER_CODE is invalid: ${error instanceof Error ? error.message : String(error)}`);
959
+ }
960
+ }
1096
961
  async function main() {
1097
962
  const transport = new StdioServerTransport();
1098
963
  await server.connect(transport);
1099
- console.error("AgentDomain MCP server running on stdio");
964
+ console.error('AgentDomain MCP server running on stdio');
1100
965
  }
1101
966
  main().catch((e) => {
1102
- console.error("Fatal:", e);
967
+ console.error('Fatal:', e);
1103
968
  process.exit(1);
1104
969
  });