Tools
Table of contents
- Lazy Tool Loading
- MCP Tools
- Available Tools
- Third-party Tools
- How to Use Tools
- Custom Tools
- Next Steps
chat.nvim supports tool call functionality, allowing the AI assistant to interact with your filesystem, manage memories, and perform other operations during conversations. Tools are invoked using the @tool_name syntax directly in your messages.
Lazy Tool Loading
By default, chat.nvim uses lazy tool loading to save prompt tokens: only the essential tools (tools.essential) plus the find_tool discovery tool are sent with each request. find_tool embeds a catalog of all available tools; the AI model looks up any other tool by name or keyword and receives its full parameter schema, which then becomes callable in the next response.
Tool activation is turn-scoped: when the model replies with plain text (no tool calls), the turn is complete and activated tools are cleared, so the next turn starts fresh from the essential toolset. Tools already called in the still-open turn are automatically re-included in requests (self-healing after an abort or restart mid tool-call loop).
A typical turn looks like this:
1. You send a message; the request carries the essential toolset + find_tool.
2. The model looks up a tool it needs: @find_tool query="git commit".
3. git_commit is activated for this turn and becomes callable in the next response.
4. The model keeps calling tools (@git_add, @git_commit, ...); tools already used
in this turn are re-included automatically.
5. The model replies with plain text (no tool call); the turn ends and activation
is cleared.
require('chat').setup({
tools = {
lazy = true, -- default; set false to send all tools with every request
essential = { 'read_file', 'list_directory', 'search_text', 'find_files', 'get_time' },
},
})
See find_tool for details.
MCP Tools
MCP (Model Context Protocol) tools are automatically discovered and integrated when MCP servers are configured. These tools follow the naming pattern mcp_<server>_<tool> and work seamlessly with built-in tools.
Example MCP Tools
mcp_open_webSearch_search- Web search via MCP servermcp_open_webSearch_fetchGithubReadme- Fetch GitHub README via MCPmcp_open_webSearch_fetchCsdnArticle- Fetch CSDN article via MCP
MCP tools are automatically available when their servers are configured in the mcp section of your setup configuration. See MCP Configuration for details.
Available Tools
Here is a list of 46 built-in tools:
| Tool | Description |
|---|---|
| read_file | Reads the content of a file |
| write_file | Write, modify, or delete file content (str_replace, chmod) |
| copy_file | Copy a file or directory (recursive) |
| create_directory | Create a directory (including parent directories) |
| delete_directory | Delete a directory (recursive) |
| file_info | Get file or directory metadata |
| list_directory | List directory contents with file metadata |
| move_file | Move or rename a file/directory |
| find_files | Finds files in the current working directory |
| search_text | Advanced text search using ripgrep |
| find_tool | Search and discover tools by name/keyword (lazy loading) |
| extract_memory | Extract memories from conversation text |
| recall_memory | Retrieve relevant information from memory system |
| set_prompt | Set system prompt from file |
| fetch_web | Fetch content from web URLs |
| web_search | Search the web using multiple engines |
| mastodon | Read-only Mastodon access: fetch toots/threads, search, timelines |
| get_time | Get current time and date information |
| get_weather | Get weather data from Meizu weather API |
| lsp_diagnostics | Get LSP diagnostics for a file |
| officecli | View office documents (Excel .xlsx) |
| ffmpeg | Convert images to WebP format using ffmpeg |
| make | Run make targets |
| git_add | Stage file changes for commit |
| git_branch | Manage git branches |
| git_checkout | Switch branches or restore files |
| git_commit | Create a git commit |
| git_config | Get, set, or list git configuration |
| git_diff | Run git diff to compare changes |
| git_fetch | Fetch changes from remote repository |
| git_log | Show commit logs with filters |
| git_merge | Merge branches |
| git_pull | Pull changes from remote and merge |
| git_push | Push commits to remote repository |
| git_rebase | Rebase current branch onto another branch |
| git_remote | Manage remote repositories |
| git_reset | Reset current HEAD to specified state |
| git_show | Show detailed changes of a specific commit |
| git_stash | Stash changes in git repository |
| git_status | Show the working tree status |
| git_tag | Manage git tags |
| get_history | Get conversation history messages (with search) |
| plan | Plan mode for task management |
| user_profile | Manage user profiles (人物画像) for personalized assistance |
| schedule_task | Schedule tasks to be executed at a future time (with skip_if_busy) |
| send_email | Send an email via the system mail command |
Third-party Tools
zettelkasten_create
Create new zettelkasten notes, provided by zettelkasten.nvim.
Usage
@zettelkasten_create <parameters>
Parameters
| Parameter | Type | Description |
|---|---|---|
title |
string | The title of zettelkasten note |
content |
string | The note body of zettelkasten |
tags |
array | Optional tags for the note (max 3) |
zettelkasten_get
Retrieve zettelkasten notes by tags, provided by zettelkasten.nvim.
Usage
@zettelkasten_get <tags>
Parameters
| Parameter | Type | Description |
|---|---|---|
tags |
array | Tags to search for (e.g., ["programming", "vim"]) |
How to Use Tools
1. Direct invocation
Include the tool call directly in your message:
Can you review this code? @read_file ./my_script.lua
2. Multiple tools
Combine multiple tools in a single message:
Compare these two configs: @read_file ./config1.json @read_file ./config2.json
3. Natural integration
The tool calls can be embedded naturally within your questions:
What's wrong with this function? @read_file ./utils.lua
4. Memory management
Use memory tools for context-aware conversations:
Based on what we discussed earlier about Vim: @recall_memory query="vim"
The AI assistant will process the tool calls, execute the specified operations, and incorporate their results into its response.
Custom Tools
chat.nvim supports both synchronous and asynchronous custom tools. Users can create lua/chat/tools/<tool_name>.lua file in their Neovim runtime path.
This module should provide at least two functions: scheme() and <tool_name> function. The scheme() function returns a table describing the tool’s schema (name, description, parameters). The <tool_name> function is the actual implementation that will be called when the tool is invoked.
Synchronous Tool Example
Here is an example for a synchronous get_weather tool:
local M = {}
function M.get_weather(action)
if not action.city or action.city == '' then
return { error = 'City name is required for weather information.' }
end
-- ... synchronous implementation ...
return { content = 'Weather in ...' }
end
function M.scheme()
return {
type = 'function',
['function'] = {
name = 'get_weather',
description = 'Get weather information for a specific city.',
parameters = {
type = 'object',
properties = {
city = {
type = 'string',
description = 'City name',
},
unit = {
type = 'string',
description = 'Temperature unit (celsius or fahrenheit)',
enum = { 'celsius', 'fahrenheit' },
},
},
required = { 'city' },
},
},
}
end
return M
Asynchronous Tool Example
For long-running operations, you can create asynchronous tools using job.nvim:
local M = {}
local job = require('job')
function M.fetch_data(action, ctx)
if not action.url or action.url == '' then
return { error = 'URL is required.' }
end
local stdout = {}
local stderr = {}
local jobid = job.start({
'curl',
'-s',
action.url,
}, {
on_stdout = function(_, data)
for _, v in ipairs(data) do
table.insert(stdout, v)
end
end,
on_stderr = function(_, data)
for _, v in ipairs(data) do
table.insert(stderr, v)
end
end,
on_exit = function(id, code, signal)
if code == 0 and signal == 0 then
ctx.callback({
content = table.concat(stdout, '\n'),
jobid = id,
})
else
ctx.callback({
error = 'Failed to fetch data: ' .. table.concat(stderr, '\n'),
jobid = id,
})
end
end,
})
if jobid > 0 then
return { jobid = jobid }
else
return { error = 'Failed to start job' }
end
end
function M.scheme()
return {
type = 'function',
['function'] = {
name = 'fetch_data',
description = 'Fetch data from a URL asynchronously.',
parameters = {
type = 'object',
properties = {
url = {
type = 'string',
description = 'URL to fetch data from',
},
},
required = { 'url' },
},
},
}
end
return M
Key Points for Asynchronous Tools
- Accept a second
ctxparameter containing{ cwd, session, callback }- Return
{ jobid = <number> }when starting async operation- Call
ctx.callback({ content = "..." })orctx.callback({ error = "..." })when done- The callback must include
jobidin the result to match the async tracking- chat.nvim will wait for all async tools to complete before sending results to AI
Next Steps
- Memory System - Learn about the memory system
- HTTP API - HTTP API integration
- IM Integration - Instant messaging integrations
Table of contents
- find_files
- read_file
- search_text
- write_file
- copy_file
- extract_memory
- make
- create_directory
- delete_directory
- recall_memory
- file_info
- set_prompt
- fetch_web
- list_directory
- move_file
- web_search
- git_diff
- git_log
- git_status
- git_show
- get_history
- plan
- get_time
- get_weather
- git_add
- git_branch
- git_checkout
- ffmpeg
- git_commit
- git_config
- lsp_diagnostics
- git_fetch
- officecli
- git_merge
- git_pull
- git_push
- git_rebase
- git_remote
- git_reset
- git_stash
- git_tag
- user_profile
- schedule_task
- find_tool
- mastodon
- send_email