@a3stack/core

Core

The A3Stack class: one object, three capabilities. Identity, payments, and MCP combined.

What is @a3stack/core?

@a3stack/core is the all-in-one package that combines identity, payments, and data into a single A3Stack class. It also re-exports everything from the other packages, so you can do one install and one import.

Use A3Stack when you want the simplest possible setup. Use the individual packages (@a3stack/identity, etc.) when you need more control.

Initialization

typescript
import { A3Stack } from "@a3stack/core";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { z } from "zod";

const agent = new A3Stack({
  // Identity config
  account: privateKeyToAccount(process.env.PRIVATE_KEY),
  chain: base,
  rpc: "https://mainnet.base.org",  // optional

  // Server config (optional — omit if not serving tools)
  server: {
    name: "MyAgent",
    version: "1.0.0",
    port: 3000,
    payment: {
      amount: "10000",     // 0.01 USDC per call
      // payTo defaults to this wallet
      description: "MyAgent: 0.01 USDC per call",
    },
  },
});

Configuration

typescript
interface A3StackConfig {
  account: Account;              // viem Account (signer)
  chain: Chain;                  // viem Chain (e.g. base)
  rpc?: string;                  // optional RPC URL override

  server?: {
    name: string;
    version?: string;            // default: "1.0.0"
    port?: number;               // default: 3000
    payment?: {
      amount: string;            // USDC base units
      payTo?: string;            // defaults to account.address
      asset?: string;            // defaults to USDC_BASE
      network?: string;          // defaults to "eip155:8453"
      description?: string;
      freeTools?: string[];
    };
  };
}

Methods

agent.tool()

Register a tool with the MCP server. Requires server config to be set.

typescript
// Register a tool (same API as MCP SDK)
agent.tool(
  "my-tool",          // tool name
  "Does a thing",     // description
  { input: z.string() },  // input schema (zod)
  async ({ input }) => ({
    content: [{ type: "text", text: `Result: ${input}` }],
  })
);

agent.start() / agent.stop()

Start or stop the MCP server.

typescript
// Start the MCP server
const { url } = await agent.start();
console.log(`Serving at ${url}`);
// → http://localhost:3000/mcp

// Stop when done
await agent.stop();

agent.register()

Register your agent on-chain via ERC-8004. One-time, costs a small amount of gas.

typescript
// Register on-chain (one-time, costs gas)
const { agentId, globalId, txHash } = await agent.register({
  name: "MyAgent",
  description: "My paid AI agent service",
  x402Support: true,
  active: true,
  includeServerEndpoint: true,  // auto-adds MCP URL to services
  mcpUrl: "https://mcp.myagent.ai/mcp",  // optional override
});

console.log(`Global ID: ${globalId}`);
// → "eip155:8453:0x8004...#42"

agent.connect()

Connect to another agent's MCP server by global ID. Returns an MCP client with auto-payment.

typescript
// Connect to another agent (auto-pays x402 if needed)
const client = await agent.connect("eip155:8453:0x8004...#9999");

const tools = await client.listTools();
const result = await client.callTool("some-tool", { query: "hello" });
const identity = await client.getAgentIdentity();

await client.close();

agent.verify()

typescript
// Verify another agent's on-chain identity
const verification = await agent.verify("eip155:8453:0x8004...#9999");

console.log(verification.valid);              // true / false
console.log(verification.owner);              // "0x..."
console.log(verification.registration?.name); // "SomeAgent"

agent.getBalance()

typescript
// Check this agent's USDC balance
const balance = await agent.getBalance();
// { amount: 5000000n, formatted: "5.000000", symbol: "USDC" }

agent.getMcpEndpoint()

typescript
// Resolve another agent's MCP endpoint
const url = await agent.getMcpEndpoint("eip155:8453:0x8004...#9999");
// "https://mcp.someagent.ai/mcp"

Standalone utilities

These are re-exported from the sub-packages and work without instantiating A3Stack:

typescript
import { probeAgent } from "@a3stack/core";

// Probe without instantiating A3Stack (no wallet needed)
const info = await probeAgent("eip155:8453:0x8004...#2376");
typescript
import { findAllRegistrations } from "@a3stack/core";

// Find all ERC-8004 registrations for a wallet across all 17 chains
const regs = await findAllRegistrations("0x1be93C...");

Full example

04-full-a3stack.ts
typescript
import { A3Stack } from "@a3stack/core";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { z } from "zod";
import { USDC_BASE } from "@a3stack/payments";

async function main() {
  const account = privateKeyToAccount(process.env.PRIVATE_KEY);

  // Initialize
  const agent = new A3Stack({
    account,
    chain: base,
    server: {
      name: "DemoAgent",
      payment: { amount: "1000", asset: USDC_BASE },
    },
  });

  // Register tools
  agent.tool("hello", { name: z.string().optional() }, async ({ name }) => ({
    content: [{ type: "text", text: `Hello, ${name ?? "world"}!` }],
  }));

  // Start serving
  const { url } = await agent.start();
  console.log(`Agent running at ${url}`);

  // Check balance
  const balance = await agent.getBalance();
  console.log(`USDC: ${balance.formatted}`);

  // Verify another agent
  const check = await agent.verify("eip155:8453:0x8004...#9999");
  if (check.valid) {
    const client = await agent.connect("eip155:8453:0x8004...#9999");
    const result = await client.callTool("some-tool", {});
    console.log(result);
    await client.close();
  }
}

main().catch(console.error);

Package re-exports

@a3stack/core re-exports everything from the sub-packages. You can use it as a single import for everything:

ExportFrom
A3Stack@a3stack/core
probeAgent, findAllRegistrations@a3stack/core
AgentIdentity, verifyAgent, getMcpEndpoint, ...@a3stack/identity
createPaymentClient, createPaymentServer, PaymentClient, USDC_BASE, ...@a3stack/payments
createAgentMcpServer, createAgentMcpClient@a3stack/data