대시보드
Morit Plugin4. 기능, 데이터, 사용자 제어

Tool, Skill, Search, Slash Command

Capability는 사용자가 실행할 수 있는 한 가지 작업과 그 실행 경계를 선언합니다. UI에서 버튼을 누르거나 AI가 Tool을 선택해도 같은 capability가 실행됩니다.

Capability kind

kind목적실행 방식
tool명시적인 한 번의 작업UI, AI, Slash Command
skill여러 입력을 해석하는 작업AI, UI, Slash Command
providerAI 검색 후보 제공Search discovery
background일정 간격의 자동 작업Host scheduler
notification알림 생성·취소 작업UI, AI 또는 background

toolskill은 runtime adapter가 필수입니다. providerruntime.role: "search"가 필요합니다. background runtime을 선언하면 interval_minutes는 15~10,080입니다.

Runtime adapter

adapter용도주요 설정·권한
text_stats텍스트 통계별도 권한 없음
text_template제한된 텍스트 templatetemplate 최대 2,000자
settings_searchInstance settings의 검색 항목Search Provider용
notification_template검증된 알림 Host action 생성notifications
calendar_store일정 저장·조회·reminderstorage, reminder는 notifications
http_json공개 HTTPS JSON APInetwork, credential 사용 시 credentials
mcp_httpRemote MCP Tool 호출network, 선택적 credentials
child_plugindependency capability 호출노출된 dependency와 capability
neis_school학교 검색·시간표·급식·일정network, storage; reminder는 notifications
sandbox_python격리된 Python 데이터 작업signed package와 고급 worker

선언형 adapter 예

Text template

json
{
  "adapter": "text_template",
  "template": "요청을 다음 형식으로 정리합니다: {query}"
}

복잡한 표현식이나 코드를 template에 넣지 않습니다.

Calendar store

json
{
  "adapter": "calendar_store",
  "operation": "reminder",
  "namespace": "study.schedule"
}

일반 저장에는 storage, 알림 예약에는 storagenotifications가 모두 필요합니다.

HTTP JSON

json
{
  "adapter": "http_json",
  "connector_id": "notes_api",
  "method": "POST",
  "request_body": {"query": "{query}"},
  "response": {"summary_path": "message", "data_path": "data"}
}

GET과 POST만 지원하며 redirect를 따라가지 않습니다. endpoint는 공개 HTTPS이고 SSRF 보호 경계를 통과합니다. bearer token은 Host가 Connection에서 주입하며 fragment에 직접 쓰지 않습니다.

Remote MCP

Morit Host 1.7.12의 plugin outbound MCP adapter는 mcp_http입니다. 개발자용 Local/Remote Plugin MCP 서버와 이름이 비슷하지만, 설치된 플러그인이 선언한 외부 MCP Tool을 Host 경계에서 호출하는 runtime입니다.

json
{
  "adapter": "mcp_http",
  "connector_id": "research_mcp",
  "tool_name": "search",
  "protocol_version": "2025-11-25",
  "argument_template": {"query": "{query}"}
}

Host가 initialize → initialized → tools/call session을 관리합니다. credential이 거부되면 지원되는 연결에서 한 번 갱신한 뒤 새 session으로 재시도합니다. MCP의 isError: true는 성공 결과로 바꾸지 않습니다.

Sandbox Python

json
{
  "adapter": "sandbox_python",
  "entrypoint": "src/analyze.py"
}

entrypoint는 package 상대 POSIX 경로이고 각 src/*.py 파일과 정확히 1:1이어야 합니다. 코드는 Archive API process에서 실행하지 않고 별도 rootless Docker + gVisor worker와 lease-fenced broker를 거칩니다. 결과는 다음 객체여야 합니다.

json
{
  "summary": "분석을 완료했습니다.",
  "data": {},
  "evidence": []
}

summary 없이 sandbox 경로나 내부 로그만 반환하면 완료된 결과가 아닙니다.

UI와 AI 노출

AI는 enabled 상태이고 사용자에게 허용된 capability만 발견합니다. 제목과 설명은 모델이 언제 이 기능을 선택할지 판단할 수 있게 동작과 입력을 구체적으로 씁니다.

Slash Command나 UI extension은 선택적 진입점일 뿐 discovery 조건이 아닙니다. 활성 Plugin의 모든 tool·skill은 매 AI turn의 actor-scoped capability catalog에 자동 포함됩니다. 설치·업데이트· enable/disable·권한 변경·Connection 생성/수정/삭제·OAuth 완료·삭제 뒤 Host는 Instance route cache를 즉시 비워 다음 turn과 실행이 새 generation을 사용하게 합니다.

json
{
  "id": "school_life.today",
  "kind": "tool",
  "title": "오늘 학교 생활 조회",
  "description": "연결한 학교의 오늘 시간표, 급식, 학사일정을 조회합니다.",
  "permissions": ["network", "storage"],
  "timeout_seconds": 10,
  "input_schema": {
    "type": "object",
    "properties": {"date": {"type": "string"}},
    "additionalProperties": false
  },
  "output_schema": {
    "type": "object",
    "properties": {"timetable": {"type": "array", "items": {"type": "object"}}},
    "required": ["timetable"]
  },
  "runtime": {"adapter": "neis_school", "operation": "overview"}
}

input_schema/output_schema는 root object인 안전한 JSON Schema 부분집합입니다. AI Tool, UI data source·invoke, Host 실행과 결과 binding이 같은 schema를 사용합니다. CLI/MCP validate는 필수 필드·타입·범위와 data.<source>.data... 경로를 package build 전에 검사합니다. 실행 시 schema와 다른 외부 응답은 정상 결과로 변환하지 않고 해당 capability 오류로 격리합니다.

UI invoke가 capability를 참조할 때도 enabled, generation, permission, timeout을 다시 확인합니다. UI에 capability ID를 사용자용 라벨로 표시하지 않습니다.

Slash Command

Slash Command는 같은 package의 tool 또는 skill에 고정된 진입점입니다.

json
{
  "id": "school_life.today_command",
  "command": "school",
  "title": "오늘 학교 생활",
  "description": "오늘 시간표와 급식을 확인합니다.",
  "capability": "school_life.today",
  "argument_template": {}
}

Slash Command를 선언하지 않아도 Tool discovery는 유지됩니다. 여러 command가 같은 이름을 사용할 수 없고 /command 값에 포함하지 않습니다.

실패와 복구

Capability는 권한 부족, 연결 필요, timeout, retryable network 오류, 잘못된 응답을 구분합니다. retry는 Connector에 선언한 bounded 정책만 사용합니다. Tool 하나가 실패했다고 AI 요청 전체를 즉시 포기하지 말고, 오케스트레이터가 대체 Tool·재연결·부분 결과를 선택할 수 있도록 공개 오류를 구체적으로 유지합니다.

실행 준비 상태의 대표 code는 EXTENSION_NOT_FOUND, EXTENSION_PERMISSION_DENIED, EXTENSION_CONNECTION_REQUIRED, EXTENSION_DISABLED, EXTENSION_VERSION_MISMATCH, EXTENSION_DEPENDENCY_REQUIRED입니다. 빈 Tool 목록이나 일반 실패 문구로 합치지 마세요.

권한과 알림은 권한, 설정, 저장소, 알림을 참고하세요.