Skip to main content

Overview

Integrate ACN into LangChain agents by defining ACN’s discover and execute endpoints as custom tools.

Python

Define ACN Tools

import os
import requests
from langchain.tools import tool

ACN_BASE_URL = "https://api.acn.exchange"
ACN_API_KEY = os.environ["ACN_API_KEY"]

@tool
def acn_discover(query: str) -> dict:
    """Search ACN marketplace for services matching a natural language query.
    Use this when you need to find an external service or API to accomplish a task."""
    response = requests.post(
        f"{ACN_BASE_URL}/v1/discover",
        json={"query": query}
    )
    return response.json()

@tool
def acn_execute(provider_id: str, endpoint_slug: str, payload: dict) -> dict:
    """Execute a service on ACN. Use the provider_id and endpoint_slug from
    discovery results. The payload should match the endpoint's parameter schema."""
    response = requests.post(
        f"{ACN_BASE_URL}/v1/execute/{provider_id}/{endpoint_slug}",
        headers={"Authorization": f"Bearer {ACN_API_KEY}"},
        json=payload
    )
    return response.json()

@tool
def acn_balance() -> dict:
    """Check your current ACN balance in USDC."""
    response = requests.get(
        f"{ACN_BASE_URL}/v1/wallet/balance",
        headers={"Authorization": f"Bearer {ACN_API_KEY}"}
    )
    return response.json()

Create an Agent

from langchain_anthropic import ChatAnthropic
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate

llm = ChatAnthropic(model="claude-sonnet-4-20250514")

tools = [acn_discover, acn_execute, acn_balance]

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are an agent with access to ACN services. "
               "Use acn_discover to find services, then acn_execute to call them. "
               "Always check costs before executing."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}")
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

result = executor.invoke({
    "input": "Get the current price of Bitcoin in USD"
})

TypeScript

import { ChatAnthropic } from "@langchain/anthropic";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
import { z } from "zod";

const ACN_BASE_URL = "https://api.acn.exchange";

const discoverTool = new DynamicStructuredTool({
  name: "acn_discover",
  description: "Search ACN marketplace for services matching a query",
  schema: z.object({
    query: z.string().describe("Natural language description of what you need"),
  }),
  func: async ({ query }) => {
    const res = await fetch(`${ACN_BASE_URL}/v1/discover`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query }),
    });
    return JSON.stringify(await res.json());
  },
});

const executeTool = new DynamicStructuredTool({
  name: "acn_execute",
  description: "Execute a service discovered on ACN",
  schema: z.object({
    provider_id: z.string(),
    endpoint_slug: z.string(),
    payload: z.record(z.any()),
  }),
  func: async ({ provider_id, endpoint_slug, payload }) => {
    const res = await fetch(
      `${ACN_BASE_URL}/v1/execute/${provider_id}/${endpoint_slug}`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${process.env.ACN_API_KEY}`,
        },
        body: JSON.stringify(payload),
      }
    );
    return JSON.stringify(await res.json());
  },
});

const tools = [discoverTool, executeTool];

LangGraph

For more complex workflows, use ACN tools within a LangGraph state machine:
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode

tool_node = ToolNode([acn_discover, acn_execute, acn_balance])

graph = StateGraph(MessagesState)
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
graph.add_edge("tools", "agent")
graph.add_conditional_edges("agent", should_continue)

app = graph.compile()
See the LangGraph documentation for full details on building stateful agent workflows.