Skip to main content
Glama
KimJintak

opinet-mcp

by KimJintak
README.md
# opinet-mcp

한국석유공사 **오피넷(Opinet)** 유가정보 무료 API를 Claude / Claude Code 등 MCP 클라이언트에서 사용할 수 있게 해주는 MCP 서버입니다.

- 언어: TypeScript (ESM)
- SDK: `@modelcontextprotocol/sdk`
- 전송: stdio
- 호출 제한: **1,500 call/일** (오피넷 정책)

---

## 사전 준비

1. [오피넷 무료 API](https://www.opinet.co.kr/) 에서 API Key 발급
2. Node.js **18 이상** (글로벌 `fetch` 사용)

---

## 설치 & 실행 — 3가지 방법

### 방법 1. npx로 즉시 실행 (권장 · 별도 설치 불필요)

> npm 레지스트리에 publish 후 사용 가능. publish는 아래 "배포" 섹션 참고.

```bash
OPINET_API_KEY=발급키 npx -y opinet-mcp
```

### 방법 2. 글로벌 설치

```bash
npm install -g opinet-mcp
OPINET_API_KEY=발급키 opinet-mcp
```

### 방법 3. 소스 클론 (개발 / private 사용)

```bash
git clone https://github.com/KimJintak/opinet-mcp.git
cd opinet-mcp
npm install
npm run build
OPINET_API_KEY=발급키 node dist/index.js
```

---

## MCP 클라이언트 등록

### Claude Desktop / Claude Code

설정 파일 위치:

| OS | 경로 |
| --- | --- |
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |

#### A. npx 방식 (가장 간편 — publish 후 사용)

```json
{
  "mcpServers": {
    "opinet": {
      "command": "npx",
      "args": ["-y", "opinet-mcp"],
      "env": {
        "OPINET_API_KEY": "발급받은_키"
      }
    }
  }
}
```

#### B. 글로벌 설치 방식

```json
{
  "mcpServers": {
    "opinet": {
      "command": "opinet-mcp",
      "env": {
        "OPINET_API_KEY": "발급받은_키"
      }
    }
  }
}
```

#### C. 로컬 빌드 방식 (소스 클론한 경우)

```json
{
  "mcpServers": {
    "opinet": {
      "command": "node",
      "args": ["/절대/경로/opinet-mcp/dist/index.js"],
      "env": {
        "OPINET_API_KEY": "발급받은_키"
      }
    }
  }
}
```

> ⚠️ Claude Desktop은 PATH를 제한적으로 상속받습니다. `command: "node"` 또는 `"npx"`로 실행 시 못 찾는다면 절대경로(`/opt/homebrew/bin/node`, `/usr/local/bin/npx` 등)로 지정하세요. 터미널에서 `which node` / `which npx`로 확인.

설정 후 **Claude Desktop 완전 종료(Cmd+Q) → 재실행**하면 도구 아이콘에서 6개 툴을 확인할 수 있습니다.

### 다른 MCP 클라이언트 (Cursor, Cline, Continue 등)

위 JSON 구조와 동일하게 각 클라이언트의 MCP 서버 설정 파일에 추가하면 됩니다.

---

## 제공 툴 (6종)

| Tool name | 오피넷 엔드포인트 | 설명 |
| --- | --- | --- |
| `get_national_average_price` | `avgAllPrice.do` | 전국 주유소 평균가격 (현재) |
| `get_sido_average_price` | `avgSidoPrice.do` | 시도별 주유소 평균가격 (현재) |
| `get_recent_7days_price` | `avgRecentPrice.do` | 최근 7일간 전국 일일 평균가격 (추세) |
| `get_lowest_price_top20` | `lowTop10.do` | 전국/지역별 최저가 주유소 TOP20 |
| `search_stations_around` | `aroundAll.do` | KATEC 좌표 기준 반경 내 주유소 검색 |
| `get_station_detail` | `detailById.do` | 주유소 ID(UNI_ID)로 상세정보 조회 |

### 공통 코드

**제품코드 (`prodcd`)**

| 코드 | 제품 |
| --- | --- |
| `B027` | 보통휘발유 |
| `D047` | 자동차경유 |
| `B034` | 고급휘발유 |
| `C004` | 실내등유 |
| `K015` | 자동차부탄 |

**시도코드 (`sido` / `area` 2자리)**

| 코드 | 지역 | 코드 | 지역 |
| --- | --- | --- | --- |
| 01 | 서울 | 10 | 부산 |
| 02 | 경기 | 11 | 제주 |
| 03 | 강원 | 12 | 대구 |
| 04 | 충북 | 13 | 인천 |
| 05 | 충남 | 14 | 광주 |
| 06 | 전북 | 15 | 대전 |
| 07 | 전남 | 16 | 울산 |
| 08 | 경북 | 17 | 세종 |
| 09 | 경남 | | |

> 시군구 단위는 4자리 코드입니다 (예: `0207` = 경기 광명시). 오피넷 `areaCode.do` 엔드포인트로 별도 조회 가능.

### 좌표계 주의사항

`search_stations_around`의 입력 좌표(`x`, `y`)와 모든 응답의 `GIS_X_COOR / GIS_Y_COOR`는 **KATEC 좌표계**입니다. WGS84(위경도)와 다르므로, 위경도를 입력으로 받으려면 클라이언트에서 KATEC으로 변환 후 호출하세요.

---

## 사용 예시 (자연어)

- "오늘 전국 휘발유 평균가 알려줘" → `get_national_average_price`
- "서울 시도 평균 경유 가격" → `get_sido_average_price` (`sido=01`, `prodcd=D047`)
- "최근 7일간 휘발유 추세" → `get_recent_7days_price` (`prodcd=B027`)
- "광명시에서 가장 싼 휘발유 주유소 5곳" → `get_lowest_price_top20` (`prodcd=B027`, `area=0207`, `cnt=5`)
- "주유소 ID A0008322 상세정보" → `get_station_detail`

---

## 동작 확인 (스모크 테스트)

API 키 없이 실행 → 환경변수 안내 후 종료되면 빌드 OK:

```bash
node dist/index.js
```

API 키가 있을 때, stdio로 직접 호출:

```bash
export OPINET_API_KEY=발급키

# 등록된 툴 목록 확인
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js

# 전국 평균가격 호출
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_national_average_price","arguments":{}}}' | node dist/index.js
```

---

## 개발

```bash
npm install
npm run dev      # tsc --watch
npm run build    # 한 번 빌드
npm start        # dist/index.js 실행
npm run clean    # dist 삭제
```

프로젝트 구조:

```
opinet-mcp/
├── src/
│   └── index.ts          # MCP 서버 본체
├── dist/                 # 빌드 결과물 (배포 대상)
├── package.json
├── tsconfig.json
├── README.md
└── LICENSE
```

---

## 배포 (npm publish)

처음 publish할 때:

```bash
# 1) npm 로그인
npm login

# 2) package.json의 author / repository / name 확인 (필요하면 scoped: @yourname/opinet-mcp)

# 3) 빌드 + publish (prepublishOnly에서 자동 빌드됨)
npm publish

# scoped 패키지면
npm publish --access public
```

이후 버전 업:

```bash
npm version patch   # 0.1.0 -> 0.1.1
npm publish
```

publish 후에는 누구나 `npx -y opinet-mcp` 로 즉시 사용 가능합니다.

> `prepare` 스크립트가 있어서 `npm install` 시 자동 빌드됩니다. 즉, GitHub에서 직접 설치 (`npm i github:KimJintak/opinet-mcp`) 해도 동작합니다.

---

## 라이선스

MIT.

데이터 출처는 한국석유공사 오피넷이며, 데이터 사용 시 [오피넷 이용 약관](https://www.opinet.co.kr/)을 따르시기 바랍니다.

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct data view (cheapest stations, national average, historical trends, regional averages, single station details). While all relate to fuel prices, the scope filters (top20, 7-day history, sido codes) create clear boundaries.

Naming Consistency5/5

All tools use consistent snake_case with a 'get_' verb prefix followed by descriptive noun phrases (lowest_price_top20, national_average_price, etc.). The pattern is predictable throughout.

Tool Count4/5

Five tools cover the essential read-only queries for a fuel price information service without bloat. The scope is well-contained, though an additional search-by-radius or brand filter could round it out.

Completeness4/5

Core price discovery workflows are covered: finding cheap stations, checking averages at national/regional levels, viewing trends, and drilling into station details. Minor gaps include no brand-specific queries or historical data beyond 7 days.

Maintenance

ActivityInactive
ResponsivenessNo issues