도구 시스템
TinyElf의 도구 시스템은 ToolRegistry가 도구 등록과 실행을 담당하고, TinyElfToolRegistryBuilder가 세션 시작 시 전체 도구 세트를 빌드하는 역할을 합니다. 각 도구는 ITool 인터페이스를 구현합니다.
도구 등록 흐름
graph TB
Builder["TinyElfToolRegistryBuilder<br/>buildToolRegistry()"] --> Reg["ToolRegistry"]
Builder -->|"1. FileSystem"| FS["createFileSystemTools()<br/>Read, Write, Edit, ListDir, Glob, Grep"]
Builder -->|"2. Shell"| Shell["ShellTool<br/>Bash"]
Builder -->|"3. Web Search"| WS["setupWebSearch()<br/>WebSearch / NativeSearch"]
Builder -->|"4. Web Fetch"| WF["createWebFetchTool()<br/>WebFetch + summarizer"]
Builder -->|"5. Skills"| SK["SkillsTool + ReadSkillTool<br/>list_skills, read_skill"]
Builder -->|"6. SkillHub"| SH["SkillHubSearchTool + InstallTool<br/>skillhub_search, skillhub_install"]
Builder -->|"7. Sub-Agent"| SA["SpawnTool<br/>spawn_agent"]
Builder -->|"8. Sub-Agent Query"| SAQ["SubagentListTool + StatusTool"]
Builder -->|"9. Slash Command"| CMD["SlashCommandTool<br/>slash_command"]
Builder -->|"10. MCP"| MCP["loadMcpTools() + loadDirectMcpTools()<br/>mcp__*"]
Builder -->|"11. Session"| SS["SessionsSpawn/List/Send/History"]
Builder -->|"12. Control"| Ctrl["NotifyTool + SessionsYieldTool"]
FS --> Reg
Shell --> Reg
WS --> Reg
WF --> Reg
SK --> Reg
SH --> Reg
SA --> Reg
SAQ --> Reg
CMD --> Reg
MCP --> Reg
SS --> Reg
Ctrl --> Reg
ITool 인터페이스
interface ITool {
readonly name: string; // 고유 도구 이름 (function_calling 사용)
readonly description: string; // LLM이 읽을 수 있는 설명
readonly parameters: JsonSchema; // JSON Schema 파라미터 정의
execute(params: Record<string, unknown>): Promise<string>;
}
ToolRegistry
class ToolRegistry {
register(tool: ITool): void;
registerAll(tools: ITool[]): void;
unregister(name: string): boolean;
get(name: string): ITool | undefined;
has(name: string): boolean;
getAll(): ITool[];
getNames(): string[];
getDefinitions(): ToolDefinition[]; // OpenAI function_calling 형식
createFiltered(allowedNames: string[]): ToolRegistry;
execute(toolCallId, toolName, params): Promise<ToolCallResult>;
}
실행 흐름
- 도구 조회 → 도구를 찾을 수 없으면 오류 반환 (사용 가능한 도구 목록 표시)
- 파라미터 타입 변환 → 일반적인 LLM 타입 오류 처리 (string → number 등)
- 필수 파라미터 유효성 검사 → 누락 시 오류 반환
tool.execute(params)호출- 출력 잘라내기 →
maxChars(기본 50KB) 초과 시 잘라내고(truncated)표시 추가 - 오류 출력에 힌트 추가 →
[Analyze the error above and try a different approach.]
도구 필터링
createFiltered()는 허용 목록에 있는 도구만 포함하는 새 ToolRegistry 인스턴스를 생성합니다. 다음 용도로 사용됩니다:
plan모드에서 읽기 전용 도구만 허용- Agent 설정의
allowedTools필드 - Slash Command의
allowed-tools메타데이터
전체 도구 목록
FileSystem 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
Read | ReadFileTool | 안전 | path, offset?, limit? | 파일 내용 읽기, 부분 읽기 지원 |
Write | WriteFileTool | 민감 | path, content | 파일 쓰기 (생성 또는 덮어쓰기) |
Edit | EditFileTool | 민감 | path, old_string, new_string, replace_all? | 정밀 문자열 교체 |
ListDir | ListDirTool | 안전 | path | 디렉토리 내용 나열 |
Glob | GlobTool | 안전 | pattern, path? | 파일 이름 패턴 매칭 |
Grep | GrepTool | 안전 | pattern, path?, include? | 파일 내용 검색 |
FileSystem 도구 특징:
- 경로 샌드박스: 모든 경로는 워크스페이스 루트를 기준으로 해석됨
restrictToWorkspace설정으로 워크스페이스 외부 접근 허용 여부 제어Read는 대용량 파일(>128KB) 자동 잘라내기, 10MB 초과 시 offset/limit 필요
Shell 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
Bash | ShellTool | 민감 | command | 셸 명령 실행 |
Shell 도구 보안 기능:
- 명령 블랙리스트 (치명적 거부 패턴):
rm -rf /,format,mkfs,diskpart등 - 고위험 명령 경고:
sudo,curl | sh, 권한 변경 - 워크스페이스 외부 경로 감지
- 출력 한도: 100KB
- 타임아웃: 기본 2분,
execTimeout으로 설정 가능
Web 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
WebSearch | WebSearchServiceTool | 안전 | query, count? | 웹 검색 |
WebFetch | WebFetchTool | 안전 | url, prompt?, raw? | 웹 콘텐츠 가져오기 |
WebFetch 특징:
- Readability를 사용해 기사 본문 추출
- HTML → Markdown 변환 (Turndown)
- 4KB 초과 콘텐츠는 백그라운드 모델을 통해 자동 요약
- 30초 타임아웃, 최대 5MB 응답
웹 검색 3단계 폴백:
- 기본 제공 검색 (Anthropic/OpenAI/Gemini/xAI 내장)
- WebSearchService (Tavily/Jina/Searxng)
- 사용 불가
Sub-Agent 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
spawn_agent | SpawnTool | 민감 | prompt, agent?, model?, background?, maxIterations?, permissionMode?, tools? | 하위 Agent 실행 |
subagent_list | SubagentListTool | 안전 | 없음 | 활성 하위 Agent 목록 조회 |
subagent_status | SubagentStatusTool | 안전 | runId | 하위 Agent 상태 조회 |
Session 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
SessionsSpawn | SessionsSpawnTool | 민감 | prompt, agentId?, title? | 새 세션 생성 |
SessionsList | SessionsListTool | 안전 | limit?, offset? | 세션 목록 조회 |
SessionsSend | SessionsSendTool | 민감 | sessionId, message | 세션에 메시지 전송 |
SessionsHistory | SessionsHistoryTool | 안전 | sessionId, limit? | 세션 기록 조회 |
SessionsYield | SessionsYieldTool | 안전 | message | Agent 루프 종료 후 메시지 반환 |
Skills 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
list_skills | SkillsTool | 안전 | 없음 | 사용 가능한 모든 Skills 나열 |
read_skill | ReadSkillTool | 안전 | name | Skill 내용 읽기 |
skillhub_search | SkillHubSearchTool | 안전 | query | 커뮤니티 Skill 검색 |
skillhub_install | SkillHubInstallTool | 안전 | skillId | 커뮤니티 Skill 설치 |
MCP 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
mcp__<server>__<tool> | 동적 생성 | 민감 | MCP 서버에서 정의 | 외부 MCP 도구 |
MCP 도구는 세 가지 방식으로 로드됩니다:
- 사용자 MCP (
mcpServerIds) — 설정 → MCP에서 사용자가 구성한 stdio/http/sse 서버를 McpService를 통해 연결 - 내장 MCP (
McpProviderRegistry를 통해 자동 조립) — 모든 내장 MCP 핸들러가 프로세스 내에서 실행되며,createSdkMcpServer로 SDK 래핑, TinyElf가 ITool로 등록, CLI는 중앙BuiltinMcpHttpServerHTTP 브릿지를 통해 접근. 각 Agent에서 보이는 MCP는 Provider의isEligible(ctx)로직으로 결정됨 (Agent 설정의builtinMcpServers필드는 더 이상 탐색하지 않음 —cleanup-legacy-mcp(2026-05-19)에서 필드 삭제) - 직접 MCP (
directMcpServers) — Agent 설정에 미리 파싱된 stdio MCP 선언 (로컬 Python 도구 호출 등 사용자 시나리오)
Control 도구
| 도구 | 클래스 | 민감도 | 파라미터 | 설명 |
|---|---|---|---|---|
Notify | NotifyTool | 안전 | title, body? | 데스크톱 알림 전송 |
slash_command | SlashCommandTool | 안전 | command, args? | Slash Command 실행 |
도구 민감도 분류
private static readonly SAFE_TOOLS = new Set([
'Read', 'ListDir', 'Glob', 'Grep',
'WebSearch', 'WebFetch',
'list_skills', 'read_skill',
'Notify', 'SessionsYield', 'SessionsHistory',
]);
분류 규칙:
SAFE_TOOLS집합에 포함된 도구 → 확인 요청 없음acceptEdits모드에서는Write와Edit도 확인 요청 없음- 그 외 모든 도구 (MCP 도구 포함) → 확인 요청 필요
도구 상속
하위 Agent는 상위 Agent로부터 일부 도구를 상속받을 수 있습니다:
const inheritableToolNames = new Set([
'list_skills', 'read_skill', 'slash_command'
]);
// + mcp__로 시작하는 모든 MCP 도구
주요 파일
| 파일 | 경로 | 설명 |
|---|---|---|
| ITool 인터페이스 | tinyelf/tools/ToolInterface.ts | 도구 기본 인터페이스 |
| ToolRegistry | tinyelf/tools/ToolRegistry.ts | 도구 레지스트리 |
| ToolRegistryBuilder | tinyelf/TinyElfToolRegistryBuilder.ts | 도구 빌더 |
| FileSystemTools | tinyelf/tools/FileSystemTools.ts | FileSystem 도구 |
| ShellTool | tinyelf/tools/ShellTool.ts | Shell 도구 |
| WebTools | tinyelf/tools/WebTools.ts | WebFetch |
| WebSearchServiceTool | tinyelf/tools/WebSearchServiceTool.ts | WebSearch |
| SpawnTool | tinyelf/tools/SpawnTool.ts | Sub-Agent 도구 |
| SessionTools | tinyelf/tools/SessionTools.ts | 세션 관리 도구 |
| SkillsTool | tinyelf/tools/SkillsTool.ts | Skills 도구 |
| SkillHubTools | tinyelf/tools/SkillHubTools.ts | SkillHub 도구 |
| McpToolAdapter | tinyelf/tools/McpToolAdapter.ts | MCP 도구 어댑터 |
| NotifyTool | tinyelf/tools/NotifyTool.ts | 알림 도구 |
| YieldTool | tinyelf/tools/YieldTool.ts | 루프 종료 도구 |
| SubagentTools | tinyelf/tools/SubagentTools.ts | 하위 Agent 조회 도구 |
| SlashCommandTool | tinyelf/tools/SlashCommandTool.ts | Slash Command |
모든 경로는 packages/desktop/app/main/services/agent-core/engine/ 기준 상대 경로입니다.
확장 지점
- 새 도구 추가:
ITool인터페이스 구현 →TinyElfToolRegistryBuilder에 등록 - 민감도 수정:
TinyElfAgentLoop.SAFE_TOOLS집합에 추가/제거 - 커스텀 도구 상속:
inheritableToolNames집합 수정 - MCP 도구 로드:
McpToolAdapter를 통해 새 MCP 전송 방식 적용
관련 모듈
| 모듈 | 경로 | 관계 |
|---|---|---|
| TinyElfAgentLoop | tinyelf/TinyElfAgentLoop.ts | 도구 실행 호출자 |
| ExecutionFirewall | platform/security/ExecutionFirewall.ts | FileSystem 도구 경로 검사 |
| McpService | capabilities/tools/mcp-users/McpService.ts | MCP 도구 소스 |
| SkillsLoader | tinyelf/skills/SkillsLoader.ts | Skills 도구 의존성 |
| SubagentManager | tinyelf/tools/SpawnTool.ts | spawn_agent 의존성 |