{"_id":"@channel.io/tolgee-mcp","_rev":"3-84e85e52ddc517126a41a734e1ecb56f","name":"@channel.io/tolgee-mcp","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@channel.io/tolgee-mcp","version":"1.0.0","keywords":["tolgee","mcp","i18n","channel"],"author":{"name":"Channel Corp."},"license":"UNLICENSED","_id":"@channel.io/tolgee-mcp@1.0.0","maintainers":[{"name":"zoyi","email":"eng@channel.io"},{"name":"quino0627","email":"dongwook627@gmail.com"},{"name":"sungik.dev","email":"sungik.dev@gmail.com"}],"homepage":"https://github.com/channel-io/ch-mcp-tools#readme","bugs":{"url":"https://github.com/channel-io/ch-mcp-tools/issues"},"bin":{"tolgee-mcp":"dist/index.js"},"dist":{"shasum":"5a880c13e4392f627ea983761d0a52c28b5dbea1","tarball":"https://registry.npmjs.org/@channel.io/tolgee-mcp/-/tolgee-mcp-1.0.0.tgz","fileCount":5,"integrity":"sha512-7sEFcNMBCfgqMo+IGNpiNzHnNXjnH3vmJ3CeQ+HJsvjVTmh8vIafBNHB0TIXUAFSe7Rqt/QOG5mcDMq4wkwwew==","signatures":[{"sig":"MEUCICMF5+j3QEee+PTyaKWMay28gsA/WBmUuL6d9hbVOD2IAiEA6UqxX++/JtsQMHJljdcs6toiZfBEjNrxwHHV2nexf9I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44752},"type":"module","engines":{"node":">=14.0.0"},"gitHead":"666701ec90cbe7f43a16b6b07e8f56e778d3664e","scripts":{"lint":"eslint . --ext .js,.jsx,.ts,.tsx","build":"tsup && chmod +x dist/index.js","format":"prettier --write .","lint:fix":"eslint . --ext .js,.jsx,.ts,.tsx --fix","format:check":"prettier --check .","prepublishOnly":"pnpm build"},"_npmUser":{"name":"zoyi","email":"eng@channel.io"},"repository":{"url":"git+https://github.com/channel-io/ch-mcp-tools.git","type":"git"},"_npmVersion":"9.6.7","description":"Model Context Protocol server for Tolgee integration","directories":{},"_nodeVersion":"18.17.1","dependencies":{"zod":"^3.24.2","axios":"1.6.7","@modelcontextprotocol/sdk":"^1.6.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"5.0.4","@types/node":"18.17.0"},"_npmOperationalInternal":{"tmp":"tmp/tolgee-mcp_1.0.0_1753420916728_0.8194269098026321","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@channel.io/tolgee-mcp","version":"1.0.1","keywords":["tolgee","mcp","i18n","channel"],"author":{"name":"Channel Corp."},"license":"UNLICENSED","_id":"@channel.io/tolgee-mcp@1.0.1","maintainers":[{"name":"zoyi","email":"eng@channel.io"},{"name":"quino0627","email":"dongwook627@gmail.com"},{"name":"sungik.dev","email":"sungik.dev@gmail.com"}],"homepage":"https://github.com/channel-io/ch-mcp-tools#readme","bugs":{"url":"https://github.com/channel-io/ch-mcp-tools/issues"},"bin":{"tolgee-mcp":"dist/index.js"},"dist":{"shasum":"369ca49f83eb8bc500dfbc2857c89286c59027ee","tarball":"https://registry.npmjs.org/@channel.io/tolgee-mcp/-/tolgee-mcp-1.0.1.tgz","fileCount":5,"integrity":"sha512-2GFTI5gRb+LThd6uyTGCtvbQQ5J6gWeodOVGuk6lHw9tpEhYRTRbXOLMJ0p+WA2Mv4TH6xJv56Igii7w9JbBDw==","signatures":[{"sig":"MEUCIQC2I3HuxxjL8aleaZyjxmcHT2wkQLslIdVPw7en80BoPAIgW4crxMJ4qCuOnP0gyp5iBqN80gnMrenGvS2kkcAMvi4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44842},"type":"module","engines":{"node":">=14.0.0"},"gitHead":"666701ec90cbe7f43a16b6b07e8f56e778d3664e","scripts":{"lint":"eslint . --ext .js,.jsx,.ts,.tsx","build":"tsup && chmod +x dist/index.js","format":"prettier --write .","lint:fix":"eslint . --ext .js,.jsx,.ts,.tsx --fix","format:check":"prettier --check .","prepublishOnly":"pnpm build"},"_npmUser":{"name":"zoyi","email":"eng@channel.io"},"repository":{"url":"git+https://github.com/channel-io/ch-mcp-tools.git","type":"git"},"_npmVersion":"9.6.7","description":"Model Context Protocol server for Tolgee integration","directories":{},"_nodeVersion":"18.17.1","dependencies":{"zod":"^3.24.2","axios":"1.6.7","@modelcontextprotocol/sdk":"^1.6.1"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"5.0.4","@types/node":"18.17.0"},"_npmOperationalInternal":{"tmp":"tmp/tolgee-mcp_1.0.1_1753423736512_0.44835570927529234","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-07-25T05:21:56.638Z","modified":"2026-01-26T12:56:59.084Z","1.0.0":"2025-07-25T05:21:56.935Z","1.0.1":"2025-07-25T06:08:56.700Z"},"bugs":{"url":"https://github.com/channel-io/ch-mcp-tools/issues"},"author":{"name":"Channel Corp."},"license":"UNLICENSED","homepage":"https://github.com/channel-io/ch-mcp-tools#readme","keywords":["tolgee","mcp","i18n","channel"],"repository":{"url":"git+https://github.com/channel-io/ch-mcp-tools.git","type":"git"},"description":"Model Context Protocol server for Tolgee integration","maintainers":[{"email":"polar@channel.io","name":"polarshin"},{"email":"eng@channel.io","name":"zoyi"},{"email":"dongwook627@gmail.com","name":"quino0627"},{"email":"sungik.dev@gmail.com","name":"sungik.dev"}],"readme":"# Tolgee MCP\n\nChannel 팀을 위한 Tolgee MCP 도구입니다. 이 도구는 Cursor에서 번역 키 생성 및 관리를 도와주는 AI 도구입니다.\n\n## Cursor MCP 설정\n\nCursor에서 MCP로 사용하려면 `.cursor/mcp.json` 파일에 다음과 같이 설정합니다:\n\n```json\n{\n  \"mcpServers\": {\n    \"tolgee-mcp\": {\n      \"command\": \"npx -y @channel.io/tolgee-mcp\",\n      \"env\": {\n        \"TOLGEE_TOKEN\": \"your-tolgee-token\",\n        \"PROJECT_ID\": \"your-project-id\",\n        \"PLATFORMS\": [\"web\", \"ios\", \"android\"]\n      }\n    }\n  }\n}\n```\n\n### 환경 변수 설명\n\n- **TOLGEE_TOKEN**: Tolgee API에 접근하기 위한 개인 액세스 토큰입니다. Tolgee 계정 설정에서 발급받을 수 있습니다.\n- **PROJECT_ID**: 작업할 Tolgee 프로젝트의 고유 식별자입니다. Tolgee 프로젝트 URL이나 설정에서 확인할 수 있습니다.\n- **PLATFORMS**: 번역 키가 지원할 플랫폼 목록입니다.\n\n## 주요 기능\n\n이 MCP 서버는 두 가지 주요 기능을 제공합니다:\n\n1. **번역 키 조회**: 프로젝트에 이미 존재하는 번역 키를 검색합니다\n2. **번역 키 생성**: 새로운 번역 키를 생성하고 초기 번역값을 설정합니다\n\n## 함께 사용하면 좋은 Cursor Rule 예시\n\n아래의 프롬프트를 사용하면 효과적으로 번역 키 추가 작업을 진행할 수 있습니다:\n\n> 이 프롬프트는 ch-desk-web에서 사용하는 프롬프트입니다. 다른 프로젝트에서 사용하려면 프롬프트를 일부 수정해야 할 수 있습니다.\n\n````\n당신은 cursor 내에 통합된 LLM 에이전트입니다. 하드코딩된 한글 문자열에 대한 번역 키 추가 작업을 자동화하기 위해 아래 가이드라인을 준수하세요.\n\n\n## 목적\n- 코드베이스에서 하드코딩된 한글 문자열을 찾아 대응하는 번역 키를 생성 및 적용합니다.\n- 기본적으로 <업무 파이프라인>을 따라 작업을 진행합니다.\n\n\n## [!CRITICAL] 제약 조건\n- <업무 파이프라인>의 단계를 반드시 지키도록\n- 만약 <업무 파이프라인>의 특정 단계에서 작업 수행을 실패하면 그 즉시 실패 원인과 함께 응답 종료\n\n\n## [!CRITICAL] 필수 참고 사항\n\n### 명령어 정의\n- '/completion'이란 현재 챗을 완료하고 사용자에게 추가 프롬프트를 요청할 때 사용하는 명령어입니다.\n\n### MCP tool 주의 사항\n- tolgee_create_keys를 통한 번역키 생성은 비가역적으로 진행되며, 이미 존재하는 키를 삭제하거나 수정할 수 없음\n- tolgee_create_keys 전에 tolgee_get_keys를 통한 중복 확인 단계를 수행하지 않으면 중복 키 생성 시 오류가 발생할 수 있음\n\n### 번역 키 네이밍 규칙\n- snake_case.snake_case.snake_case 네이밍 사용\n- 계층 구조 준수: 코드베이스의 구조를 참조하여, 위계와 맥락에 따라 번역키에 적절히 이름을 붙이기\n\n\n## 업무 파이프라인\n\n### 1. 작업 맥락 파악\n- 사용자가 참조로 제공한 \"작업 범위\" 내에서 하드코딩된 한글 문자열 검색 (주석 처리된 문자열 제외)\n- 번역이 필요한 페이지/컴포넌트의 구조와 문맥 파악\n\n### 2. 번역 키:값 준비\n- <번역 키 네이밍 규칙>에 따라 `{ \"key\": \"value\" }` 형식으로 번역 키:값 목록 준비 (`value`는 원본 한글)\n- [!IMPORTANT] 특수 요소 처리:\n  * 템플릿 리터럴(`${}`) → `import { sprintf } from 'sprintf-js'`에서 parse할 수 있는 형식으로 변환 (e.g. `\"${name}님 안녕하세요\"` → `\"%s님 안녕하세요\"`)\n  * HTML 태그 → 번역 값에 직접 innerHTML로 처리 (e.g. `제 이름은 <b>라온</b>입니다.`)\n  * 줄바꿈 등 특수 문자 → 적절히 이스케이프 시퀀스 활용\n\n### 3. 번역 값 중복 확인\n- 동일한 번역 값(`value`)을 가진 키가 있는지 확인\n  - [!IMPORTANT] 리포지토리 루트에 있는 `l10n/ko.json` 파일에서 batch로 grep 하여 추출\n- 중복이 없다면 최종 번역 키:값 목록 준비 후 다음 단계로 넘어감\n- 중복 발견 시 옵션 제안:\n  * 기존 키 재사용 (도메인 로직이 아니라 일반적인 번역 키인 경우)\n  * 새 키 생성 (도메인 의존적인 번역 키인 경우)\n- [!CRITICAL] 옵션에 대한 제안은 하되, 최종 결정은 사용자에게 물어볼 것 (/completion)\n  - 가독성 있게 코드블록(json)으로 제안할 것\n  - 사용자의 답변을 바탕으로 최종 `{ \"key\": \"value\" }` 형식의 번역 키:값 목록 준비\n\n### 4. 번역 키 생성 전 품질 검증\n- \"작업 범위\" 내 놓친 번역 키가 있는지 확인\n- 이전 단계가 모두 정상적으로 수행되었는지 확인\n\n### 5. 번역 키 생성 및 통합\n- `tolgee_get_keys` 도구로 번역키 중복 확인\n  - [!CRITICAL] 중복 키가 있는 경우:\n    * 키에 version postfix를 붙여 중복 회피 (e.g. `meet.meet_banner.title` → `meet.meet_banner.title.v1`)\n    * 사용자에게 다시 최종 결정을 물어볼 것 (/completion)\n- `tolgee_create_keys` 도구로 키 생성\n  - [!CRITICAL] 사용자에게 번역 키 태그를 한번도 받지 못한 경우 사용자에게 직접 요청할 것 (/completion)\n- `yarn download-l10n` 스크립트 실행하여 번역 파일 갱신\n- 코드 적용:\n  * `import useTranslator from 'Hooks/useTranslator'` 훅을 사용한 번역 키 적용\n  * 기본적으로 translate 함수를 사용\n  * 템플릿 변수 처리해야하는 경우, 함수의 파라미터를 적절히 사용\n  * innerHTML 처리해야하는 경우, translate 대신 translateWithInnerHtml 함수를 사용\n\n\n## 번역 키:값 예시\n\n### 일반적인 번역 키:값\n```json\n{\n  \"channel_settings.manage_webhooks.webhook_list.empty\": \"Webhook이 없습니다. 새 Webhook을 만들어 주세요.\"\n  \"channel_settings.manage_webhooks.show_webhook.modal.title\": \"새 Webhook이 만들어졌습니다.\"\n  \"channel_settings.manage_webhooks.show_webhook.modal.ok\": \"확인\"\n  \"channel_settings.manage_webhooks.edit_webhook.modal.title\": \"Webhook 관리\"\n  \"channel_settings.manage_webhooks.delete_webhook.success\": \"Webhook이 삭제되었습니다.\"\n  \"channel_settings.plugin_setting.button_customize\": \"버튼 커스터마이징\"\n  \"channel_settings.plugin_setting.button_customize.reset\": \"초기화\"\n  \"channel_settings.integrations.messengers.line.apply_modal.locale\": \"언어\"\n  \"channel_settings.integrations.messengers.line.apply_modal.locale.description\": \"선택하신 언어에 따라 고객에게 부재중 메시지와 같은 자동 메시지가 전송됩니다.\"\n  \"channel_settings.integrations.messengers.line.apply_modal.channel_id\": \"라인 Channel ID\"\n  \"channel_settings.integrations.messengers.line.apply_modal.channel_id.placeholder\": \"라인 Channel ID 입력\"\n  \"channel_settings.integrations.messengers.line.apply_modal.channel_secret\": \"라인 Channel Secret\"\n  \"channel_settings.integrations.messengers.line.apply_modal.channel_secret.placeholder\": \"라인 Channel Secret 입력\"\n  \"channel_settings.integrations.messengers.line.apply_modal.access_token\": \"Access token\\n(long-lived)\"\n  \"channel_settings.integrations.messengers.line.apply_modal.access_token.placeholder\": \"Access token 입력\"\n  \"channel_settings.integrations.messengers.line.apply_modal.id\": \"Basic ID (또는 Premium ID)\"\n  \"channel_settings.integrations.messengers.line.apply_modal.id.placeholder\": \"Basic ID 또는 Premium ID를 입력\"\n  \"channel_settings.integrations.messengers.line.webhook_link_modal.description\": \"아래 링크를 복사하여 라인 Channel의 Messaging API settings - Webhook URL에 입력하고 Webhook을 활성화하면 연동이 완료됩니다.\"\n}\n```\n\n### with common prefix\n```json\n{\n  \"common.cancel\": \"취소\"\n  \"common.confirm\": \"확인\"\n  \"common.close\": \"닫기\"\n  \"common.delete\": \"삭제\"\n  \"common.save\": \"저장\"\n  \"common.copy\": \"복사\"\n  \"common.apply\": \"적용\"\n  \"common.me\": \"나\"\n  \"common.next\": \"다음\"\n  \"common.retry\": \"재시도\"\n  \"common.time\": \"시간\"\n  \"common.no_data\": \"표시할 내용이 없습니다.\"\n  \"common.not_empty\": \"비워둘 수 없습니다\"\n}\n```\n\n### with error prefix\n```json\n{\n  \"error.do_not_empty\": \"비워둘 수 없습니다.\"\n  \"error.max_length\": \"%s자까지 입력할 수 있습니다.\"\n  \"error.available_english_number\": \"영문, 숫자, -, _만 사용할 수 있습니다.\"\n  \"error.aspect_ratio\": \"가로:세로 비율이 %s이 아닌 경우 등록할 수 없습니다.\"\n  \"error.min_width\": \"가로 %spx 이하일 경우 등록할 수 없습니다.\"\n  \"error.max_file_size\": \"최대 %s까지 등록할 수 있습니다.\"\n  \"error.content_type\": \"%s만 등록할 수 있습니다.\"\n  \"error.require_version_update.title\": \"앗, 이전 버전의 앱을 사용 중이에요\"\n  \"error.unsupported_file_extension\": \"파일 형식을 다시 확인해주세요.\"\n  \"error.invalid_url\": \"잘못된 주소입니다.\"\n}\n```\n\n### with innerHTML & escape sequence\n```json\n{\n  \"log_message.create_chat\": \"<b>%(subject)s<\\/b>님이 <b>%(object)s<\\/b>(을)를 만들었습니다.\"\n  \"log_message.invite_chat\": \"<b>%(subject)s<\\/b>님이 <b>%(object)s<\\/b>을(를) 초대했습니다.\"\n  \"common.powered_by\": \"<b>채널톡<\\/b> 이용중\"\n  \"channel.invite_recommend_description\": \"현재 채널에 <b>%s명<\\/b>의 매니저가 있습니다. <b>매니저를 추가해도 추가 과금이 없으니<\\/b> 안심하고 매니저를 초대하여 대화해보세요.\"\n  \"campaign_editor.ui.operating_panel.activated_description\": \"언제, 어떻게 메시지를 전송할지 설정합니다. '운영' 설정을 끝으로 메시지가 전송됩니다.<br>\\n예) 서울 접속자 중 가입하고 2주 동안 구매가 없으면 <b><u>매주 월요일 아침 9시에<\\/u><\\/b> 전송\",\n  \"campaign_editor.ui.delay_panel.activated_description\": \"아래 '대기 시간' 만큼 기다렸다가 다시 대상 고객을 체크하고 '운영' 단계로 넘어갑니다.<br>\\n예) 서울 접속자 중 가입하고 <b><u>2주 동안<\\/u><\\/b> 구매가 없으면 매주 월요일 아침 9시에 전송\"\n}\n```\n\n### with template variable\n```json\n{\n  \"chat_action.manager_list.header\": \"%s명 참여\"\n  \"confirm_delete_member\": \"%s님을 채널에서 삭제하시겠습니까?\"\n  \"invitation.sns.message\": \"%s님이 '%s' 채널로 당신을 초대했습니다.\\n채널에 참여해 주시기 바랍니다.\"\n  \"settings.billing.order_histories.discount_tooltip\": \"%s%% 할인 쿠폰 적용됨\"\n  \"support_bot.max\": \"최대 %s개까지 추가할 수 있습니다.\"\n  \"bot.select.create_new_bot\": \"'%s' 새로 만들기...\"\n  \"teamchats.participants_list.title\": \"참여자 ∙ %s\"\n  \"expressive_query.values.format.plural\": \"%s 또는 %s개\"\n  \"common.append_new_value\": \"'%s' 입력\"\n  \"marketing.otm.success_modal.title_content\": \"%s명에게 메시지를 성공적으로 전달했습니다!👏\"\n  \"user_profile_page.menu.copy_link.tooltip\": \"유저 링크 복사\\n%s\"\n  \"log_message.invite_chat\": \"<b>%(subject)s<\\/b>님이 <b>%(object)s<\\/b>을(를) 초대했습니다.\"\n  \"log_message.leave_chat\": \"<b>%(subject)s<\\/b>님이 대화를 떠났습니다.\"\n  \"log_message.change_chat_name\": \"<b>%(subject)s<\\/b>님이 그룹이름을 <b>%(object)s<\\/b>(으)로 변경하였습니다.\"\n  \"notification.upload_file.description\": \"%(name)s 님이 파일을 업로드했습니다.\"\n  \"log_message.remove\": \"<b>%(subject)s<\\/b>님이 상담을 삭제하였습니다.\"\n  \"log_message.close\": \"<b>%(subject)s<\\/b>님이 상담을 종료하였습니다.\"\n  \"log_message.unhold\": \"<b>%(subject)s<\\/b>님이 상담을 보류 해제 하였습니다.\"\n}\n```\n\n````\n","readmeFilename":"README.md"}