LLM tool catalog
From v0.5.0, the SDK publishes a shared catalog of LLM-oriented tools: Zod input schemas, descriptions, and handlers that call CelinaClient. The same definitions power celina-mcp (surface: "mcp") and browser wallet apps (surface: "browser").
Use the programmatic client (createCelinaClient) when you only need reads and prepare* in TypeScript. Use the /tools export when you are building an agent host (MCP server, Vercel AI SDK chat API, custom orchestrator).
Install and import
The catalog is a separate export path (keeps MCP/agent deps out of the default bundle for simple wagmi apps):
npm i @andrewkimjoseph/celina-sdkimport { createCelinaClient } from "@andrewkimjoseph/celina-sdk";
import {
ALL_TOOL_DEFINITIONS,
filterToolDefinitions,
getBrowserToolNames,
getMcpToolNames,
type ToolDefinition,
type ToolRuntime,
} from "@andrewkimjoseph/celina-sdk/tools";Requires Node.js ≥ 20. Schemas are built with Zod 3 (same major as this package’s dependency).
What is a ToolDefinition?
Each catalog entry is a plain object:
name
Snake_case tool id (e.g. get_stablecoin_balances)
description
Text shown to the model
inputSchema
Zod schema (z.ZodTypeAny) — keys must be snake_case
families
"read" | "prepare" | "execute"
surfaces
Optional: "mcp", "browser", or both (default: both)
mcp
Optional MCP metadata (title, annotations, responseKind)
handler
(runtime, input) => Promise<unknown>
Handlers receive a ToolRuntime: { celina, resolveWallet, hooks?, executors?, mcpWallet? }.
celina—ReturnType<typeof createCelinaClient>(reads + unsigned prepare).resolveWallet(input?)— host supplies howaddress/wallet_address/frommap to0x….hooks— optional host overrides (e.g. send preflight). Browser chat hosts set these; MCP usually does not.executors— MCP-only signed execution (sendToken,executeFx, etc.). Not used in wallet-signing browser apps.
Filtering by host
surface
"mcp" or "browser" — only tools that list that surface
families
Subset: read / prepare / execute
names
Allow-list by tool name
serverKeyToolsEnabled
false hides tools requiring CELO_PRIVATE_KEY or SELF_AGENT_PRIVATE_KEY
Helpers: getToolNames(), getMcpToolNames(), getBrowserToolNames(), getToolDefinition(name).
Catalog layout: src/tools/domains/*.ts (merged in ALL_TOOL_DEFINITIONS). Browser-only swap routing (get_swap_quote, prepare_swap) lives in domains/browser.ts. GoodDollar reserve quotes (get_gooddollar_reserve_quote, prepare_gooddollar_reserve_swap) live in domains/gooddollar.ts and are included in aggregated swap routing for G$ ↔ USDm. AgentKarma reputation tools (get_agentkarma_reputation, get_agentkarma_celo_agent, check_agentkarma_counterparty) live in domains/agentkarma.ts. On-chain attribution tools live in domains/blockchain.ts:
check_attribution_tag
Unified custom tags list (excludes platform CELINA/celina) or confirm one tag
verify_attribution_tag
Raw legacy + ERC-8021 layer decode
get_stake_eligibility
Before execute_stake — validates group headroom, locked balance, account registration
get_governance_delegates
User asks who to delegate to — Celo Mondo curated directory + optional stats
See On-chain attribution and Staking.
MCP remote (reference)
celina-mcp registers the catalog with @modelcontextprotocol/sdk — no Vercel AI SDK involved:
Build
ToolRuntime(SDK client +resolveWallet+ optionalexecutorsfor writes).filterToolDefinitions(..., { surface: "mcp", ... }).For each definition:
server.registerTool(name, { description, inputSchema }, handler).
See celina-mcp registerSdkTools / sdk-register.ts in the monorepo.
Vercel AI SDK (browser chat API)
For streamText / generateText, wrap definitions with dynamicTool, not tool() in a tight loop.
Using tool() plus ReturnType<typeof tool> over dozens of Zod schemas makes TypeScript infer a huge union and can OOM during next build (TS2589: Type instantiation is excessively deep).
Recommended pattern:
Runtime validation still uses each definition’s Zod schema inside the AI SDK; the cast only limits compile-time work.
Zod versions
celina-sdk/tools — Zod 3
Vercel AI SDK — supports Zod 3 or 4
If your app depends on Zod 4, keep using the catalog schemas as-is and the unknown → FlexibleSchema cast above. Aligning your app to Zod 3 avoids duplicate majors but is optional.
Sample browser app
Celeste AI is a reference browser surface chat UI: filterToolDefinitions(..., { surface: "browser" }), wagmi signing, send preflight (balance checks) in celeste-ai/src/lib/chat-tools/sdk-adapter.ts, and per-step simulatePreparedStep in tx-confirm-card.tsx (MiniPay feeCurrency resolved in Celeste only). It uses the SDK tool catalog directly — not celina-mcp.
Adding a new tool
Implement logic on
CelinaClient(service method or shared util insrc/tools/).Add a
ToolDefinitioninsrc/tools/domains/<domain>.ts(orbrowser.tsfor browser-only routing tools).Use snake_case input keys.
Set
familiesandsurfaces(["mcp"],["browser"], or omit for both).Call
resolveWalletFromRuntimeorruntime.resolveWalletfor wallet-scoped reads/prepares.
Export via
domains/index.tsif you added a new file.Wire the host:
MCP: definitions are picked up automatically after filter.
Browser chat: extend
ToolRuntime.hooksin your adapter if the tool needs host-specific behavior; update the app system prompt.
Test:
npm run test:unitin celina-sdk (tools-catalog.test.ts); run integration tests in MCP or your browser app.
validateToolCatalogSnakeCase() (unit tests) guards non–snake_case Zod keys.
Website tool docs sync
celina-website derives its MCP tool pages from this catalog:
npm run buildin celina-sdk (compilessrc/tools/website-sync.ts).npm run generate:website-toolswritescelina-website/src/data/tools.generated.ts(names, descriptions, categories, inputs).Rich
returns/exampleslive incelina-website/src/data/tools.overrides.ts.celina-websiteprebuildruns sync automatically.
Helpers exported from @andrewkimjoseph/celina-sdk/tools: getWebsiteToolBaselines, getHostedMcpToolCount, getMcpToolNameSet, toWebsiteToolBaseline.
See also
Architecture — stack and wallet-address rules
Prepared flows —
SerializedPreparedFlowforprepare_*toolsOn-chain attribution — dual tags, check vs verify
Account Abstraction —
createAAClient(SDK-first)MCP session wallet — omitting address on MCP stdio
Last updated
Was this helpful?