Skip to main content
Glama

azeth_publish_service

Register services, agents, or infrastructure on the ERC-8004 trust registry to make them discoverable by other Azeth network participants with metadata and capabilities.

Instructions

Register a service, agent, or infrastructure on the ERC-8004 trust registry with metadata and capabilities.

Use this when: You want to make your agent or service discoverable by other participants in the Azeth network.

Returns: The trust registry token ID and creation transaction hash.

Note: This is a state-changing on-chain operation. The token ID is your permanent identity in the trust registry. Other participants can discover you by capability, entity type, and reputation score. The account is determined by the AZETH_PRIVATE_KEY environment variable.

Example: { "name": "MarketOracle", "description": "Real-time market data API", "entityType": "service", "capabilities": ["price-feed", "market-data"], "endpoint": "https://api.example.com" }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chainNoTarget chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").
nameYesDisplay name for this participant in the trust registry.
descriptionYesHuman-readable description of what this participant does.
entityTypeYesParticipant type: "agent" (AI agent), "service" (API/oracle), or "infrastructure" (bridge/relay).
capabilitiesYesList of capabilities offered (e.g., ["swap", "price-feed", "translation"]).
endpointNoOptional HTTP endpoint where this participant can be reached.
pricingNoListed price for this service (e.g., "$0.01/request", "Free", "$10/month"). Informational — actual x402 settlement price may differ.
catalogNoOff-chain service catalog for multi-service providers. Included in initial registration as a snapshot; providers should serve their live catalog from their endpoint. Each entry: name, path, method (GET/POST/etc), description, pricing, capabilities, params, paid (default true), accepts (multi-chain payment methods).

Implementation Reference

  • The handler for the 'azeth_publish_service' MCP tool, which registers a service/agent on the ERC-8004 trust registry. It performs an initial check for existing registrations and calls the `publishService` method on the client.
    server.registerTool(
      'azeth_publish_service',
      {
        description: [
          'Register a service, agent, or infrastructure on the ERC-8004 trust registry with metadata and capabilities.',
          '',
          'Use this when: You want to make your agent or service discoverable by other participants in the Azeth network.',
          '',
          'Returns: The trust registry token ID and creation transaction hash.',
          '',
          'Note: This is a state-changing on-chain operation. The token ID is your permanent identity in the trust registry.',
          'Other participants can discover you by capability, entity type, and reputation score.',
          'The account is determined by the AZETH_PRIVATE_KEY environment variable.',
          '',
          'Example: { "name": "MarketOracle", "description": "Real-time market data API", "entityType": "service", "capabilities": ["price-feed", "market-data"], "endpoint": "https://api.example.com" }',
        ].join('\n'),
        inputSchema: z.object({
          chain: z.string().optional().describe('Target chain. Defaults to AZETH_CHAIN env var or "baseSepolia". Accepts "base", "baseSepolia", "ethereumSepolia", "ethereum" (and aliases like "base-sepolia", "eth-sepolia", "sepolia", "eth", "mainnet").'),
          name: z.string().min(1).max(256).describe('Display name for this participant in the trust registry.'),
          description: z.string().min(1).max(2048).describe('Human-readable description of what this participant does.'),
          entityType: z.enum(['agent', 'service', 'infrastructure']).describe('Participant type: "agent" (AI agent), "service" (API/oracle), or "infrastructure" (bridge/relay).'),
          capabilities: z.preprocess(
            (val) => typeof val === 'string' ? JSON.parse(val) : val,
            z.array(z.string().max(128)).min(1).max(50),
          ).describe('List of capabilities offered (e.g., ["swap", "price-feed", "translation"]).'),
          endpoint: z.string().url().max(2048)
            .refine(url => url.startsWith('https://') || url.startsWith('http://'), {
              message: 'Endpoint must use HTTP or HTTPS protocol',
            })
            .optional()
            .describe('Optional HTTP endpoint where this participant can be reached.'),
          pricing: z.string().max(256).optional()
            .describe('Listed price for this service (e.g., "$0.01/request", "Free", "$10/month"). Informational — actual x402 settlement price may differ.'),
          catalog: z.preprocess(
            (val) => typeof val === 'string' ? JSON.parse(val) : val,
            z.array(z.object({
              name: z.string().min(1).max(256),
              path: z.string().min(1).max(CATALOG_MAX_PATH_LENGTH),
              method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']).optional(),
              description: z.string().max(1024).optional(),
              pricing: z.string().max(256).optional(),
              mimeType: z.string().max(128).optional(),
              capabilities: z.array(z.string().max(128)).max(20).optional(),
              params: z.record(z.string(), z.string().max(512)).optional(),
              paid: z.boolean().optional(),
              accepts: z.array(z.object({
                network: z.string().min(1).max(64),
                asset: z.string().regex(/^0x[0-9a-fA-F]{40}$/) as z.ZodType<`0x${string}`>,
                symbol: z.string().max(16).optional(),
              })).max(10).optional(),
            })).max(CATALOG_MAX_ENTRIES).optional(),
          ).optional().describe('Off-chain service catalog for multi-service providers. Included in initial registration as a snapshot; providers should serve their live catalog from their endpoint. Each entry: name, path, method (GET/POST/etc), description, pricing, capabilities, params, paid (default true), accepts (multi-chain payment methods).'),
        }),
      },
      async (args) => {
        let client;
        try {
          client = await createClient(args.chain);
    
          // Check if the smart account is already registered to prevent silent duplicates
          try {
            const chainName = resolveChain(args.chain);
            const trustRegAddr = AZETH_CONTRACTS[chainName].trustRegistryModule as `0x${string}`;
            const smartAccount = await client.resolveSmartAccount();
            const isAlreadyRegistered = await client.publicClient.readContract({
              address: trustRegAddr,
              abi: TrustRegistryModuleAbi,
              functionName: 'isRegistered',
              args: [smartAccount],
            }) as boolean;
            if (isAlreadyRegistered) {
              return error(
                'ACCOUNT_EXISTS',
                'This account is already registered on the trust registry.',
                'Use azeth_update_service to update your existing registration metadata.',
              );
            }
          } catch {
            // Non-fatal: if the check fails (RPC error, module not deployed), proceed anyway
          }
    
          const result = await client.publishService({
            name: args.name,
            description: args.description,
            entityType: args.entityType,
            capabilities: args.capabilities,
            endpoint: args.endpoint,
            pricing: args.pricing,
            catalog: args.catalog,
          });
    
          return success(
            {
              tokenId: result.tokenId.toString(),
              txHash: result.txHash,
            },
            { txHash: result.txHash },
          );
        } catch (err) {
          return handleError(err);
        } finally {
          try { await client?.destroy(); } catch (e) { process.stderr.write(`[azeth-mcp] destroy error: ${e instanceof Error ? e.message : String(e)}\n`); }
        }
      },
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/azeth-protocol/mcp-azeth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server