@agentdomain/mcp-server 0.5.1 → 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/NOTICE ADDED
@@ -0,0 +1,5 @@
1
+ AgentDomain public developer tools and verified Base contracts
2
+ Copyright 2026 Md. Rakib
3
+
4
+ AgentDomain and related names and logos are trademarks or service marks of
5
+ their respective owner. This license does not grant trademark rights.
package/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  Lets any MCP-compatible LLM client (Claude Desktop, ChatGPT desktop apps, custom agents) register and manage agent identities through natural language.
6
6
 
7
+ The default API base, `https://agentdomain.app/api/v1`, also returns machine-readable discovery
8
+ metadata when requested directly.
9
+
7
10
  ## Tools exposed
8
11
 
9
12
  - `check_domain_availability` - is a domain available?
@@ -14,24 +17,26 @@ Lets any MCP-compatible LLM client (Claude Desktop, ChatGPT desktop apps, custom
14
17
  - `send_agent_email` - send an email from an agent's address
15
18
  - `send_agent_email_batch` - queue up to 100 email objects in one API request
16
19
  - `list_agent_email` - read agent inbox/outbox messages
17
- - `delete_agent_email` - permanently delete one inbox/outbox message
18
20
  - `get_agent_email_usage` - inspect combined monthly sent and received usage
19
21
  - `configure_email_webhook` - configure a signed inbound email webhook
20
22
  - `update_primary_email` - change the included primary email username
21
23
  - `create_email_alias` - create a Starter/Pro/Enterprise receive-and-send email alias
22
24
  - `delete_email_alias` - delete an active email alias
23
25
  - `list_dns_records` - list DNS records for an agent domain
24
- - `create_dns_record` - create a user-managed record; apex routing records activate external hosting
26
+ - `create_dns_record` - create a user-managed DNS record
25
27
  - `update_dns_record` - update a user-managed DNS record
26
28
  - `delete_dns_record` - delete a user-managed DNS record
27
- - `reconfigure_ssl` - rebuild Cloudflare SaaS SSL when AgentDomain-managed hosting is active
29
+ - `get_dns_capabilities` - discover all 13 Spaceship-supported types and validation constraints
30
+ - `change_dns_records` - preview or apply a revision-protected merge/replace batch
31
+ - `import_dns_zone` - preview or apply a standard BIND zone import
32
+ - `export_dns_zone` - export user-managed or permitted complete-zone records as BIND
33
+ - `reconfigure_ssl` - rebuild Cloudflare SaaS SSL and DNS validation records
28
34
  - `fund_renewal_vault` - top up an agent's renewal vault
29
35
  - `withdraw_renewal_vault` - build an owner-signed vault withdrawal transaction
30
36
  - `get_renewal_status` - check renewal date, amount, vault balance, and auto-renew state
31
37
  - `enable_auto_renew` - enable on-chain auto-renew with the AgentID NFT owner wallet
32
38
  - `get_service_plan` - inspect per-agent Included/Starter/Pro/Enterprise limits
33
39
  - `purchase_service_plan` - upgrade to Starter, Pro, or Enterprise with x402 USDC
34
- - `schedule_service_plan_renewal` - choose the exact next-renewal plan and Enterprise tier
35
40
 
36
41
  ## Install
37
42
 
@@ -53,6 +58,7 @@ npm install -g @agentdomain/mcp-server
53
58
  "AGENTDOMAIN_API_URL": "https://agentdomain.app/api/v1",
54
59
  "AGENT_PRIVATE_KEY": "0x...",
55
60
  "AGENTDOMAIN_NETWORK": "base",
61
+ "AGENTDOMAIN_BUILDER_CODE": "your_builder_code",
56
62
  "RENEWAL_VAULT_ADDRESS": "0x..."
57
63
  }
58
64
  }
@@ -63,6 +69,12 @@ npm install -g @agentdomain/mcp-server
63
69
  For `enable_auto_renew`, `AGENT_PRIVATE_KEY` must be the AgentID NFT owner wallet. Funding can come
64
70
  from any wallet, but the RenewalVault contract only accepts auto-renew changes from the owner.
65
71
 
72
+ `AGENTDOMAIN_BUILDER_CODE` is the public ERC-8021 app identifier used to attribute direct Base
73
+ transactions created through MCP. It must contain 1-32 lowercase letters, numbers, or underscores.
74
+ It is required only by `enable_auto_renew` and `withdraw_renewal_vault`; the server validates it when
75
+ one of those tools is called, so read-only, API-managed, and x402 payment tools continue to work
76
+ without it. x402 v2 payments use AgentDomain's resource-server attribution instead.
77
+
66
78
  ## Pricing flags
67
79
 
68
80
  Registration pricing includes the live domain price plus the annual AgentDomain
package/dist/index.d.ts CHANGED
@@ -15,7 +15,8 @@
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
  * }
package/dist/index.js CHANGED
@@ -15,7 +15,8 @@
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
  * }
@@ -25,7 +26,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
25
26
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
26
27
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
27
28
  import { z } from 'zod';
28
- import { AgentDomain } from '@agentdomain/sdk';
29
+ import { AgentDomain, validateBuilderCode } from '@agentdomain/sdk';
30
+ import { DNS_RECORD_TYPES, dnsRecordSchema, dnsRecordObjectSchema, } from '@agentdomain/shared';
29
31
  import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_FRAMEWORKS, SUPPORTED_TLDS, } from '@agentdomain/shared/constants';
30
32
  import { createPublicClient, createWalletClient, http } from 'viem';
31
33
  import { privateKeyToAccount } from 'viem/accounts';
@@ -34,6 +36,7 @@ const API_URL = process.env.AGENTDOMAIN_API_URL ?? AGENTDOMAIN_API_BASE_URL;
34
36
  const NETWORK = (process.env.AGENTDOMAIN_NETWORK ?? 'base');
35
37
  const AGENT_PRIVATE_KEY = process.env.AGENT_PRIVATE_KEY;
36
38
  const AGENTDOMAIN_API_KEY = process.env.AGENTDOMAIN_API_KEY;
39
+ const AGENTDOMAIN_BUILDER_CODE = process.env.AGENTDOMAIN_BUILDER_CODE;
37
40
  const RENEWAL_VAULT_ADDRESS = process.env.RENEWAL_VAULT_ADDRESS;
38
41
  function getClient() {
39
42
  const config = {
@@ -41,6 +44,7 @@ function getClient() {
41
44
  apiKey: AGENTDOMAIN_API_KEY,
42
45
  network: NETWORK,
43
46
  renewalVaultAddress: RENEWAL_VAULT_ADDRESS,
47
+ builderCode: AGENTDOMAIN_BUILDER_CODE,
44
48
  };
45
49
  if (AGENT_PRIVATE_KEY) {
46
50
  const account = privateKeyToAccount(AGENT_PRIVATE_KEY);
@@ -335,6 +339,15 @@ const TOOLS = [
335
339
  required: ['agentId', 'messageId'],
336
340
  },
337
341
  },
342
+ {
343
+ name: 'get_dns_capabilities',
344
+ description: 'Get the machine-readable Spaceship DNS types, fields, limits, and safety warnings supported by AgentDomain.',
345
+ inputSchema: {
346
+ type: 'object',
347
+ properties: { agentId: { type: 'string', description: 'AgentDomain agent ID (UUID)' } },
348
+ required: ['agentId'],
349
+ },
350
+ },
338
351
  {
339
352
  name: 'list_dns_records',
340
353
  description: 'List Spaceship-backed DNS records for an agent domain.',
@@ -353,13 +366,14 @@ const TOOLS = [
353
366
  type: 'object',
354
367
  properties: {
355
368
  agentId: { type: 'string' },
356
- type: { type: 'string', enum: ['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV'] },
369
+ type: { type: 'string', enum: DNS_RECORD_TYPES },
357
370
  name: { type: 'string' },
358
- value: { type: 'string' },
371
+ value: { type: 'string', description: 'Legacy format; structured data is preferred' },
372
+ data: { type: 'object', description: 'Type-specific structured DNS record data' },
359
373
  ttl: { type: 'number', default: 3600 },
360
374
  priority: { type: 'number' },
361
375
  },
362
- required: ['agentId', 'type', 'name', 'value'],
376
+ required: ['agentId', 'type', 'name'],
363
377
  },
364
378
  },
365
379
  {
@@ -370,9 +384,10 @@ const TOOLS = [
370
384
  properties: {
371
385
  agentId: { type: 'string' },
372
386
  recordId: { type: 'string' },
373
- type: { type: 'string', enum: ['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV'] },
387
+ type: { type: 'string', enum: DNS_RECORD_TYPES },
374
388
  name: { type: 'string' },
375
389
  value: { type: 'string' },
390
+ data: { type: 'object', description: 'Type-specific structured DNS record data' },
376
391
  ttl: { type: 'number' },
377
392
  priority: { type: 'number' },
378
393
  },
@@ -391,6 +406,48 @@ const TOOLS = [
391
406
  required: ['agentId', 'recordId'],
392
407
  },
393
408
  },
409
+ {
410
+ name: 'change_dns_records',
411
+ description: 'Preview or apply an atomic DNS merge/replace batch. Apply requires the baseRevision returned by preview.',
412
+ inputSchema: {
413
+ type: 'object',
414
+ properties: {
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' },
420
+ },
421
+ required: ['agentId', 'records'],
422
+ },
423
+ },
424
+ {
425
+ name: 'import_dns_zone',
426
+ description: 'Preview or apply a BIND zone import. System-managed records remain protected.',
427
+ inputSchema: {
428
+ type: 'object',
429
+ properties: {
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' },
435
+ },
436
+ required: ['agentId', 'zoneFile'],
437
+ },
438
+ },
439
+ {
440
+ name: 'export_dns_zone',
441
+ description: 'Export user-managed or permitted complete DNS state as a standard BIND zone file.',
442
+ inputSchema: {
443
+ type: 'object',
444
+ properties: {
445
+ agentId: { type: 'string' },
446
+ scope: { type: 'string', enum: ['user', 'all'], default: 'user' },
447
+ },
448
+ required: ['agentId'],
449
+ },
450
+ },
394
451
  {
395
452
  name: 'reconfigure_ssl',
396
453
  description: 'Rebuild the Cloudflare SaaS SSL hostname and sync required DNS validation records.',
@@ -629,7 +686,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
629
686
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
630
687
  }
631
688
  case 'delete_agent_email': {
632
- const a = z.object({ agentId: z.string().uuid(), messageId: z.string().uuid() }).parse(args);
689
+ const a = z
690
+ .object({ agentId: z.string().uuid(), messageId: z.string().uuid() })
691
+ .parse(args);
633
692
  const result = await client.deleteEmailMessage(a.agentId, a.messageId);
634
693
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
635
694
  }
@@ -686,6 +745,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
686
745
  const result = await client.deleteEmailAlias(a.agentId, a.emailAddress);
687
746
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
688
747
  }
748
+ case 'get_dns_capabilities': {
749
+ const a = z.object({ agentId: z.string() }).parse(args);
750
+ const result = await client.getDnsCapabilities(a.agentId);
751
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
752
+ }
689
753
  case 'list_dns_records': {
690
754
  const a = z.object({ agentId: z.string() }).parse(args);
691
755
  const result = await client.listDnsRecords(a.agentId);
@@ -695,20 +759,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
695
759
  const a = z
696
760
  .object({
697
761
  agentId: z.string(),
698
- type: z.enum(['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV']),
762
+ type: z.enum(DNS_RECORD_TYPES),
699
763
  name: z.string(),
700
- value: z.string(),
764
+ value: z.string().optional(),
765
+ data: z.record(z.unknown()).optional(),
701
766
  ttl: z.number().default(3600),
702
767
  priority: z.number().optional(),
703
768
  })
704
769
  .parse(args);
705
- const result = await client.createDnsRecord(a.agentId, {
706
- type: a.type,
707
- name: a.name,
708
- value: a.value,
709
- ttl: a.ttl,
710
- priority: a.priority,
711
- });
770
+ const { agentId, ...record } = a;
771
+ const result = await client.createDnsRecord(agentId, dnsRecordSchema.parse(record));
712
772
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
713
773
  }
714
774
  case 'update_dns_record': {
@@ -716,15 +776,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
716
776
  .object({
717
777
  agentId: z.string(),
718
778
  recordId: z.string(),
719
- type: z.enum(['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV']).optional(),
779
+ type: z.enum(DNS_RECORD_TYPES).optional(),
720
780
  name: z.string().optional(),
721
781
  value: z.string().optional(),
782
+ data: z.record(z.unknown()).optional(),
722
783
  ttl: z.number().optional(),
723
784
  priority: z.number().optional(),
724
785
  })
725
786
  .parse(args);
726
787
  const { agentId, recordId, ...record } = a;
727
- const result = await client.updateDnsRecord(agentId, recordId, record);
788
+ const result = await client.updateDnsRecord(agentId, recordId, dnsRecordObjectSchema.partial().parse(record));
728
789
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
729
790
  }
730
791
  case 'delete_dns_record': {
@@ -732,6 +793,43 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
732
793
  const result = await client.deleteDnsRecord(a.agentId, a.recordId);
733
794
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
734
795
  }
796
+ case 'change_dns_records': {
797
+ const a = z
798
+ .object({
799
+ agentId: z.string(),
800
+ records: z.array(dnsRecordSchema).min(1).max(200),
801
+ mode: z.enum(['merge', 'replace']).default('merge'),
802
+ dryRun: z.boolean().default(true),
803
+ baseRevision: z.string().length(64).optional(),
804
+ })
805
+ .parse(args);
806
+ const result = a.dryRun
807
+ ? await client.previewDnsBatch(a.agentId, a.records, a.mode)
808
+ : await client.applyDnsBatch(a.agentId, a.records, requireDnsRevision(a.baseRevision), a.mode);
809
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
810
+ }
811
+ case 'import_dns_zone': {
812
+ const a = z
813
+ .object({
814
+ agentId: z.string(),
815
+ zoneFile: z.string().min(1).max(262_144),
816
+ mode: z.enum(['merge', 'replace']).default('merge'),
817
+ dryRun: z.boolean().default(true),
818
+ baseRevision: z.string().length(64).optional(),
819
+ })
820
+ .parse(args);
821
+ const result = a.dryRun
822
+ ? await client.previewDnsImport(a.agentId, a.zoneFile, a.mode)
823
+ : await client.applyDnsImport(a.agentId, a.zoneFile, requireDnsRevision(a.baseRevision), a.mode);
824
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
825
+ }
826
+ case 'export_dns_zone': {
827
+ const a = z
828
+ .object({ agentId: z.string(), scope: z.enum(['user', 'all']).default('user') })
829
+ .parse(args);
830
+ const result = await client.exportDnsZone(a.agentId, a.scope);
831
+ return { content: [{ type: 'text', text: result }] };
832
+ }
735
833
  case 'reconfigure_ssl': {
736
834
  const a = z.object({ agentId: z.string() }).parse(args);
737
835
  const result = await client.reconfigureSsl(a.agentId);
@@ -743,6 +841,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
743
841
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
744
842
  }
745
843
  case 'withdraw_renewal_vault': {
844
+ requireDirectBaseWriteBuilderCode('withdraw_renewal_vault');
746
845
  const a = z.object({ agentId: z.string(), amountUsdc: z.string() }).parse(args);
747
846
  const result = await client.withdrawFromVault(a.agentId, a.amountUsdc);
748
847
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
@@ -821,8 +920,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
821
920
  ],
822
921
  };
823
922
  }
923
+ requireDirectBaseWriteBuilderCode('enable_auto_renew');
824
924
  const a = z.object({ agentId: z.string() }).parse(args);
825
- const result = await client.setAutoRenew(a.agentId, true);
925
+ const result = await client.setAutoRenew(a.agentId, true, { waitForReceipt: true });
826
926
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
827
927
  }
828
928
  default:
@@ -842,6 +942,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
842
942
  // ----------------------------------------------------------------------
843
943
  // MAIN
844
944
  // ----------------------------------------------------------------------
945
+ function requireDnsRevision(value) {
946
+ if (!value)
947
+ throw new Error('Apply requires baseRevision from a fresh DNS dry-run preview.');
948
+ return value;
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
+ }
845
961
  async function main() {
846
962
  const transport = new StdioServerTransport();
847
963
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentdomain/mcp-server",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server exposing AgentDomain registration and management tools to any LLM",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/0xmdrakib/AgentDomain.git",
@@ -15,6 +15,8 @@
15
15
  "files": [
16
16
  "dist",
17
17
  "README.md",
18
+ "LICENSE",
19
+ "NOTICE",
18
20
  "package.json"
19
21
  ],
20
22
  "publishConfig": {
@@ -24,8 +26,8 @@
24
26
  "@modelcontextprotocol/sdk": "^1.0.4",
25
27
  "viem": "^2.55.2",
26
28
  "zod": "^3.24.1",
27
- "@agentdomain/sdk": "^0.5.1",
28
- "@agentdomain/shared": "^0.5.1"
29
+ "@agentdomain/sdk": "^0.7.0",
30
+ "@agentdomain/shared": "^0.7.0"
29
31
  },
30
32
  "devDependencies": {
31
33
  "@types/node": "^22.10.5",
@@ -36,6 +38,7 @@
36
38
  "build": "tsc",
37
39
  "dev": "tsx watch src/index.ts",
38
40
  "start": "node dist/index.js",
41
+ "test": "pnpm --filter @agentdomain/sdk build && pnpm build && node --test test/*.test.mjs",
39
42
  "typecheck": "tsc --noEmit",
40
43
  "lint": "echo \"no lint\""
41
44
  }