# Tool catalog

`tnsai-tools` ships 63 toolkits with 209 `@Tool` methods in 29 categories. Each toolkit is a plain class whose public `@Tool` methods become tools, the same way as a class you register with `toolPojos(...)`.

To write your own, see [Custom tools](custom.md). To choose between an action, a tool and an MCP server, see [Actions and tools](../agents/actions-and-tools.md).

## Register toolkits

Pass `BuiltInTool` constants, and the framework creates each toolkit for you. `build()` requires `principal` and `authorityScope`; `liabilitySink` is optional.

<!-- java-contract: src/main/java/com/example/tnsai/docs/ToolsCatalogBuilderExample.java -->
```java
package com.example.tnsai.docs;

import com.tnsai.accountability.AuthorityScope;
import com.tnsai.accountability.LiabilitySink;
import com.tnsai.agents.Agent;
import com.tnsai.agents.AgentBuilder;
import com.tnsai.enums.BuiltInTool;
import com.tnsai.identity.AgentPrincipal;
import com.tnsai.llm.providers.OpenAIClient;
import com.tnsai.roles.Role;

public final class ToolsCatalogBuilderExample {
    private ToolsCatalogBuilderExample() {}

    public static Agent build(
        Role myRole,
        AgentPrincipal principal,
        LiabilitySink sink,
        AuthorityScope scope
    ) {
        return AgentBuilder.create()
            .llm(new OpenAIClient("gpt-4o"))
            .role(myRole)
            .builtInTools(
                BuiltInTool.WEB_SEARCH_TOOLS,
                BuiltInTool.UTILITY_TOOLS,
                BuiltInTool.PDF_TOOLS
            )
            .principal(principal)
            .liabilitySink(sink)
            .authorityScope(scope)
            .build();
    }
}
```

```java
String response = agent.chat("What is the population of Tokyo? Triple it.");
```

The model sees every `@Tool` method of every registered toolkit, and calls each by its `@Tool` name (`brave_search`, `calculator`, `pdf_extract_text`, …). Most toolkits read credentials from environment variables on first use:

```bash
export BRAVE_API_KEY=your-key
export OPENAI_API_KEY=your-key
```

## How toolkits are organised

Each `BuiltInTool` enum entry maps a stable `toolName` to the FQCN of a POJO in `tnsai-tools`. The POJO's public `@Tool`-annotated methods are the actual functions exposed to the LLM. For example, `BuiltInTool.CSV_TOOLS` backs `com.tnsai.tools.file.CsvTools`, which exposes `csv_summary`, `csv_columns`, `csv_filter`, `csv_head`, `csv_search`.

Each category is the toolkit's package under `com.tnsai.tools`:

| Category | `BuiltInTool` constants |
|---|---|
| `academic` | `ACADEMIC_TOOLS`, `ACADEMIC_EXTRA_TOOLS` |
| `ai` | `VISION_TOOLS` |
| `audio` | `TEXT_TO_SPEECH_TOOLS`, `SPEECH_TO_TEXT_TOOLS` |
| `code` | `E2B_SANDBOX_TOOLS`, `JS_EXECUTION_TOOLS`, `PYTHON_EXECUTION_TOOLS` |
| `commerce` | `ETSY_TOOLS`, `SHOPIFY_TOOLS` |
| `communication` | `EMAIL_TOOLS`, `MESSAGING_TOOLS` |
| `crm` | `HUBSPOT_TOOLS`, `SALESFORCE_TOOLS` |
| `database` | `MONGO_TOOLS`, `QDRANT_TOOLS`, `REDIS_TOOLS`, `SQL_TOOLS`, `WEAVIATE_TOOLS` |
| `developer` | `DEPENDENCY_TOOLS`, `DEVELOPER_TOOLS`, `PROJECT_ANALYZER_TOOLS` |
| `diagram` | `DIAGRAM_TOOLS` |
| `document` | `DOCUMENT_TOOLS`, `DOCLING_TOOLS` |
| `file` | `CSV_TOOLS`, `FILE_IO_TOOLS`, `JSON_TOOLS`, `MARKDOWN_TOOLS`, `PDF_TOOLS`, `XML_TOOLS` |
| `finance` | `FINANCE_TOOLS` |
| `fintech` | `AFTERPAY_TOOLS`, `CASH_APP_PAY_TOOLS`, `LIGHTNING_TOOLS`, `PAYMENT_ANALYTICS_TOOLS`, `SQUARE_TOOLS` |
| `goose` | `CLIPBOARD_TOOLS`, `GOOSE_TOOLS` |
| `image` | `IMAGE_GEN_TOOLS` |
| `knowledge` | `KNOWLEDGE_TOOLS` |
| `media` | `CHATTERBOX_TOOLS`, `MEDIA_TOOLS` |
| `memory` | `MEMORY_TOOLS` |
| `productivity` | `GOOGLE_TOOLS`, `JIRA_TOOLS`, `NOTION_TOOLS`, `TRELLO_TOOLS` |
| `project` | `PROJECT_TOOLS` |
| `realtime` | `REALTIME_TOOLS` |
| `scraping` | `SCRAPING_TOOLS` |
| `search` | `QNA_TOOLS`, `SPECIALIZED_SEARCH_TOOLS`, `WEB_SCRAPING_TOOLS`, `WEB_SEARCH_TOOLS` |
| `social` | `LINKEDIN_TOOLS`, `REDDIT_TOOLS`, `TWITTER_TOOLS` |
| `system` | `SYSTEM_TOOLS` |
| `trading` | `TRADING_TOOLS` |
| `utility` | `ENCODING_TOOLS`, `UTILITY_TOOLS` |
| `visualization` | `VISUALIZATION_TOOLS` |

The tables below list each toolkit's constant, its tools and the environment variables it needs. The tool names are what the model calls.

## search

Web search, scraping, and specialised lookups.

| Enum | Methods | API key |
|---|---|---|
| `WEB_SEARCH_TOOLS` | `duckduckgo`, `wikipedia`, `wikidata`, `searxng`, `npm`, `maven_central`, `brave_search`, `serpapi`, `tavily`, `exa` | Per-provider (none for the first six, and `BRAVE_API_KEY`, `SERPAPI_API_KEY`, `TAVILY_API_KEY`, `EXA_API_KEY` for the last four) |
| `WEB_SCRAPING_TOOLS` | `web_scraper`, `firecrawl` | `FIRECRAWL_API_KEY` (firecrawl only) |
| `QNA_TOOLS` | `hackernews`, `stackoverflow_search` | Optional `STACKEXCHANGE_KEY` for Stack Overflow |
| `SPECIALIZED_SEARCH_TOOLS` | `yahoo_finance_lookup`, `yahoo_finance_news`, `wolfram_alpha` | `WOLFRAM_APP_ID` (wolfram only) |

## academic

Free / freemium scholarly databases.

| Enum | Methods | API key |
|---|---|---|
| `ACADEMIC_TOOLS` | `arxiv_search`, `pubmed_search`, `semantic_scholar_search`, `openalex_search`, `crossref_search`, `dblp_search` | Optional `SEMANTIC_SCHOLAR_API_KEY` and `OPENALEX_MAILTO` |
| `ACADEMIC_EXTRA_TOOLS` | `orcid_search`, `orcid_get`, `unpaywall_lookup`, `biorxiv_recent` | `UNPAYWALL_EMAIL` for Unpaywall |

## file

Text and structured-document parsing.

| Enum | Methods | Notes |
|---|---|---|
| `CSV_TOOLS` | `csv_summary`, `csv_columns`, `csv_filter`, `csv_head`, `csv_search` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `JSON_TOOLS` | `json_query` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `XML_TOOLS` | `xml_query` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `PDF_TOOLS` | `pdf_extract_text`, `pdf_extract_pages`, `pdf_metadata`, `pdf_merge`, `pdf_to_image` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `MARKDOWN_TOOLS` | `markitdown` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `FILE_IO_TOOLS` | `file_read`, `file_write` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |

### `CSV_TOOLS` example

`CsvTools` is the canonical example for the function-shape pattern. The five methods below are independent, and the LLM picks the one it needs.

```java
Agent agent = AgentBuilder.create()
    .llm(new OpenAIClient("gpt-4o"))
    .role(myRole)
    .builtInTools(BuiltInTool.CSV_TOOLS)
    .principal(principal)
    .liabilitySink(sink)
    .authorityScope(scope)
    .build();

agent.chat("Summarise /data/sales.csv and list the column headers.");
// LLM emits two tool calls: csv_summary("/data/sales.csv") then csv_columns(...)
```

| Method | Purpose | Notes |
|---|---|---|
| `csv_summary` | Row/column counts plus per-column dtype/null stats | Default for "describe this CSV" prompts |
| `csv_columns` | Extract a subset of columns by name | Case-insensitive, falling back to numeric index |
| `csv_filter` | Rows where a column's value contains a substring | Case-insensitive substring, capped at 100 rows |
| `csv_head` | First N rows as a Markdown ASCII table | |
| `csv_search` | All rows where any cell contains the term | Capped at 100 rows |

The methods accept typed parameters (path, column name, etc.). Each method is a regular Java method whose signature defines the LLM-facing schema (via `@Tool` and `@ToolParam`).

## communication

Email, chat, and SMS sending.

| Enum | Methods | Config |
|---|---|---|
| `EMAIL_TOOLS` | `smtp_send`, `gmail_send`, `gmail_inbox` | SMTP: `SMTP_HOST`, `SMTP_PORT`, `SMTP_USERNAME`, `SMTP_PASSWORD`, `SMTP_AUTH`, `SMTP_STARTTLS_ENABLE`. Gmail: `GMAIL_ACCESS_TOKEN`, `GMAIL_USER` |
| `MESSAGING_TOOLS` | `slack_post`, `discord_post`, `twilio_sms_send`, `twilio_sms_status` | `SLACK_WEBHOOK_URL`, `DISCORD_WEBHOOK_URL`. Twilio: `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, `TWILIO_FROM` |

## fintech

Payment and BNPL platforms.

| Enum | Methods | API key |
|---|---|---|
| `SQUARE_TOOLS` | `square_create_payment`, `square_list_payments`, `square_create_invoice`, `square_create_customer`, `square_search_catalog` | `SQUARE_ACCESS_TOKEN`, `SQUARE_LOCATION_ID`, with `SQUARE_SANDBOX` selecting the sandbox host |
| `CASH_APP_PAY_TOOLS` | `cashapp_create_request`, `cashapp_get_request`, `cashapp_cancel_request` | `CASHAPP_ACCESS_TOKEN`, with `CASHAPP_SANDBOX` selecting the sandbox host |
| `LIGHTNING_TOOLS` | `lightning_create_invoice`, `lightning_pay_invoice`, `lightning_decode_invoice` | `LIGHTNING_NODE_URL`, `LND_MACAROON` |
| `AFTERPAY_TOOLS` | `afterpay_create_checkout`, `afterpay_capture_payment`, `afterpay_get_order` | `AFTERPAY_MERCHANT_ID`, `AFTERPAY_SECRET_KEY`, with `AFTERPAY_SANDBOX` selecting the sandbox host |
| `PAYMENT_ANALYTICS_TOOLS` | `payment_revenue_summary` | Square source: `SQUARE_ACCESS_TOKEN`, `SQUARE_LOCATION_ID`, with `SQUARE_SANDBOX` selecting the sandbox host |

## commerce

Storefront APIs.

| Enum | Methods | API key |
|---|---|---|
| `SHOPIFY_TOOLS` | `shopify_search`, `shopify_get_product` | `SHOPIFY_STOREFRONT_TOKEN`, `SHOPIFY_SHOP_DOMAIN` |
| `ETSY_TOOLS` | `etsy_search`, `etsy_get_listing`, `etsy_get_shop` | `ETSY_API_KEY` |

## crm

Customer-relationship platforms.

| Enum | Methods | API key |
|---|---|---|
| `HUBSPOT_TOOLS` | `hubspot_list_contacts`, `hubspot_get_contact`, `hubspot_create_contact` | `HUBSPOT_ACCESS_TOKEN` |
| `SALESFORCE_TOOLS` | `salesforce_query`, `salesforce_search`, `salesforce_get_sobject` | `SALESFORCE_INSTANCE_URL`, `SALESFORCE_ACCESS_TOKEN` |

## database

Relational, document, key-value, and vector stores.

| Enum | Methods | Config |
|---|---|---|
| `SQL_TOOLS` | `sql_query` | `SQL_JDBC_URL`, `SQL_JDBC_USERNAME`, `SQL_JDBC_PASSWORD`, `SQL_JDBC_MAX_ROWS`, plus the driver on the classpath |
| `MONGO_TOOLS` | `mongo_find`, `mongo_count` | `MONGODB_URI`, `MONGODB_DATABASE` |
| `REDIS_TOOLS` | `redis_get`, `redis_keys`, `redis_ttl`, `redis_set`, `redis_del` | `REDIS_URL` |
| `QDRANT_TOOLS` | `qdrant_collections`, `qdrant_count`, `qdrant_search`, `qdrant_create_collection`, `qdrant_upsert` | `QDRANT_URL`, optional `QDRANT_API_KEY` |
| `WEAVIATE_TOOLS` | `weaviate_classes`, `weaviate_count`, `weaviate_search`, `weaviate_create_class`, `weaviate_upsert` | `WEAVIATE_URL`, optional `WEAVIATE_API_KEY` |

`sql_query` is read-only. It rejects modifying CTEs and `SELECT INTO` (write
tokens outside string literals, not a leading-keyword check) and opens the JDBC session
`Connection.setReadOnly(true)` inside a read-only transaction so a
`WITH … DELETE` prefix cannot commit even if a dialect accepts it.
Dialects without read-only SQL still get `setReadOnly` plus
auto-commit-off and rollback.

## developer

Repo, dependency, and project introspection.

| Enum | Methods | API key |
|---|---|---|
| `DEVELOPER_TOOLS` | `github_search_repos`, `github_search_code`, `github_search_issues`, `github_search_users`, `jshell_eval` | `GITHUB_TOKEN` (optional, raises rate limit) |
| `DEPENDENCY_TOOLS` | `dependency_latest`, `dependency_compare`, `project_detect_type` | None |
| `PROJECT_ANALYZER_TOOLS` | `project_tree`, `project_stats`, `project_languages` | None |

## productivity

Calendars, task trackers, docs.

| Enum | Methods | API key |
|---|---|---|
| `GOOGLE_TOOLS` | `gcal_list_events`, `gcal_get_event`, `gcal_create_event`, `gdrive_list_files`, `gdrive_read_file`, `gdrive_create_file` | `GOOGLE_CALENDAR_ACCESS_TOKEN`, `GOOGLE_DRIVE_ACCESS_TOKEN` |
| `JIRA_TOOLS` | `jira_search`, `jira_get_issue`, `jira_create_issue`, `jira_transition_issue` | `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` |
| `NOTION_TOOLS` | `notion_search`, `notion_get_page`, `notion_query_database`, `notion_create_page` | `NOTION_API_KEY` |
| `TRELLO_TOOLS` | `trello_list_boards`, `trello_get_board`, `trello_list_cards`, `trello_create_card`, `trello_move_card` | `TRELLO_API_KEY`, `TRELLO_TOKEN` |

## media

OpenAI audio and Chatterbox TTS.

| Enum | Methods | API key |
|---|---|---|
| `MEDIA_TOOLS` | `whisper_transcribe`, `openai_tts` | `OPENAI_API_KEY` |
| `CHATTERBOX_TOOLS` | `chatterbox_tts` | `CHATTERBOX_API_URL`, optional `CHATTERBOX_API_KEY` |

## audio

Non-OpenAI speech synthesis and transcription.

| Enum | Methods | API key |
|---|---|---|
| `TEXT_TO_SPEECH_TOOLS` | `elevenlabs_tts`, `cartesia_tts`, `deepgram_tts` | `ELEVENLABS_API_KEY`, `CARTESIA_API_KEY`, or `DEEPGRAM_API_KEY` |
| `SPEECH_TO_TEXT_TOOLS` | `deepgram_transcribe`, `assemblyai_transcribe`, `replicate_whisper` | `DEEPGRAM_API_KEY`, `ASSEMBLYAI_API_KEY`, or `REPLICATE_API_TOKEN` |

## social

Social-network APIs.

| Enum | Methods | API key |
|---|---|---|
| `TWITTER_TOOLS` | `twitter_search`, `twitter_user`, `twitter_timeline` | `TWITTER_BEARER_TOKEN` |
| `REDDIT_TOOLS` | `reddit_search`, `reddit_subreddit_posts`, `reddit_post_comments` | `REDDIT_CLIENT_ID`, `REDDIT_CLIENT_SECRET`, optional `REDDIT_USER_AGENT` |
| `LINKEDIN_TOOLS` | `linkedin_me`, `linkedin_share` | `LINKEDIN_ACCESS_TOKEN` |

## ai

Multimodal helpers.

| Enum | Methods | API key |
|---|---|---|
| `VISION_TOOLS` | `image_analyze` | `GEMINI_API_KEY` |

## image

Image generation. See [Images and speech](images-and-speech.md).

| Enum | Methods | API key |
|---|---|---|
| `IMAGE_GEN_TOOLS` | `dalle3_generate`, `flux_generate`, `stability_generate` | `OPENAI_API_KEY`, `REPLICATE_API_TOKEN`, or `STABILITY_API_KEY` |

## code

Code execution through the framework's [Sandbox SPI](../security/sandbox.md). The Python and Node toolkits run through the `process` sandbox by default, with `ResourceLimits.standard()` and `NetPolicy.denyAll()`. For container isolation, pass a `SandboxFactory` and a `SandboxSpec` with an image to their full constructors. E2B runs code remotely, in E2B's cloud.

| Enum | Methods | Host requirement |
|---|---|---|
| `JS_EXECUTION_TOOLS` | `js_execute` | `PATH`, plus optional `NODE_PATH_BINARY` to select the Node executable |
| `PYTHON_EXECUTION_TOOLS` | `python_execute`, `python_version` | `PATH`, plus optional `PYTHON_PATH` and `PYTHON_VENV_PATH` to select the interpreter and environment |
| `E2B_SANDBOX_TOOLS` | `e2b_create`, `e2b_execute`, `e2b_upload`, `e2b_download`, `e2b_install`, `e2b_list`, `e2b_kill` | `E2B_API_KEY` |

## utility

Math, hashing, datetime, encoding.

| Enum | Methods | API key |
|---|---|---|
| `UTILITY_TOOLS` | `calculator`, `hash`, `datetime_now`, `datetime_diff`, `datetime_add` | None |
| `ENCODING_TOOLS` | `qr_generate`, `qr_base64`, `qr_read`, `google_translate` | `GOOGLE_TRANSLATE_API_KEY` (translate only) |

## diagram

Diagram-as-code rendering.

| Enum | Methods | API key |
|---|---|---|
| `DIAGRAM_TOOLS` | `mermaid_render`, `excalidraw_generate` | None |

## document

DOCX / Office / image conversion.

| Enum | Methods | API key |
|---|---|---|
| `DOCUMENT_TOOLS` | `document_read`, `markdown_to_html`, `image_convert`, `image_info`, `slides_create` | File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT` |
| `DOCLING_TOOLS` | `docling_parse` | Registers without a provider, so calls fail until you register a configured `DoclingTools` instead. File guard: `TNSAI_FILE_MAX_READ_BYTES`, `TNSAI_FILE_MAX_WRITE_BYTES`, `TNSAI_FILE_ALLOWED_EXTS`, `TNSAI_FILE_SANDBOX_ROOT`. See [Docling](docling.md) |

## visualization

Charts, tables, infographics.

| Enum | Methods | API key |
|---|---|---|
| `VISUALIZATION_TOOLS` | `chart_ascii`, `table_format`, `infographic_templates` | None |

## realtime

Live FX, crypto, weather feeds.

| Enum | Methods | API key |
|---|---|---|
| `REALTIME_TOOLS` | `crypto_price`, `fx_rates`, `fx_convert`, `weather_current` | `OPENWEATHER_API_KEY` for weather. CoinGecko and Frankfurter calls need no key |

## finance

Borsa Istanbul market data.

| Enum | Methods | API key |
|---|---|---|
| `FINANCE_TOOLS` | `bist_quote`, `bist_index`, `bist_fx`, `bist_gold` | None |

## trading

Prediction markets.

| Enum | Methods | API key |
|---|---|---|
| `TRADING_TOOLS` | `polymarket_markets`, `polymarket_search`, `polymarket_prices` | None (read-only) |

## scraping

Apify actor execution.

| Enum | Methods | API key |
|---|---|---|
| `SCRAPING_TOOLS` | `apify_run_actor`, `apify_search_actors`, `apify_actor_info` | `APIFY_API_KEY` |

## knowledge

In-memory knowledge graph. Live triples are also the bundled GraphRAG backend when `tnsai-rag` is installed. See [Graph stores](../rag/graph-stores.md).

| Enum | Methods | API key |
|---|---|---|
| `KNOWLEDGE_TOOLS` | `kg_extract_entities`, `kg_extract_relations`, `kg_add_triple`, `kg_query` | None |

## memory

Persistent recall.

| Enum | Methods | API key |
|---|---|---|
| `MEMORY_TOOLS` | `reever_store`, `reever_recall`, `reever_search` | `REEVER_API_URL` selects the Reever endpoint |

## goose

Desktop automation.

| Enum | Methods | API key |
|---|---|---|
| `GOOSE_TOOLS` | `git_status`, `git_log`, `git_diff`, `git_branches`, `screenshot`, `system_info` | `git` on PATH |
| `CLIPBOARD_TOOLS` | `clipboard_read_text`, `clipboard_write_text` | None (headless-aware) |

## project

Repo-level read helpers.

| Enum | Methods | API key |
|---|---|---|
| `PROJECT_TOOLS` | `project_context`, `project_read_file`, `agentsmd_parse`, `agentsmd_generate` | None (sandboxed by Role policy) |

`agentsmd_parse` returns an `AgentsMdContent` record (`intro` + ordered `sections: [{level, title, body}]`) parsed from `AGENTS.md`, with case-variant + `CLAUDE.md` + `README.md` fallback. Use this when an agent needs to route on individual sections (e.g. pull the "Setup" body) rather than the whole document. `agentsmd_generate` produces a draft `AGENTS.md` by detecting the build system from `pom.xml` / `package.json` / `pyproject.toml` / `Cargo.toml` / `go.mod` and filling in language-appropriate setup + test commands. It returns the markdown string, and the caller decides whether to write it.

## system

HTTP and tool discovery.

| Enum | Methods | API key |
|---|---|---|
| `SYSTEM_TOOLS` | `http_request`, `tool_search` | `TNSAI_HTTP_ALLOW_PRIVATE` opts into private-network requests |

## Direct instantiation

To register a toolkit another way, for example from a plugin loader, call `instantiate()`. It returns a new instance of the toolkit class:

```java
Object csvToolkit = BuiltInTool.CSV_TOOLS.instantiate();
// a com.tnsai.tools.file.CsvTools instance

for (BuiltInTool entry : BuiltInTool.values()) {
    System.out.println(entry.getToolName() + " -> " + entry.getClassName());
}
```

`instantiate()` throws `BuiltInToolInstantiationException` if `tnsai-tools` is missing from the classpath (the FQCN string isn't resolvable) or if the POJO's public no-arg constructor fails.

## Authoritative source

The full per-toolkit Javadoc, including every `@Tool` method's exact signature and the corresponding `@ToolParam` constraints, lives in [`com.tnsai.enums.BuiltInTool`](https://github.com/TnsAI-Framework/TnsAI/blob/main/tnsai-core/src/main/java/com/tnsai/enums/BuiltInTool.java) and the backing POJOs under [`com.tnsai.tools.*`](https://github.com/TnsAI-Framework/TnsAI/tree/main/tnsai-tools/src/main/java/com/tnsai/tools).
