M MCP모아
튜토리얼

지오코딩 MCP 서버 구축 — 카카오·네이버 주소 좌표 변환 자동화

카카오·네이버 지오코딩 API를 MCP 서버로 연동해 Claude에서 주소를 좌표로 자동 변환하는 방법을 단계별로 안내합니다. 역지오코딩까지 완전 해결.

카카오·네이버 지오코딩 API를 MCP 서버로 연결해 Claude에서 주소를 위도·경도로 변환하는 데이터 흐름 표지 이미지

카카오·네이버 지오코딩 API를 MCP 서버로 구성하면, Claude에서 자연어 한 줄로 주소를 위도·경도로 변환하거나 좌표를 다시 주소로 역변환할 수 있습니다. 별도 스크립트나 외부 도구 없이 대화 흐름 안에서 바로 좌표를 얻을 수 있어, 데이터 전처리·현장 조사·배달 서비스 등 위치 데이터를 다루는 모든 워크플로에서 유용합니다. 이 글에서는 Node.js 기반 MCP 서버를 직접 작성하고 Claude Desktop에 등록하는 전 과정을 단계별로 설명합니다.

지오코딩 MCP가 왜 필요한가

지오코딩은 “서울시 강남구 테헤란로 152”처럼 사람이 읽는 주소를 위도(latitude)·경도(longitude) 숫자 쌍으로 바꾸는 기술입니다. 지도 표시, 반경 검색, 배달 경로 계산 등 위치 기반 서비스의 거의 모든 기능이 이 첫 단계를 필요로 합니다.

Claude 같은 AI 어시스턴트는 기본적으로 외부 API를 직접 호출하지 못합니다. 그러나 **Model Context Protocol(MCP)**을 이용하면 외부 API를 Claude의 “도구(tool)“로 노출할 수 있습니다. 한국에서 가장 널리 쓰이는 카카오 로컬 API와 네이버 지오코딩 API를 MCP 서버로 감싸면 다음과 같은 일이 가능해집니다.

사용자 → Claude Desktop
           ↓  (MCP 도구 호출)
       MCP 서버(Node.js)
           ↓  (HTTP REST)
   카카오 로컬 API  /  네이버 Geocoding API

       위도·경도 반환

       Claude가 결과 요약·가공

이 구조를 갖추면 Claude에게 “고객 주소 목록에서 좌표를 뽑아 표로 만들어줘”라고 말하는 것만으로 수백 건의 주소를 일괄 변환할 수 있습니다.

사전 준비물

항목내용
Node.js18 버전 이상 (LTS 권장)
Claude Desktop최신 버전 (MCP 지원 포함)
카카오 REST API 키Kakao Developers에서 앱 등록 후 발급
네이버 Client ID / SecretNaver Cloud Platform에서 Maps - Geocoding 활성화 후 발급

단계별 구축 방법

1단계: 카카오 REST API 키 발급

  1. Kakao Developers에 로그인합니다.
  2. 내 애플리케이션 → 애플리케이션 추가하기를 선택합니다.
  3. 앱 이름과 회사명을 입력하고 저장합니다.
  4. 생성된 앱의 앱 키 탭에서 REST API 키를 복사합니다.
  5. 플랫폼 → Web 에서 허용할 도메인(개발 중이라면 http://localhost)을 등록합니다.

카카오 로컬 API의 지오코딩 엔드포인트는 아래와 같습니다.

GET https://dapi.kakao.com/v2/local/search/address.json?query=주소
Authorization: KakaoAK {REST_API_KEY}

2단계: 네이버 클라우드 플랫폼 API 키 발급

  1. Naver Cloud Platform 콘솔에 로그인합니다.
  2. AI·NAVER API → Maps → Geocoding을 활성화합니다.
  3. Application 탭에서 새 앱을 생성하고 Client IDClient Secret을 복사합니다.

네이버 지오코딩 엔드포인트는 다음과 같습니다.

GET https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=주소
X-NCP-APIGW-API-KEY-ID: {CLIENT_ID}
X-NCP-APIGW-API-KEY: {CLIENT_SECRET}

3단계: MCP 서버 프로젝트 초기화

작업 디렉터리를 만들고 필요한 패키지를 설치합니다.

mkdir geocoding-mcp-server
cd geocoding-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk node-fetch

package.json"type": "module"을 추가해 ESM을 활성화합니다.

{
  "name": "geocoding-mcp-server",
  "version": "1.0.0",
  "type": "module",
  "main": "index.js"
}

4단계: 지오코딩 도구 함수 구현

프로젝트 루트에 index.js 파일을 만들고 아래 코드를 작성합니다.

# 파일 생성
touch index.js

index.js 전체 내용은 다음과 같습니다.

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import fetch from "node-fetch";

const KAKAO_API_KEY = process.env.KAKAO_REST_API_KEY;
const NAVER_CLIENT_ID = process.env.NAVER_CLIENT_ID;
const NAVER_CLIENT_SECRET = process.env.NAVER_CLIENT_SECRET;

// 카카오 지오코딩
async function kakaoGeocode(address) {
  const url = `https://dapi.kakao.com/v2/local/search/address.json?query=${encodeURIComponent(address)}`;
  const res = await fetch(url, {
    headers: { Authorization: `KakaoAK ${KAKAO_API_KEY}` },
  });
  const data = await res.json();
  if (!data.documents || data.documents.length === 0) {
    return null;
  }
  const doc = data.documents[0];
  return { lat: parseFloat(doc.y), lng: parseFloat(doc.x), source: "kakao" };
}

// 네이버 지오코딩
async function naverGeocode(address) {
  const url = `https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query=${encodeURIComponent(address)}`;
  const res = await fetch(url, {
    headers: {
      "X-NCP-APIGW-API-KEY-ID": NAVER_CLIENT_ID,
      "X-NCP-APIGW-API-KEY": NAVER_CLIENT_SECRET,
    },
  });
  const data = await res.json();
  if (!data.addresses || data.addresses.length === 0) {
    return null;
  }
  const addr = data.addresses[0];
  return { lat: parseFloat(addr.y), lng: parseFloat(addr.x), source: "naver" };
}

// 카카오 역지오코딩
async function kakaoReverseGeocode(lat, lng) {
  const url = `https://dapi.kakao.com/v2/local/geo/coord2address.json?x=${lng}&y=${lat}`;
  const res = await fetch(url, {
    headers: { Authorization: `KakaoAK ${KAKAO_API_KEY}` },
  });
  const data = await res.json();
  if (!data.documents || data.documents.length === 0) {
    return null;
  }
  const doc = data.documents[0];
  return doc.address?.address_name || null;
}

const server = new Server(
  { name: "geocoding-mcp-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "geocode",
      description: "한국 주소를 위도·경도로 변환합니다. 카카오 API를 우선 사용하고 결과가 없으면 네이버 API로 폴백합니다.",
      inputSchema: {
        type: "object",
        properties: {
          address: { type: "string", description: "변환할 한국 주소 (도로명 또는 지번)" },
        },
        required: ["address"],
      },
    },
    {
      name: "reverseGeocode",
      description: "위도·경도를 한국 주소로 변환합니다(역지오코딩). 카카오 API를 사용합니다.",
      inputSchema: {
        type: "object",
        properties: {
          lat: { type: "number", description: "위도(latitude)" },
          lng: { type: "number", description: "경도(longitude)" },
        },
        required: ["lat", "lng"],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "geocode") {
    let result = await kakaoGeocode(args.address);
    if (!result) result = await naverGeocode(args.address);
    if (!result) {
      return { content: [{ type: "text", text: "주소를 찾을 수 없습니다. 주소를 다시 확인해 주세요." }] };
    }
    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({ address: args.address, ...result }, null, 2),
        },
      ],
    };
  }

  if (name === "reverseGeocode") {
    const address = await kakaoReverseGeocode(args.lat, args.lng);
    if (!address) {
      return { content: [{ type: "text", text: "해당 좌표에서 주소를 찾을 수 없습니다." }] };
    }
    return {
      content: [{ type: "text", text: JSON.stringify({ lat: args.lat, lng: args.lng, address }, null, 2) }],
    };
  }

  throw new Error(`알 수 없는 도구: ${name}`);
});

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

5단계: Claude Desktop 설정 파일에 서버 등록

Claude Desktop의 설정 파일을 열어 MCP 서버를 등록합니다.

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

파일에 아래 내용을 추가합니다. 이미 다른 서버가 있다면 mcpServers 객체 안에 병합하면 됩니다.

{
  "mcpServers": {
    "geocoding": {
      "command": "node",
      "args": ["/절대경로/geocoding-mcp-server/index.js"],
      "env": {
        "KAKAO_REST_API_KEY": "여기에_카카오_REST_API_키",
        "NAVER_CLIENT_ID": "여기에_네이버_클라이언트_ID",
        "NAVER_CLIENT_SECRET": "여기에_네이버_클라이언트_시크릿"
      }
    }
  }
}

경로는 반드시 절대 경로로 지정해야 합니다. 예를 들어 macOS라면 /Users/홈폴더이름/geocoding-mcp-server/index.js 형태입니다.

6단계: Claude에서 주소 변환 테스트

Claude Desktop을 완전히 종료한 뒤 다시 실행합니다. 채팅창에서 아래와 같이 입력해 도구가 정상 작동하는지 확인합니다.

"서울시 강남구 테헤란로 152의 좌표를 알려줘"
"위도 37.566826, 경도 126.978656은 어떤 주소야?"

Claude가 geocoding 도구를 자동으로 호출해 결과를 반환하면 연동 성공입니다.

흔한 오류와 해결 방법

오류 증상원인해결 방법
Claude에 도구가 나타나지 않음설정 파일 JSON 문법 오류 또는 경로 오타claude_desktop_config.json을 JSON 검증기로 확인, 절대 경로 재확인
401 UnauthorizedAPI 키가 잘못되었거나 env에 누락설정 파일의 env 블록에 키가 올바르게 입력됐는지 확인
주소 변환 결과 없음입력 주소 형식 문제도로명 주소 전체를 입력, 특수문자 제거 후 재시도
node-fetch 오류Node.js 버전 또는 ESM 설정 문제package.json"type": "module" 확인, Node.js 18+ 사용 확인
네이버 API 401플랫폼에서 Geocoding API 미활성화Naver Cloud Platform 콘솔에서 해당 API 서비스 활성화 여부 확인

활용 시나리오

지오코딩 MCP를 구성하면 다음과 같은 실무 작업을 Claude 대화 안에서 바로 처리할 수 있습니다.

  • 주소 목록 일괄 변환: 엑셀에서 복사한 수백 개 주소를 Claude에 붙여넣으면 위도·경도 테이블로 변환
  • 배달·물류 데이터 전처리: 고객 주소 데이터를 지도 API 입력 형식으로 즉시 정제
  • 역지오코딩 검증: GPS 로그의 좌표가 어느 도로·건물인지 빠르게 확인
  • 부동산·현장 조사: 관심 지점 주소를 좌표로 변환해 반경 검색이나 지도 레이어에 바로 적용

지도·위치 카테고리의 다른 MCP 서버도 함께 활용하면 경로 검색, 장소 검색 등 더 풍부한 위치 기능을 AI 워크플로에 통합할 수 있습니다.

MCP모아 서버 전체 목록에서 위치 데이터와 함께 사용할 수 있는 다른 도구들도 살펴보세요.

자주 묻는 질문

카카오 지오코딩 API와 네이버 지오코딩 API 중 어느 것이 더 정확한가요?

카카오는 도로명·지번 모두 지원하며 국내 주소 정확도가 높습니다. 네이버는 지번 주소와 영문 주소에도 강점이 있습니다. 둘 다 무료 할당량이 있으므로 서비스 규모에 따라 선택하거나, 이 가이드에서처럼 폴백 구조로 함께 사용하는 것이 안정적입니다.

MCP 서버 없이 Claude에서 지오코딩을 사용할 수는 없나요?

Claude 자체는 실시간 외부 API를 호출하지 않습니다. MCP 서버를 통해야만 카카오·네이버 API를 실시간으로 연동할 수 있습니다. MCP는 이런 용도로 설계된 표준 프로토콜입니다.

역지오코딩(좌표 → 주소)도 같은 MCP 서버로 처리할 수 있나요?

네, 가능합니다. 카카오 로컬 API와 네이버 Reverse Geocoding API 모두 좌표를 주소로 변환하는 엔드포인트를 제공합니다. 이 가이드의 코드에서 reverseGeocode 도구를 함께 구현했으므로, 별도 서버 없이 양방향 변환이 가능합니다.

카카오 API 무료 할당량은 얼마인가요?

Kakao Developers 기준으로 지오코딩(로컬 API)은 일일 300,000건이 무료로 제공됩니다. 초과 시 유료 플랜이 필요하며, 정확한 수치는 Kakao Developers 공식 정책 페이지를 확인해 주세요.

Windows에서 Claude Desktop 설정 파일은 어디에 있나요?

%APPDATA%\Claude\claude_desktop_config.json 경로에 있습니다. macOS는 ~/Library/Application Support/Claude/claude_desktop_config.json 입니다.

MCP 서버가 Claude에서 인식되지 않으면 어떻게 해야 하나요?

설정 파일의 JSON 문법 오류, 서버 파일 경로 오타, Node.js 미설치, API 키 환경변수 누락이 가장 흔한 원인입니다. Claude Desktop 메뉴의 Help → Show Logs에서 오류 메시지를 확인하면 원인을 빠르게 파악할 수 있습니다.

다음 단계

지오코딩 MCP 서버를 구성했다면, 같은 방식으로 장소 검색이나 경로 탐색 API도 도구로 추가해 더 강력한 위치 기반 AI 어시스턴트를 만들 수 있습니다. MCP모아 가이드 목록에서 관련 튜토리얼을 계속 확인하세요. 직접 만든 MCP 서버를 다른 개발자와 공유하고 싶다면 MCP모아 서버 등록 페이지를 이용해 주세요.