LangChain Tools

Use Cron Protocol with LangChain and LangGraph agents via built-in TypeScript tool wrappers.

Overview

The SDK exports buildLangChainTools(client) which returns an array of tools compatible with LangChain's StructuredTool interface. No separate package is required — it's included in @cron/sdk.

The tools have zero hard dependency on LangChain itself — they implement the expected interface shape so they work with any LangChain version without version conflicts.

Installation

bash
npm install @cron/sdk @langchain/anthropic @langchain/core langchain

Available Tools

  • cron_list_plans — search active subscription plans
  • cron_get_plan — fetch plan details by ID
  • cron_get_subscription — check a wallet's subscription status
  • cron_subscribe — subscribe the connected wallet
  • cron_cancel_subscription — cancel an active subscription
  • cron_create_plan — create a new subscription plan
  • cron_api_list_plans — list plans via paid MPP API (available when mpp transport is provided)
  • cron_api_chargeable — query chargeable subscriptions via paid MPP API
  • cron_api_stream_plans — stream plans via SSE through MPP API

Usage with createReactAgent

Use wrapForLangChain() to convert the plain tool objects into actual DynamicStructuredTool instances that LangChain agents expect. This requires @langchain/core to be installed.

typescript
import { CronClient, buildLangChainTools, wrapForLangChain } from "@cron/sdk";
import { ChatAnthropic } from "@langchain/anthropic";
import { createReactAgent } from "langchain/agents";

const client = new CronClient({
  chain: "base",
  walletClient, // your viem WalletClient
});

// wrapForLangChain() creates actual DynamicStructuredTool instances
// required by createReactAgent and AgentExecutor
const tools = await wrapForLangChain(buildLangChainTools(client));

const llm = new ChatAnthropic({ model: "claude-sonnet-4-6" });
const agent = createReactAgent({ llm, tools });

const result = await agent.invoke({
  input: "What is the status of my subscription to plan 1?",
});

Using tools directly

typescript
import { CronClient, buildLangChainTools } from "@cron/sdk";

const client = new CronClient({ chain: "baseSepolia" });
const tools = buildLangChainTools(client);

// Each tool has: name, description, schema, invoke()
const tool = tools.find(t => t.name === "cron_get_subscription")!;
const result = await tool.invoke({
  subscriber: "0xabc...",
  planId: "1",
});
// Returns a JSON string with status, chargeCount, nextChargeAt, etc.
console.log(JSON.parse(result));

With MPP transport

typescript
import { MppTransport } from "@cron/sdk";
import { privateKeyToAccount } from "viem/accounts";

const mpp = new MppTransport({
  account: privateKeyToAccount(process.env.AGENT_KEY!),
  maxSessionDeposit: "5",
});

const tools = buildLangChainTools(client, {
  mpp,
  apiBaseUrl: "https://api.cronprotocol.xyz",
});
// Now includes cron_api_list_plans, cron_api_chargeable, cron_api_stream_plans

[*] Python support

A Python LangChain tool wrapper is on the roadmap. For now, Python agents can query subscription state via the Guild.xyz endpoint or your own backend.

Error handling

All tools return a JSON string. On failure, they return { "error": "message" } rather than throwing, so agent loops can handle errors gracefully without crashing.

typescript
const result = JSON.parse(await tool.invoke({ planId: "99999" }));
if ("error" in result) {
  console.error("Tool failed:", result.error);
}