NAVER WORKS CLI + MCP 서버 개발기 (2) — MCP 서버 만들고 awesome-mcp-servers 등록하기

2026. 3. 20. 23:30·개발기
User: 오늘 일정 알려줘

Claude → nworks_calendar_list
  → 3건: 스탠드업(10:00), 점심미팅(12:00), 코드리뷰(15:00)

Claude Desktop에서 말하면 NAVER WORKS 캘린더를 알아서 조회한다.

User: 팀 채널에 배포 완료 메시지 보내줘

Claude → nworks_message_send
  → 메시지가 전송되었습니다

메시지도 보낸다. 이걸 가능하게 하는 게 MCP(Model Context Protocol)다.

demo

이전 글에서 NAVER WORKS CLI를 만들었다. 터미널에서 잘 돌아갔다. 근데 이걸 AI 에이전트한테도 쓰게 해주고 싶었다. "오늘 일정 알려줘"라고 말하면 알아서 API를 호출하는 그런 거.

이 글은 CLI를 MCP 서버로 확장하고, awesome-mcp-servers에 등록하고, Glama에서 AAA 점수를 받기까지의 과정이다. MCP 서버를 만들고 생태계에 올리려는 사람한테 도움이 되면 좋겠다.


MCP 서버 구조: stdio transport

MCP 서버는 표준 입출력(stdio)으로 통신한다. AI 에이전트가 stdin으로 JSON-RPC 메시지를 보내면, 서버가 stdout으로 응답하는 구조다.

@modelcontextprotocol/sdk를 쓰면 이 프로토콜을 직접 구현할 필요 없다.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "nworks", version: "1.1.1" });

server.tool("nworks_calendar_list", { /* params */ }, async (params) => {
  // API 호출 후 결과 반환
  return { content: [{ type: "text", text: JSON.stringify(events) }] };
});

const transport = new StdioServerTransport();
await server.connect(transport);

tool을 등록하고, 파라미터 스키마를 정의하고, 핸들러를 달면 된다. 에이전트가 tool 목록을 조회해서 상황에 맞는 걸 골라 호출한다.

사용자 설정은 이게 끝이다.

{
  "mcpServers": {
    "nworks": {
      "command": "nworks",
      "args": ["mcp"]
    }
  }
}

tool description이 곧 UX다

MCP 서버에서 가장 중요한 건 코드가 아니라 tool의 description이다.

AI 에이전트는 tool의 이름과 description을 읽고 어떤 tool을 호출할지 결정한다. description이 부실하면 에이전트가 잘못된 tool을 고르거나, 아예 안 쓴다.

나쁜 예:

name: "nworks_calendar_list"
description: "List events"

이러면 에이전트가 "오늘 일정 알려줘"라는 요청을 받았을 때 이 tool을 써야 할지 확신을 못 한다.

좋은 예:

name: "nworks_calendar_list"
description: "List calendar events for the current user.
Returns event title, start/end time, location, and description.
Use 'from' and 'until' params to filter by date range.
If not specified, returns today's events."

파라미터 하나하나에도 description을 달았다. from이 뭔지, 포맷이 뭔지, 기본값이 뭔지.

nworks는 26개 tool을 제공한다. 각 tool의 description을 다듬는 데 코드 작성보다 시간이 더 걸렸다. 하지만 이게 실제 에이전트가 "잘 쓰느냐 못 쓰느냐"를 결정한다.


AI 에이전트가 직접 로그인하게 만들기

MCP 서버의 인증 문제를 고민했다.

첫 번째는 UX 문제다. CLI에서는 사용자가 nworks login --user를 먼저 실행해야 한다. 근데 MCP에서는 AI 에이전트가 동작하는 거다. 에이전트한테 "먼저 터미널 열어서 로그인하세요"라고 하면 UX가 깨진다.

두 번째는 보안 문제다. MCP로 동작할 때 인증 정보를 어디까지 AI한테 직접 넘길지, 사용자가 직접 설정하게 할지. UX와 상충될 수밖에 없다.

이걸 고려해서 두 가지 setup tool을 만들었다.

nworks_setup → Client ID 등 기본 설정
nworks_login_user → 브라우저를 열어서 User OAuth 로그인

에이전트가 이 순서대로 호출하면 사용자는 브라우저에서 한 번 로그인하는 것만으로 전체 기능을 쓸 수 있다.

보안 쪽은 이렇게 잡았다. Client Secret은 nworks_setup 파라미터로 받지 않는다. MCP tool 파라미터는 Glama 같은 클라우드 환경에서 네트워크를 타기 때문에, 민감 정보가 로그에 남거나 중간에 노출될 수 있다. Client Secret은 MCP 설정의 env 필드나 시스템 환경변수로만 설정하게 했다. Private Key도 마찬가지로 파일 경로를 환경변수로 받는다.

{
  "mcpServers": {
    "nworks": {
      "command": "nworks",
      "args": ["mcp"],
      "env": {
        "NWORKS_CLIENT_SECRET": "<Client Secret>",
        "NWORKS_PRIVATE_KEY_PATH": "<Private Key path>"
      }
    }
  }
}

비민감 정보(Client ID 등)는 에이전트가 nworks_setup으로 설정하고, 민감 정보(Secret, Key)는 사용자가 설정 파일에 미리 넣어두는 구조다. MCP 서버에서 인증을 설계할 때 "이 파라미터가 어디를 경유하는지"를 항상 생각해야 한다.

진단 도구도 만들었다. nworks_doctor는 인증 상태, 토큰 유효성, API 연결을 한 번에 확인한다. 에이전트가 "연결이 안 된다"고 판단하면 doctor를 먼저 호출해서 뭐가 문제인지 파악한다.


에러 메시지도 에이전트가 읽는다

CLI에서는 에러가 나면 사람이 읽고 판단한다. MCP에서는 에러를 에이전트가 읽는다.

영어 에러 코드만 던지면 에이전트가 사용자한테 그대로 전달한다. "FORBIDDEN" 같은 걸 사용자한테 보여주면 안 된다.

nworks는 한국어 에러 메시지를 같이 넣었다.

❌ scope 권한이 부족합니다.
필요한 scope: calendar.read
현재 scope에 포함되지 않은 것 같습니다.
`nworks logout` 후 다시 로그인해주세요.

에이전트가 이걸 읽고 사용자한테 "캘린더 권한이 없어서 로그아웃 후 다시 로그인해야 합니다"라고 안내한다. 에러 메시지가 곧 에이전트의 대화 품질이 된다.


Glama 빌드: 3번 실패하고 통과한 과정

awesome-mcp-servers에 등록하려면 Glama(glama.ai)에 등록 후 빌드 및 품질 테스트를 통과해야 한다. 과거엔 모르겠지만 현재는 필수로 품질 평가를 AAA를 받아야한다. Glama는 GitHub repo를 Docker로 빌드해서 보안, 라이선스, 품질을 평가한다.

빌드 테스트는 이 페이지에서 받을 수 있다.

1차 실패: zod 의존성 누락

✘ [ERROR] Could not resolve "zod"
    src/mcp/tools.ts:2:18:
      2 │ import { z } from "zod";

zod를 코드에서 직접 import하는데 package.json의 dependencies에 안 넣어둔 거였다. 로컬에서는 @modelcontextprotocol/sdk가 zod를 의존성으로 깔아놓으니까 잘 돌아갔다. 하지만 Glama의 클린 Docker 환경에서는 명시적 dependency만 설치한다.

pnpm add zod

한 줄로 해결. 근데 push해도 Glama에 반영이 안 됐다. Glama는 하루에 한 번 GitHub repo를 동기화한다. push 직후에 Deploy하면 옛날 코드로 빌드한다. admin에서 "Sync Server"를 눌러서 수동 동기화해야 한다.

2차 실패: Node.js 버전

Error: yargs parser supports a minimum Node.js version of 20.

Glama가 사용하는 mcp-proxy가 Node 20 이상을 요구하는데, 설정이 Node 18로 돼있었다. Glama admin에서 Node version을 20으로 바꿨다.

빌드 테스트를 하는 Dockerfile 페이지 밑으로 가면 빌드 설정하는 부분이 있다. 이 부분을 잘 확인해야한다.

3차 실패: 진입점

could not start the proxy McpError: MCP error -32000: Connection closed

Glama가 node dist/index.js로 실행했는데, 이건 CLI 진입점이다. MCP 서버 진입점은 dist/mcp.js다. 이전 글에서 진입점을 두 개로 분리해둔 게 여기서 중요해졌다. CMD arguments를 dist/mcp.js로 수정했다.

세 번의 실패 끝에 빌드 테스트가 통과됐다.

빌드 테스트가 통과 되면 조건에 따라 캡쳐의 우측처럼 품질을 AAA를 받을 수 있다.


awesome-mcp-servers 등록하기

awesome-mcp-servers(github.com/punkpeye/awesome-mcp-servers)는 MCP 서버의 디렉토리다. GitHub star가 7만 개가 넘는다. 여기에 등록되면 MCP 사용자들한테 노출된다.

등록 조건은 이렇다:

  • Glama에 서버가 등록되어 있어야 한다
  • Glama에서 빌드 테스트를 통과해야 한다
  • Release가 있어야 한다
  • PR에 Glama score badge를 포함해야 한다

fork → README.md에 nworks 항목 추가 → PR. Communication 카테고리의 알파벳 순서에 맞춰서 넣었다.

메인테이너(punkpeye)가 "just needs to pass the tests"라고 코멘트를 남겼고, Glama AAA가 확인되자 머지됐다.

awesome-mcp-servers 외에도 등록할 곳이 있다.

플랫폼 특징
Glama (glama.ai/mcp/servers) 자동 분석, 점수, Install 버튼
mcp.so 커뮤니티 디렉토리
mcpservers.org 디렉토리

Glama는 GitHub repo 제출하면 자동으로 등록되고, 나머지는 URL을 제출하면 된다.


README 다국어 대응: LINE WORKS 브랜딩

NAVER WORKS는 한국에서 쓰는 이름이다. 일본과 동남아에서는 LINE WORKS라는 이름으로 서비스된다. 같은 제품, 같은 API(worksmobile.com 도메인), 다른 브랜드명이다.

awesome-mcp-servers에 올라가면 글로벌 개발자가 본다. "NAVER WORKS"라고만 쓰면 일본 개발자는 자기가 쓰는 서비스인 줄 모른다.

README를 세 개 만들었다.

파일 브랜드 순서 Developer Console
README.md (영어) LINE WORKS (NAVER WORKS) dev.worksmobile.com/en/
README.ko.md (한국어) NAVER WORKS (LINE WORKS) dev.worksmobile.com
README.ja.md (일본어) LINE WORKS (NAVER WORKS) dev.worksmobile.com/jp/

상단에 언어 전환 링크를 넣었다. 한국에서는 NAVER WORKS를 앞에, 해외에서는 LINE WORKS를 앞에. 같은 API를 쓰니까 코드 수정은 없다. README만 바꾸면 된다.


지금 다시 한다면

가능하다면 해외 지원을 처음부터 고려해서 다국어 README도 처음부터 만들었으면 좋았을 것 같다. 중간에 리브랜딩을 하니까 불필요한 패치를 하거나 홍보를 다시하거나 하는 번거로움이 있었다.

MCP tool description은 처음부터 영어로, 충분히 길게 쓸 걸. 에이전트가 읽는 건 코드가 아니라 description이다. 결국 MCP tool의 품질은 이 description에서 나온다. 실제로 테스트 해보면 이 것의 상세함에 따라 UX 품질이 차이가 난다.


배운 것들

  • MCP tool의 핵심은 description이다. 에이전트는 이름과 설명만 보고 어떤 tool을 쓸지 결정한다.
  • Glama 빌드는 클린 환경이다. 로컬에서 되는 거랑 다르다. dependencies를 명시적으로 선언해야 한다.
  • Glama는 하루 1회 GitHub 동기화다. push 직후 Deploy하면 옛날 코드로 빌드한다.
  • awesome-mcp-servers 등록에는 Glama 점수가 필수다.
  • NAVER WORKS = LINE WORKS. 같은 API, 다른 이름. 글로벌 대응하려면 README에 둘 다 써야 한다.
  • 에러 메시지도 에이전트가 읽는다. 한국어 안내 메시지를 넣으면 에이전트의 대화 품질이 올라간다.

이전 글: NAVER WORKS CLI를 만들고 npm에 배포하기 — 없길래 직접 만들었다


GitHub: https://github.com/yjcho9317/nworks
npm: https://www.npmjs.com/package/nworks
Glama: https://glama.ai/mcp/servers/yjcho9317/nworks
awesome-mcp-servers: https://github.com/punkpeye/awesome-mcp-servers

'개발기' 카테고리의 다른 글

MCP AI 에이전트 보안 프록시 개발기 (4) — YAML 정책 엔진과 SARIF 감사 로깅  (0) 2026.04.14
MCP AI 에이전트 보안 프록시 개발기 (3) — 유니코드 호모글리프와 ReDoS로 보안 감사하기  (0) 2026.04.14
MCP AI 에이전트 보안 프록시 개발기 (2) — regex로 프롬프트 인젝션 탐지하기  (1) 2026.04.14
MCP AI 에이전트 보안 프록시 개발기 (1) — MCP 서버 응답은 검증 없이 AI에 전달된다  (0) 2026.04.14
NAVER WORKS CLI + MCP 서버 개발기 (1) — CLI 만들고 npm 배포하기  (0) 2026.03.20
'개발기' 카테고리의 다른 글
  • MCP AI 에이전트 보안 프록시 개발기 (3) — 유니코드 호모글리프와 ReDoS로 보안 감사하기
  • MCP AI 에이전트 보안 프록시 개발기 (2) — regex로 프롬프트 인젝션 탐지하기
  • MCP AI 에이전트 보안 프록시 개발기 (1) — MCP 서버 응답은 검증 없이 AI에 전달된다
  • NAVER WORKS CLI + MCP 서버 개발기 (1) — CLI 만들고 npm 배포하기
João Jin
João Jin
모바일 · 보안 · AI 기록
  • João Jin
    João Jin - 모바일 · 보안 · AI
    João Jin
  • 전체
    오늘
    어제
    • 분류 전체보기 (30)
      • 프로젝트 (3)
      • 개발기 (8)
      • 모바일 (8)
      • 보안 (2)
      • AI (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
    • X
  • 공지사항

  • 인기 글

  • 태그

    Docker Compose
    머신러닝
    MLOps
    MCP 보안
    온디바이스AI
    AI
    model context protocol
    LLM 보안
    Android
    안드로이드 NDK
    Docker
    JNI
    LINE WORKS
    ndk
    Native
    AI 에이전트 보안
    FastAPI
    MLFlow
    mcp-fence
    MCP
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
João Jin
NAVER WORKS CLI + MCP 서버 개발기 (2) — MCP 서버 만들고 awesome-mcp-servers 등록하기
상단으로

티스토리툴바