Skip to content

Built-in tools ​

The agent loop has access to a set of built-in tools that the LLM can call without any YAML configuration. Tools that require credentials are only registered when the relevant environment variable is set. Workflow tools: blocks are function calling, a different page.

FamilyToolsPage
Filesread_file, write_file, edit_file, list_files, md5_file, tail_fileFile tools. Edit file
Memory and identitymemory_save, memory_search, memory_delete, memory_query, identity_getMemory and identity
Knowledge vaultknowledge_recall, knowledge_card_get, knowledge_card_update, knowledge_note_save (while the vault is on: the default)Knowledge vault
Shellbash_exec, bash_job_list, bash_job_waitShell execution
Web and searchweb_search, wikipedia, web_scraper, plus keyed search APIsWeb and search
Datacalculator, sql_*, embeddings, rerankData tools
Actionshttp_request, search_local, load_document, transcribe_audio, ocr_image, Zapier, Google cacheAction tools
Structured operationsfile_ops, git_ops, sql_ops - the same handlers behind the file, git and sql componentsFile, Git, SQL
Harnessinstruct (alias help)Efficiency enforcement

Permission modes and lean mode stay on this page. The calling rules are their own pages: Fenced tools, Harness reminders, Session-integrity handshake.

Tool definitions ​

Each built-in tool's model-facing text is a YAML definition in the tools asset set, installed by kdeps update: the description, category, usage notes and parameter schema the model sees. The tool's code only supplies its name and what it runs.

yaml
# tools/md5_file.yaml (built-in, shown for reference)
version: 1.0.0       # bumped whenever the text the model sees changes
category: file       # section header in the tool list sent to the model
description: Compute the MD5 checksum of a file. Call once before and once after a change to prove whether the file's contents actually changed ...
seeAlso: read_file, tail_file, list_files   # shown as "See also: ..."
parameters:
  file_path:
    type: string
    description: Absolute (or cwd-relative) path to the file to hash. Omit to hash the file most recently accessed this session.

Optional fields: constraints (limits and gotchas, shown inline), outputFormat (what the tool returns), name (the tool name the model sees, when it differs from the file name), and aliases (see below).

Tool aliases ​

A model trained on another agent often calls a tool by the name it knows - bash, cat, grep, str_replace_editor - and gets "tool not found". A definition lists those names under aliases, and a call to one runs the tool:

yaml
# tools/bash_exec.yaml
version: 1.1.0
category: shell
aliases: [bash, shell, sh, terminal, run_command, execute_command, run_terminal_cmd, run_shell_command, exec_command]
text
model calls:   bash {"cmd": "go test ./..."}
kdeps runs:    bash_exec {"command": "go test ./..."}   # the alias picks the tool, then the argument synonyms below map cmd -> command

The model is shown only the tool's own name, so aliases add nothing to the prompt. Matching ignores case, a real tool's name always wins over an alias, and an alias two tools claim goes to neither (kdeps warns at load). Permissions, logging and the result all use the tool's own name. Shipped aliases:

ToolAliases
bash_execbash, shell, sh, terminal, run_command, execute_command, run_terminal_cmd, run_shell_command, exec_command
read_fileread, cat, view_file, open_file, read_text_file
write_filewrite, create_file, save_file, write_to_file
edit_fileedit, str_replace_editor, str_replace_based_edit_tool, replace_in_file, edit_text_file
list_filesls, list_dir, list_directory, dir
search_localgrep, rg, ripgrep, search_files, find_in_files, codebase_search, grep_search
tail_filetail
web_searchwebsearch, search_web, internet_search
web_scraperfetch, web_fetch, fetch_url, read_url
memory_saveremember, save_memory

A name that is neither a tool nor an alias still returns {"error": "tool \"<name>\" not found"}.

Declared HTTP tools ​

A tool whose definition has an http: block needs no Go code: kdeps registers it when the block's env resolves and runs it as one HTTP call. exa_search, wolfram_alpha, zapier_*, the three rerankers and retrieve_context ship this way, and a new HTTP-backed tool is one YAML file published to the tools set (or dropped into $KDEPS_ASSETS_SRC/tools/ while developing).

text
model calls tool -> args + parameter defaults -> render url/headers/body -> HTTP call -> render result -> model
yaml
# tools/wolfram_alpha.yaml (shipped)
version: 1.1.0
description: Query Wolfram Alpha for factual computations ... Requires WOLFRAM_APP_ID.
parameters:
  query:
    type: string
    required: true           # a missing required argument fails with "wolfram_alpha: query is required"
http:
  env:
    APP_ID: [WOLFRAM_APP_ID]  # .env.APP_ID; first non-empty variable wins; unset -> tool not offered
  method: GET
  url: "https://api.wolframalpha.com/v1/result?i={{urlquery .args.query}}&appid={{urlquery .env.APP_ID}}"
  cache: true                 # repeat calls with the same arguments reuse the answer for the run
yaml
# tools/cohere_rerank.yaml (shipped, abridged): JSON body and a templated result
parameters:
  documents: {type: string, required: true}   # a JSON array, decoded with fromJSON
  model: {type: string, default: rerank-v3.5} # defaults fill missing arguments before rendering
  top_n: {type: number, default: 5}
http:
  env:
    API_KEY: [COHERE_API_KEY]
  method: POST
  url: https://api.cohere.com/v2/rerank
  headers:
    Authorization: "Bearer {{.env.API_KEY}}"
  body: '{"model": {{json .args.model}}, "query": {{json .args.query}}, "documents": {{json (fromJSON .args.documents)}}, "top_n": {{int .args.top_n}}}'
  result: |-                  # rendered over .response (the parsed JSON body)
    {{range $i, $r := .response.results}}{{$r.index}}: {{$r.relevance_score}}
    {{end}}
FieldMeaning
envNames templates read as .env.NAME, each mapped to the variables that may hold it. Templates see no other environment variable.
methodGET, POST, PUT, PATCH or DELETE
url, headers, bodyGo templates over .args (arguments plus parameter defaults) and .env
resultTemplate over .args, .env and .response. Empty, or a body that is not JSON: the body is returned as is.
cacheReuse the answer for identical arguments within the run
timeoutPer-call limit (Go duration, default 30s)

A block can upload files: files maps form fields to path templates and form holds text fields (empty ones are left out), sent as multipart/form-data instead of body. paths lists the parameters holding file paths, checked against the workspace boundary like read_file's. An env entry whose variable list ends with "" is optional (it may render empty, and the tool registers without it), and a header that renders empty is not sent:

yaml
# tools/transcribe_audio.yaml (shipped, abridged)
http:
  env:
    OPENAI: [OPENAI_API_KEY, ""]     # optional: a local server may take it or no key at all
    GROQ: [GROQ_API_KEY, ""]
  method: POST
  url: '{{if .args.baseURL}}{{.args.baseURL}}{{else if eq .args.backend "groq"}}https://api.groq.com/openai/v1{{else if eq .args.backend "local"}}http://localhost:8080/v1{{else}}https://api.openai.com/v1{{end}}/audio/transcriptions'
  headers:
    Authorization: '{{if eq .args.backend "groq"}}{{with .env.GROQ}}Bearer {{.}}{{end}}{{else}}{{with .env.OPENAI}}Bearer {{.}}{{end}}{{end}}'   # omitted when empty
  files:
    file: "{{.args.file}}"           # uploaded as the "file" form field
  form:
    model: "{{.args.model}}"
    response_format: "{{.args.responseFormat}}"
  paths: [file]

Template helpers: json (encode), fromJSON (decode a string argument), urlquery, urlpath, trimSuffix, int, add, min, and get (nested lookup by key or index that yields nothing instead of failing on a missing level). A non-2xx status returns <tool>: API error <status>: <body> to the model. An http: block whose templates do not parse is rejected by kdeps update, so a broken download never replaces a working tool.

Declared SQL tools ​

A tool can run one parameterized SQLite statement. The statement is fixed in the YAML. Each argument named in params is bound to a ? placeholder in order. Arguments are never spliced into the text, so a value cannot change the statement.

yaml
# assets/tools/note_get.yaml
version: 1.0.0
description: Read one note by id.
parameters:
  id:
    type: string
    required: true
sql:
  dsn: KDEPS_NOTES_DB           # environment variable holding the SQLite file path
  query: SELECT id, title FROM notes WHERE id = ?
  params: [id]                  # bound to the ? placeholders, in order

mode: rows (the default) returns a JSON array of row objects. mode: exec runs a write and returns N rows changed. The tool is registered only when the environment variable is set.

Declared exec tools ​

A tool whose definition has an exec: block runs one program directly (no shell) and needs no Go code. ocr_image and transcribe_audio_offline ship this way.

yaml
# tools/ocr_image.yaml (shipped)
version: 1.1.0
description: Extract text from an image via tesseract OCR ...
parameters:
  file: {type: string, required: true}
  language: {type: string, default: eng}
exec:
  command: tesseract          # looked up on PATH when the tool runs
  install: tesseract-ocr      # the error names it when tesseract is missing
  paths: [file]               # checked against the workspace boundary before running
  args:                       # templates over .args; an arg that renders empty is dropped
    - "{{.args.file}}"
    - stdout
    - "-l"
    - "{{.args.language}}"
FieldMeaning
commandProgram to run, found on PATH
argsOne template per argument; empty results are dropped, so an optional flag is two conditional args
pathsParameters holding file paths; each is checked like read_file's path
installPackage to name when command is missing
envAs in an http: block: names templates read as .env.NAME (a trailing "" makes one optional)
timeoutPer-run limit (Go duration, default 60s)
resultTemplate over .args, .env and .stdout; empty returns stdout trimmed

A non-zero exit returns <tool>: <command>: exit status N: <stderr> to the model. A tool declares http: or exec:, not both.

Declared python tools ​

A tool whose definition has a python: block runs one Python script and needs no Go code. With no packages:, the script runs directly on the system python3 (or python), with no venv. With packages:, it runs on the kdeps python runner behind the python tool, which installs them into a venv with uv. The script reads the call's arguments as a JSON object from sys.argv[1] and prints its answer.

yaml
# tools/word_count.yaml (or ~/.kdeps/tools/word_count.yaml)
version: 1.0.0
description: Count the words in a text.
parameters:
  text:
    type: string
    required: true
python:
  script: |
    import json, sys
    args = json.loads(sys.argv[1])     # {"text": "..."}
    print(len(args["text"].split()))   # printed text is the tool's answer
  packages: []          # pip packages installed into the runner's venv first
  timeout: 30s          # optional; the runner's default when empty

A tool declares at most one of http:, exec:, sql: or python:.

Your own tools ​

A tool you write yourself goes in ~/.kdeps/tools/. A file with an http:, exec:, sql: or python: block is a new tool: kdeps registers it for the agent and serves it on /apis/tools.kdeps.io/v1/tools/<name>/call, with no registry or lock entry and no Go code. A file named like a shipped tool replaces that tool's definition.

yaml
# ~/.kdeps/tools/git_version.yaml - the file name is the tool name
version: 1.0.0
description: Print the installed git version.
exec:
  command: git          # run directly, no shell
  args: ["--version"]
bash
curl -s -X POST -H "Authorization: Bearer $KDEPS_API_TOKEN" -H "Content-Type: application/json" \
  -d '{}' http://127.0.0.1:9095/apis/tools.kdeps.io/v1/tools/git_version/call
# git version 2.47.0

The call runs in the kdeps API ​

A declared http: or exec: tool is served by the kdeps API like every other tool. The tool asset declares the call; the handler runs it. The agent loop and a workflow component both reach it the same way.

text
workflow YAML -> component YAML -> POST http://kdeps.api/apis/tools.kdeps.io/v1/tools/{name}/call -> handler -> http: or exec: block
agent loop    -> POST http://kdeps.api/apis/tools.kdeps.io/v1/tools/{name}/call -> handler -> http: or exec: block
yaml
# resources/ocr.yaml
actionId: ocrText
name: Extract text
component:
  name: ocr_image          # assets/components/ocr_image/component.yaml POSTs the tool's route
  with:
    file: /tmp/scan.png

A required env entry that is unset keeps the tool out of the agent's catalog; a direct API call returns <tool>: required environment variables are not set.

Parameter-name synonyms ​

A model sometimes names a tool's argument something plausible but not exact - grep's pattern instead of search_local's query, cat's path instead of read_file's file_path. These synonym keys are normalized to the key the tool actually expects before dispatch, without clobbering a real key already present. Alternate tool names are tool aliases, declared in each tool's definition.

Failed tool calls are fed back to the model ​

Every tool failure is returned to the model as {"error": ...} plus a [TOOL FAILED] banner ("nothing changed - fix the cause and retry, or say it failed"), so a skimmed error is hard to miss. The turn will not end on a "done" claim made right after a work tool failed: the loop pushes back for a real success or an honest "it failed" - up to twice, with the second push-back reading as a repeat, same bound as the other corrective nudges. If the model still has not acknowledged the failure after both, the turn does not settle on the bald claim unflagged: the response is followed by a notice naming the tool and its error, so the claim is kept but clearly marked unresolved. An honest admission at any point (in whatever words) is accepted immediately, no nudge needed.

Loop-generated notices - budget changes, context-window trims - are injected into the model's context as [kdeps] ... messages, since the human at the REPL cannot act on them but the model can adjust.

Permission modes ​

Set KDEPS_PERMISSION_MODE to restrict which tools the agent may call:

bash
KDEPS_PERMISSION_MODE=read-only ./kdeps          # reads, searches, lookups only
KDEPS_PERMISSION_MODE=workspace-write ./kdeps    # adds file writes and bash_exec
KDEPS_PERMISSION_MODE=danger-full-access ./kdeps # no restrictions (default)

Blocked calls return a permission denied tool error to the model, which explains the restriction instead of executing. Tools not in the built-in policy - including workflow, component, and agency tools - require workspace-write, so read-only blocks anything that could mutate state.

Lean mode ​

The full tool catalog (~61 tools - bash_exec, web_search, web_scraper, wikipedia, http_request, external API tools, plus the lean set below) is on by default for every session. Trim it down when you want less prompt weight (each tool costs tokens twice - once as a native tool schema, once as prose in the tool-use guidance) or a restricted surface for CI/automation:

/tools lean     # this session only, switch back any time
/tools full     # switch back
/tools          # show current mode and tool count

The choice persists automatically across sessions - no flag needed - the same way /model tool set settings do. Lean mode keeps read_file, write_file, edit_file, list_files, search_local, load_document, calculator, embedding_vectorize, embedding_search, transcribe_audio (~16 tools).

KDEPS_LEAN_MODE/KDEPS_AGENT_PRESET (below) start a session already in lean mode and take priority over the persisted /tools choice.

Agent presets ​

KDEPS_AGENT_PRESET combines lean mode with a permission mode in one flag for common workflows:

bash
KDEPS_AGENT_PRESET=audit       # read-only, lean tools
KDEPS_AGENT_PRESET=explain     # read-only, lean tools
KDEPS_AGENT_PRESET=implement   # workspace-write, lean tools
PresetPermission modeTool set
auditReadOnlyLean (no bash, no network)
explainReadOnlyLean (no bash, no network)
implementWorkspaceWriteLean + file writes

IsLeanOrPreseted() returns true when either KDEPS_LEAN_MODE or KDEPS_AGENT_PRESET is set.

See also ​

Released under the Apache 2.0 License.