Skip to content

Tools#

ECA supports 3 types of tools:

  • Native tools: (edit_file, write_file, read, etc)
  • MCP servers: if any configured
  • User custom tools: if defined

MCP#

For MCP servers configuration, use the mcpServers config, examples:

~/.config/eca/config.json
{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      // optional
      "env": {"FOO": "bar"}
    }
  }
}

ECA supports OAuth authentication automatically via MCP spec discovery.

~/.config/eca/config.json
{
  "mcpServers": {
    "cool-mcp": {
      "url": "https://my-remote-mcp.com/mcp"
    }
  }
}

Some providers (e.g. Databricks) require a pre-registered OAuth application and don't support dynamic client registration. Use clientId with the client ID from your provider's OAuth app settings.

~/.config/eca/config.json
{
  "mcpServers": {
    "databricks-sql": {
      "url": "https://my-workspace.cloud.databricks.com/api/2.0/mcp/sql",
      "clientId": "<your-oauth-app-client-id>"
    }
  }
}

For servers that accept a static token (e.g. a personal access token), set the Authorization header directly. This skips OAuth entirely.

~/.config/eca/config.json
{
  "mcpServers": {
    "my-api": {
      "url": "https://my-remote-mcp.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:MY_API_TOKEN}"
      }
    }
  }
}

Set "disabled": true to keep the configuration but prevent ECA from starting the server.

~/.config/eca/config.json
{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"],
      "disabled": true
    }
  }
}

Custom Tools#

You can define your own command-line tools that the LLM can use. These are configured via the customTools key in your config.json.

The customTools value is an object where each key is the name of your tool. Each tool definition has the following properties:

  • description: A clear description of what the tool does. This is crucial for the LLM to decide when to use it.
  • command: An string representing the command and its static arguments.
  • schema: An object that defines the parameters the LLM can provide.
    • properties: An object where each key is an argument name.
    • required: An array of required argument names.

Placeholders in the format {{argument_name}} within the command string will be replaced by the values provided by the LLM.

~/.config/eca/config.json
{
  "customTools": {
    "web-search": {
      "description": "Fetches the content of a URL and returns it in Markdown format.",
      "command": "trafilatura --output-format=markdown -u {{url}}",
      "schema": {
        "properties": {
          "url": {
            "type": "string",
            "description": "The URL to fetch content from."
          }
        },
        "required": ["url"]
      }
    }
  }
}
~/.config/eca/config.json
{
  "customTools": {
    "file-search": {
      "description": "${file:tools/my-tool.md}",
      "command": "find {{directory}} -name {{pattern}}",
      "schema": {
        "properties": {
          "directory": {
            "type": "string",
            "description": "The directory to start the search from."
          },
          "pattern": {
            "type": "string",
            "description": "The search pattern for the filename (e.g., '*.clj')."
          }
        },
        "required": ["directory", "pattern"]
      }
    }
  }
}

Disabled tools#

You can completely disable tools so they are never available to the LLM. This is configured via the disabledTools config, which accepts a list of tool name strings.

It can be set globally or per agent.

~/.config/eca/config.json
{
  "disabledTools": ["eca__shell_command", "my-mcp__dangerous_tool"]
}
~/.config/eca/config.json
{
  "agent": {
    "plan": {
      "disabledTools": ["eca__edit_file", "eca__write_file", "eca__move_file"]
    }
  }
}

Disabled vs Denied

disabledTools removes the tool entirely from the LLM — it won't even know it exists. This is different from toolCall.approval.deny which lets the LLM see the tool but blocks execution.

Approval / permissions#

By default, ECA asks to call any non read-only tool (default here), but that can easily be configured in several ways via the toolCall.approval config.

You can configure the default approval with byDefault and/or configure a tool in ask, allow or deny configs.

Check some examples:

~/.config/eca/config.json
{
  "toolCall": {
    "approval": {
      "byDefault": "allow"
    }
  }
}
~/.config/eca/config.json
{
  "toolCall": {
    "approval": {
      "byDefault": "allow",
      "ask": {
        "eca_editfile": {},
        "my-mcp__my_tool": {}
      }
    }
  }
}
~/.config/eca/config.json
{
  "toolCall": {
    "approval": {
      // "byDefault": "ask", not needed as it's eca default
      "allow": {
        "eca": {},
        "my-mcp": {}
      }
    }
  }
}

argsMatchers is a map of argument name by list of java regex.

~/.config/eca/config.json
{
  "toolCall": {
    "approval": {
      "byDefault": "allow",
      "ask": {
        "shell_command": {"argsMatchers": {"command": [".*rm.*",
                                                           ".*mv.*"]}}
      }
    }
  }
}
~/.config/eca/config.json
{
  "toolCall": {
    "approval": {
      "byDefault": "allow",
      "deny": {
        "shell_command": {"argsMatchers": {"command": [".*rm.*",
                                                       ".*mv.*"]}}
      }
    }
  }
}

Also check the plan agent which is safer.

The manualApproval setting was deprecated and replaced by the approval one without breaking changes