Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ A powerful, extensible AI coding agent CLI with multi-provider support, built-in

- **Multi-Provider LLM Support**: Anthropic, OpenAI, Google Gemini, Ollama, Azure OpenAI, AWS Bedrock, OpenRouter, and more
- **Built-in Core Tools**: bash (with interactive sudo password prompt), read, write, edit, grep, find, ls, subagent - no MCP overhead
- **Named Agents**: Reusable subagent presets defined in markdown with per-agent tool allowlists, advertised to the LLM for delegation
- **Smart @ Attachments**: Binary files auto-detected via MIME type, MCP resources via `@mcp:server:uri`
- **MCP Integration**: Connect external MCP servers for expanded capabilities
- **Extension System**: Write custom tools, commands, widgets, and UI modifications in Go
Expand Down Expand Up @@ -140,6 +141,9 @@ skill: # explicit skill files/dirs (disables auto-discovery)
skills-dir: "" # scan this directory directly for skills (overrides auto-discovery)
skill-disable: # hide skills from the model catalog by name (still usable via /skill:)
- some-skill

# Named agents
no-agents: false # set to true to disable named agent discovery (built-ins and definition files)
```

All of the above keys can also be set programmatically via the SDK
Expand Down Expand Up @@ -223,6 +227,7 @@ mcpServers:
--skills-dir Scan this directory directly for skills (overrides auto-discovery)
--skill-disable Hide a skill from the model catalog by name (repeatable); still usable via /skill:
--no-skills Disable skill loading (auto-discovery and explicit)
--no-agents Disable named agent discovery (built-ins and definition files)

# Generation parameters
--max-tokens Maximum tokens in response (default: 8192, auto-raised up to 32768 for models with larger known output limits)
Expand Down Expand Up @@ -494,6 +499,50 @@ Placeholders inside fenced code blocks (```) and inline code spans are ignored.

Disable templates with `--no-prompt-templates` or load a specific template with `--prompt-template <name>`.

### Named Agents

Define reusable subagent presets as markdown files. Named agents are advertised to the LLM in the `subagent` tool description, so the main agent can delegate tasks to the right specialist by name — with a preset system prompt, model, tool allowlist, temperature, and timeout.

**Discovery locations** (highest to lowest precedence):

1. `<project>/.agents/agents/*.md` — project-local (cross-client convention)
2. `<project>/.kit/agents/*.md` — project-local (Kit-specific)
3. `~/.config/kit/agents/*.md` — user-level (`$XDG_CONFIG_HOME` aware)
4. Built-in agents: `general` (full tool access) and `explore` (read-only: `read`, `grep`, `find`, `ls`)

The filename (minus `.md`) is the agent name. Higher-precedence definitions override lower ones, so a project can replace — or disable — a built-in or user-level agent.

**Example** (`.agents/agents/code-reviewer.md`):

```markdown
---
description: Reviews code for quality and best practices # required
model: anthropic/claude-sonnet-4 # optional model override
tools: [read, grep, find, ls] # optional tool allowlist
temperature: 0.1 # optional
timeout: 300 # optional, seconds
hidden: false # optional: resolvable but not advertised
disabled: false # optional: remove this agent (and anything it shadows)
---
You are in code review mode. Focus on correctness, security, and
maintainability. Report findings with file paths and line references.
```

The LLM invokes it through the `subagent` tool's `agent` parameter; explicit `model` / `system_prompt` / `timeout_seconds` arguments override the agent's presets. An agent without a `tools:` list gets the default subagent tool set (everything except `subagent`, preventing recursion); with a `tools:` allowlist the subagent is restricted to exactly those tools.

From the Go SDK:

```go
agents := k.GetAgents() // discovered definitions (built-ins included)

result, err := k.Subagent(ctx, kit.SubagentConfig{
Prompt: "Map out the session persistence flow",
Agent: "explore", // preset prompt + read-only tools
})
```

Disable discovery entirely with `--no-agents`, the `no-agents` config key (`.kit.yml`), `KIT_NO_AGENTS=true`, or `Options.NoAgents` in the SDK.

## GitHub Integration

Kit can run as an automated collaborator/reviewer inside GitHub Actions. The
Expand Down
7 changes: 7 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ var (
skillsDir string
skillsDisable []string

// Named agents control
noAgentsFlag bool

// TLS configuration
tlsSkipVerify bool

Expand Down Expand Up @@ -299,6 +302,8 @@ func init() {
// Skills flags
rootCmd.PersistentFlags().
BoolVar(&noSkillsFlag, "no-skills", false, "disable skill loading (auto-discovery and explicit)")
rootCmd.PersistentFlags().
BoolVar(&noAgentsFlag, "no-agents", false, "disable named agent discovery (built-ins and .agents/agents, .kit/agents, ~/.config/kit/agents)")
rootCmd.PersistentFlags().
StringSliceVar(&skillsPaths, "skill", nil, "load skill file or directory (repeatable)")
rootCmd.PersistentFlags().
Expand Down Expand Up @@ -359,6 +364,7 @@ func init() {
_ = viper.BindPFlag("prompt-template", rootCmd.PersistentFlags().Lookup("prompt-template"))
_ = viper.BindPFlag("no-prompt-templates", rootCmd.PersistentFlags().Lookup("no-prompt-templates"))
_ = viper.BindPFlag("no-skills", rootCmd.PersistentFlags().Lookup("no-skills"))
_ = viper.BindPFlag("no-agents", rootCmd.PersistentFlags().Lookup("no-agents"))
_ = viper.BindPFlag("skill", rootCmd.PersistentFlags().Lookup("skill"))
_ = viper.BindPFlag("skills-dir", rootCmd.PersistentFlags().Lookup("skills-dir"))
_ = viper.BindPFlag("skill-disable", rootCmd.PersistentFlags().Lookup("skill-disable"))
Expand Down Expand Up @@ -868,6 +874,7 @@ func runNormalMode(ctx context.Context) error {
DisableCoreTools: viper.GetBool("no-core-tools"),
CoreToolList: coreToolList,
NoSkills: noSkillsFlag,
NoAgents: noAgentsFlag,
Skills: skillsPaths,
SkillsDir: skillsDir,
SkillsDisable: skillsDisable,
Expand Down
11 changes: 10 additions & 1 deletion internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ type AgentConfig struct {
// Used by extensions to register custom tools.
ExtraTools []fantasy.AgentTool

// NamedAgents lists discovered named agent definitions to advertise in
// the subagent tool description (see core.WithNamedAgents). Only
// consumed when core tools are built from CoreToolList.
NamedAgents []core.NamedAgentSpec

// OnMCPServerLoaded, if non-nil, is called when each MCP server finishes
// loading (successfully or with error). The callback receives the server
// name, tool count, and any error. Called from the background goroutine.
Expand Down Expand Up @@ -315,7 +320,11 @@ func NewAgent(ctx context.Context, agentConfig *AgentConfig) (*Agent, error) {
coreTools = agentConfig.CoreTools
} else {
// Default: load all core tools
coreTools = core.ListedTools(agentConfig.CoreToolList)
var toolOpts []core.ToolOption
if len(agentConfig.NamedAgents) > 0 {
toolOpts = append(toolOpts, core.WithNamedAgents(agentConfig.NamedAgents...))
}
coreTools = core.ListedTools(agentConfig.CoreToolList, toolOpts...)
}

// Build the initial tool list: core tools + extension tools (no MCP yet).
Expand Down
5 changes: 5 additions & 0 deletions internal/agent/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"charm.land/fantasy"

"github.com/mark3labs/kit/internal/config"
"github.com/mark3labs/kit/internal/core"
"github.com/mark3labs/kit/internal/models"
"github.com/mark3labs/kit/internal/tools"
)
Expand Down Expand Up @@ -53,6 +54,9 @@ type AgentCreationOptions struct {
ToolWrapper func([]fantasy.AgentTool) []fantasy.AgentTool
// ExtraTools are additional tools to include (e.g. from extensions).
ExtraTools []fantasy.AgentTool
// NamedAgents lists discovered named agent definitions to advertise in
// the subagent tool description.
NamedAgents []core.NamedAgentSpec
// OnMCPServerLoaded, if non-nil, is called when each MCP server finishes
// loading (successfully or with error). Called from the background goroutine.
OnMCPServerLoaded func(serverName string, toolCount int, err error)
Expand All @@ -77,6 +81,7 @@ func CreateAgent(ctx context.Context, opts *AgentCreationOptions) (*Agent, error
CoreToolList: opts.CoreToolList,
ToolWrapper: opts.ToolWrapper,
ExtraTools: opts.ExtraTools,
NamedAgents: opts.NamedAgents,
OnMCPServerLoaded: opts.OnMCPServerLoaded,
MCPTaskConfig: opts.MCPTaskConfig,
}
Expand Down
Loading
Loading