linetta를 MCP로 외부 에이전트에 연결하기
linetta는 그동안 AI를 앱 안에서만 썼다. 그런데 자기 API 키로 붙이는 내장 AI는 소설 쓰기와 상관없는 LLM 연동 코드를 앱이 떠안게 했다. 쓰는 사람은 이미 자기 에이전트를 갖고 있어서 앱에 API 키를 또 넣고 토큰을 또 결제하는 것도 중복이었고, 외부 에이전트가 앱 안의 컴패니언보다 강하기도 했다. 그래서 AI를 앱 안에 넣는 대신 외부 에이전트가 원고를 다룰 수 있게 하기로 하고, 원고를 로컬 MCP 서버로 열었다. linetta만 줄 수 있는 것은 원고에서 골라 낸 맥락, 곧 스토리 브리프라고 봤다.
연결 방법
설정의 “외부 에이전트 연결 (MCP)“에서 동의 체크박스를 켠 뒤, Claude Code는 claude mcp add 한 줄로 HTTP에 연결하고 Claude Desktop은 claude_desktop_config.json에 설정 조각을 넣는다. Claude Desktop은 로컬 HTTP MCP 서버에 직접 붙지 못해서 앱에 stdio 브리지를 넣었다. App Store 빌드에는 이 브리지가 없다.
써 보면서 찾은 버그
리뷰보다 실제로 돌려 보면서 찾은 버그가 많았다.
- 앱을 다시 켤 때마다 MCP가 꺼져 있어서 설정이 저장되지 않는다는 걸 알았다.
- 실제 원고로 서버를 돌려 보니 빈 장면을 줄바꿈 하나로 돌려줬다.
- 엔진이 하나 더 뜨면 연결 정보를 담은 discovery 파일을 지웠다.
- Linux CI에서는 secret store가 없어 MCP가 켜지지 않았다.
- 개발하는 Windows에서는 Tauri 리소스 설정이 통째로 덮어써져서, 브리지가 번들에 들어가지 않을 뻔했다.
내장 AI
MCP로 실제로 써 보기 전에 지우면 사용자 손에 AI 없는 앱만 남아서 내장 AI는 지우지 않고 기본 경로에서만 뺐다. 처음 쓰는 사람에게는 설정의 “내장 AI 컴패니언 (레거시)” 블록이 접혀 보이고, 컴패니언 설정에서도 MCP 안내가 맨 위에 온다.
이번 작업에서 가장 까다로웠던 건 새로 온 사람과 이미 컴패니언을 쓰던 사람을 구분하는 일이었다. 기본 설정이 프로바이더 값을 채워 넣어서 설정만 봐서는 둘을 가를 수 없었다. 그래서 블록을 숨기지 않고 접어 두는 쪽을 택했다.
모델 없이 쓰는 장면 요약
모델이 없으면 요약기가 아무것도 쓰지 않았다. 장면 요약은 MCP 스토리 브리프, 이웃 장면 맥락, 개요 화면에 들어가서 요약이 비면 에이전트가 필요한 맥락을 잃었고, 오류 카드도 계속 켜져 있었다. 그래서 모델 없이도 요약 자리를 채우게 했다. 짧은 장면은 본문을 그대로 쓰고, 긴 장면은 도입부를 문장 경계에서 자르고, 부와 장은 아래 요약을 모은다. 진짜 요약은 아니지만 모델 없는 집필 도구가 만들 수 있는 정직한 결과이고 빈 브리프보다는 낫다고 봤다. 에이전트가 요약을 쓰면 그것으로 바뀐다.
App Store에서 받거나 brew install --cask devlikebear/tap/linetta로 설치한다.