From d1dbe68dbb98d44819ea3509e281b1059e460f1d Mon Sep 17 00:00:00 2001 From: hmmhmmhm Date: Wed, 7 Oct 2026 19:41:28 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20README=20=EC=83=81=EB=8B=A8=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=EC=99=80=20=EA=B8=B0=EC=A1=B4=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=20=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflows/workers-invocations-chart.yml | 2 +- README.md | 125 ++++++++++++++++-- .../ops/update-workers-invocations-chart.ts | 18 ++- tests/scripts/repository-config.test.ts | 10 +- .../scripts/workers-chart-entrypoint.test.ts | 20 +++ 5 files changed, 157 insertions(+), 18 deletions(-) diff --git a/.github/workflows/workers-invocations-chart.yml b/.github/workflows/workers-invocations-chart.yml index 68b06122..dfa7a448 100644 --- a/.github/workflows/workers-invocations-chart.yml +++ b/.github/workflows/workers-invocations-chart.yml @@ -69,7 +69,7 @@ jobs: run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add scripts/ops/README.md assets/analytics/workers-invocations.json assets/analytics/workers-invocations.png + git add README.md scripts/ops/README.md assets/analytics/workers-invocations.json assets/analytics/workers-invocations.png if git diff --cached --quiet; then echo "No chart changes to commit" diff --git a/README.md b/README.md index c78097f5..d8b3c344 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,120 @@ +[![MCP Toplist](https://mcptoplist.com/badge/glama%2Fhmmhmmhm%2Fdaiso-mcp.svg)](https://mcptoplist.com/server/glama%2Fhmmhmmhm%2Fdaiso-mcp) + +
+ +Daiso MCP + +
+
+ # Daiso MCP 및 Skill +다이소(제품/매장/재고), 상품 가격 비교, 주변 음식점/카페, 주유소/유가, 개발자 요청 제출, GS25(매장/상품/재고), 세븐일레븐(상품/매장/재고/인기검색어/카탈로그), CU(매장/재고), 이마트24(매장/상품/재고), 올리브영(매장/재고), 메가박스(지점/영화/시간표/좌석), 롯데시네마(지점/영화/좌석), CGV(극장/영화/시간표), 디트릭스(독립·예술영화관/상영작/잔여 좌석) 조회 기능을 MCP, CLI, Codex Skill로 AI에 연결합니다. + +디트릭스의 지원 범위와 CLI 예시는 [독립·예술영화관 조회 가이드](docs/dtryx.md)를 참고하세요. + +
+ +**MCP:** `https://mcp.aka.page` · **CLI:** `npx daiso` · **Skill:** `clawhub install daiso-cli` + +**ClawHub:** [clawhub.ai/hmmhmmhm/daiso-cli](https://clawhub.ai/hmmhmmhm/daiso-cli) + +한국 로컬 리테일, 생활 정보, 영화관 조회를 MCP, CLI, Codex Skill로 연결하는 도구입니다. +사용자는 별도 API 키를 준비하지 않고 바로 사용할 수 있습니다. + +
+ +

지원 서비스

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
분류서비스조회 기능
장소네이버 지역 검색음식점, 카페, 디저트, 주변 장소
교통오피넷전국 평균 유가, 최저가 주유소, 위치 기반 주유소, 주유소 상세정보
비교다이소, GS25, 세븐일레븐, 이마트24같은 상품의 판매처별 가격 후보 비교
운영SupabaseMCP 오류, 개선 요청, 신규 기능 요청 저장
리테일다이소, 올리브영상품, 매장, 재고
편의점GS25, 세븐일레븐, CU, 이마트24상품, 매장, 재고, 인기검색어, 카탈로그
영화관CGV, 메가박스, 롯데시네마극장, 영화, 시간표, 잔여 좌석
+ +
+ +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) +[![Cloudflare Workers](https://img.shields.io/badge/Cloudflare-Workers-F38020.svg)](https://workers.cloudflare.com/) +[![MCP](https://img.shields.io/badge/MCP-Protocol-8B5CF6.svg)](https://modelcontextprotocol.io/) +[![Code Coverage](https://img.shields.io/badge/Code%20Coverage-100%25-brightgreen.svg)](https://github.com/hmmhmmhm/daiso-mcp/actions/workflows/coverage.yml) +[![Coverage](https://github.com/hmmhmmhm/daiso-mcp/actions/workflows/coverage.yml/badge.svg?branch=main)](https://github.com/hmmhmmhm/daiso-mcp/actions/workflows/coverage.yml) +[![Better Stack Badge](https://uptime.betterstack.com/status-badges/v2/monitor/2mmhx.svg)](https://aka-page.betteruptime.com/) + +**[실시간 서비스 상태 보기](https://aka-page.betteruptime.com/)** + + +

Cloudflare 요청 수 (2026-09-07 ~ 2026-10-06, 30일)

+ +Cloudflare 요청 수 그래프 (2026-09-07 ~ 2026-10-06) + +기준 워커: daiso-mcp · 마지막 갱신: 2026-10-07 05:21 KST +
집계: Worker 실행 + 루트 GET 리디렉션 요청 · 사용자 수와 다릅니다. + +
+ +> [!IMPORTANT] +> 최근 공개 서버 사용량이 크게 증가하여 2026년 7월 18일부터 올리브영·CGV·CU·GS25의 검색을 포함한 공개 GET API에 IP당 하루 합산 3,000회(KST 기준)의 호출 제한을 적용합니다. 한도를 초과하는 사용이 필요하다면 Daiso MCP는 오픈 소스이므로 이 저장소를 직접 배포해 이용해 주세요. + +
+ + + +
+ +
+ +   + +
+ +
+ +--- + +
+ 다이소·편의점 재고, 주변 장소, 주유소 가격, 영화 시간표를 AI에서 조회합니다. **공개 원격 MCP에 연결하면 로컬 설치·빌드·API 키 준비 없이 바로 사용할 수 있습니다.** 에이전트는 [짧은 시작 안내](https://mcp.aka.page/llms.txt)를 참고하세요. 무설치 요청에는 npm 설치나 전체 스키마 탐색이 필요하지 않습니다. @@ -65,16 +180,6 @@ GS25 mcp로 강남 근처 오감자 재고 알려줘 재고 조회는 먼저 상품을 검색해 ID를 확인한 뒤 진행합니다. 자세한 선택 규칙은 [AI 지시문](docs/ai-instruction.md)에 있습니다. -## 지원 서비스 - -| 분류 | 서비스 | 주요 조회 | -| :-------- | :---------------------------------- | :---------------------- | -| 리테일 | 다이소, 올리브영 | 상품·매장·재고 | -| 편의점 | GS25, 세븐일레븐, CU, 이마트24 | 상품·매장·재고 | -| 가격 비교 | 다이소, GS25, 세븐일레븐, 이마트24 | 같은 상품의 가격 후보 | -| 장소·유가 | 네이버 지역 검색, 오피넷 | 카페·음식점·주유소·유가 | -| 영화관 | CGV, 메가박스, 롯데시네마, 디트릭스 | 지점·영화·시간표·좌석 | - 서비스별 지원 범위와 입력은 [서비스 레퍼런스](docs/service-reference.md)와 [디트릭스 가이드](docs/dtryx.md)를 참고하세요. 롯데마트는 지원이 종료되었습니다. 과거 분석과 호환 경로만 보존합니다. diff --git a/scripts/ops/update-workers-invocations-chart.ts b/scripts/ops/update-workers-invocations-chart.ts index 40a10149..0d0d3986 100644 --- a/scripts/ops/update-workers-invocations-chart.ts +++ b/scripts/ops/update-workers-invocations-chart.ts @@ -274,16 +274,16 @@ async function renderChart(points, summary, metadata) { return sharp(Buffer.from(svg)).png().toBuffer(); } -async function updateReadme(section) { - const readme = (await fs.readFile(README_PATH, 'utf8')).replaceAll('\r\n', '\n'); +async function updateReadme(section, readmePath = README_PATH) { + const readme = (await fs.readFile(readmePath, 'utf8')).replaceAll('\r\n', '\n'); const pattern = new RegExp(`${README_START}[\\s\\S]*?${README_END}`, 'm'); if (pattern.test(readme)) { - await fs.writeFile(README_PATH, readme.replace(pattern, section), 'utf8'); + await fs.writeFile(readmePath, readme.replace(pattern, section), 'utf8'); return; } const next = `${readme.trimEnd()}\n\n${section}\n`; - await fs.writeFile(README_PATH, next, 'utf8'); + await fs.writeFile(readmePath, next, 'utf8'); } async function main() { @@ -397,6 +397,16 @@ async function main() { includesRootRedirect: Boolean(payload.rootRedirect), }); await updateReadme(section); + const publicReadmePath = path.join(REPO_ROOT, 'README.md'); + const publicReadme = await fs.readFile(publicReadmePath, 'utf8'); + if (publicReadme.includes(README_START) && publicReadme.includes(README_END)) { + // 상단의 중앙 정렬은 차트 앞에서 시작하고 예시 이미지 뒤에서 끝납니다. + const publicSection = section + .replace('
\n\n', '') + .replace('../../assets/analytics/', './assets/analytics/') + .replace(README_END, `
\n\n${README_END}`); + await updateReadme(publicSection, publicReadmePath); + } console.log( `[workers-chart] script=${scriptName} days=${points.length} total=${formatNumber(payload.total)}`, diff --git a/tests/scripts/repository-config.test.ts b/tests/scripts/repository-config.test.ts index 0a717ada..84a0527b 100644 --- a/tests/scripts/repository-config.test.ts +++ b/tests/scripts/repository-config.test.ts @@ -204,7 +204,7 @@ describe('repository maintenance configuration', () => { expect(workflow).toContain('CLOUDFLARE_ZONE_ID'); expect(workflow).toContain('WORKERS_CHART_ROOT_REDIRECT_START'); expect(workflow).toContain( - 'git add scripts/ops/README.md assets/analytics/workers-invocations.json assets/analytics/workers-invocations.png', + 'git add README.md scripts/ops/README.md assets/analytics/workers-invocations.json assets/analytics/workers-invocations.png', ); expect(workflow).toContain('git pull --rebase --autostash origin main'); expect(workflow).toContain('git push origin HEAD:main'); @@ -298,7 +298,11 @@ describe('repository maintenance configuration', () => { expect(readme).toContain('Daiso MCP 및 Skill'); expect(readme).toContain('skills/daiso-cli/SKILL.md'); expect(readme).toContain('npx daiso'); - const fastStart = readme.split('\n').slice(0, 100).join('\n'); + const fastStart = readme + .slice(readme.indexOf('다이소·편의점 재고')) + .split('\n') + .slice(0, 100) + .join('\n'); expect(fastStart).toContain('https://mcp.aka.page'); expect(fastStart).toContain('Streamable HTTP'); expect(fastStart).toContain('API 키·토큰·OAuth 설정 불필요'); @@ -307,7 +311,7 @@ describe('repository maintenance configuration', () => { expect(fastStart).toContain('"method":"tools/call"'); expect(fastStart).toContain('"name":"daiso_search_products"'); expect(fastStart).toContain('"query":"수납박스"'); - expect(readme).not.toContain('WORKERS_INVOCATIONS_CHART:START'); + expect(readme).toContain('WORKERS_INVOCATIONS_CHART:START'); expect(readme).toContain('scripts/ops/README.md'); }); diff --git a/tests/scripts/workers-chart-entrypoint.test.ts b/tests/scripts/workers-chart-entrypoint.test.ts index cff51480..20f03f1b 100644 --- a/tests/scripts/workers-chart-entrypoint.test.ts +++ b/tests/scripts/workers-chart-entrypoint.test.ts @@ -137,4 +137,24 @@ describe('workers chart entrypoint', () => { expect(readme.endsWith('\n\n## Footer\n')).toBe(true); expect(readme).toContain('Worker 실행 + 루트 GET 리디렉션 요청'); }); + it('상단 README 차트도 갱신하며 기존 중앙 정렬과 뒤 이미지를 보존한다', async () => { + const { root, dataPath } = await fixture(); + const prefix = '# Header\n
\n'; + const suffix = '\n\n
\n## Quick start\n'; + await fs.writeFile( + path.join(root, 'README.md'), + prefix + + '\nold chart\n
\n> quota\n
\n' + + suffix, + ); + run(root, { WORKERS_CHART_INPUT_JSON: dataPath }); + const readme = await fs.readFile(path.join(root, 'README.md'), 'utf8'); + expect(readme.startsWith(prefix)).toBe(true); + expect(readme.endsWith(suffix)).toBe(true); + expect(readme).toContain('./assets/analytics/workers-invocations.png'); + expect(readme).not.toContain('old chart'); + expect(readme.match(/
/g)).toHaveLength(2); + expect(readme.match(/<\/div>/g)).toHaveLength(2); + expect(readme).toContain('IP당 하루 합산 3,000회'); + }); });