mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-06-24 02:04:11 +00:00
Prevent misleading real-estate self-host instructions
Tighten the real-estate skill docs so the launchd fallback stays operational and the Onbid bid-result tools are described with the same WIP caveat the upstream project still publishes. Constraint: Upstream Docker compose already uses restart: unless-stopped while `docker compose ... up -d` daemonizes immediately Rejected: Keep a separate server LaunchAgent with RunAtLoad + KeepAlive | launchd would restart-loop on the exiting compose command Confidence: high Scope-risk: narrow Reversibility: clean Directive: Mirror upstream capability caveats in k-skill docs and do not wrap daemonized server commands in launchd KeepAlive jobs Tested: node --test scripts/skill-docs.test.js Tested: npm run ci Tested: uv sync Tested: uv run real-estate-mcp --help Tested: DATA_GO_KR_API_KEY=dummy uv run real-estate-mcp --transport http --host 127.0.0.1 --port 8017 Tested: curl initialize on http://127.0.0.1:8017/mcp returned protocolVersion 2024-11-05 Not-tested: Live 거래 조회 with a real DATA_GO_KR_API_KEY
This commit is contained in:
parent
81c81cb5da
commit
d656d26412
3 changed files with 38 additions and 31 deletions
|
|
@ -6,7 +6,9 @@
|
|||
- 아파트 전월세 조회 (`get_apartment_rent`)
|
||||
- 오피스텔/연립다세대/단독주택/상업업무용 실거래가 조회
|
||||
- 지역코드 조회 (`get_region_code`) 후 행정구역 기준 검색
|
||||
- 청약홈/온비드 도구 연결
|
||||
- 청약홈 도구 연결
|
||||
- 온비드 코드/주소 조회
|
||||
- 온비드 입찰결과 도구 (`get_public_auction_items`, `get_public_auction_item_detail`)는 upstream README 기준 `⚠️ WIP` 상태로 preview 안내
|
||||
- hosted endpoint가 없을 때 self-host + Cloudflare Tunnel + launchd 운영
|
||||
|
||||
## 가장 중요한 규칙
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
|
||||
`DATA_GO_KR_API_KEY` 하나만 넣어도 기본 실거래가 조회는 시작할 수 있다.
|
||||
청약홈/온비드를 더 세밀하게 나누고 싶으면 upstream 문서대로 `ODCLOUD_API_KEY`, `ODCLOUD_SERVICE_KEY`, `ONBID_API_KEY` 를 추가한다.
|
||||
다만 `get_public_auction_items`, `get_public_auction_item_detail` 는 2026-04-05 기준 upstream README 에서 아직 `⚠️ WIP` 로 남아 있으므로, 안정 기능처럼 소개하지 말고 preview/실험 단계로만 설명한다.
|
||||
|
||||
## 가장 빠른 시작: Codex CLI stdio
|
||||
|
||||
|
|
@ -111,17 +114,15 @@ cloudflared tunnel run real-estate-mcp
|
|||
|
||||
### 4. launchd로 자동 실행
|
||||
|
||||
macOS 기준으로는 서버와 tunnel을 분리한 launchd 항목 두 개를 만든다.
|
||||
macOS 기준으로는 **launchd 를 tunnel 전용으로만** 쓰고, upstream 서버 컨테이너 재시작은 Docker 쪽에 맡긴다.
|
||||
upstream `docker/docker-compose.yml` 이 이미 `restart: unless-stopped` 를 설정하므로, `docker compose -f docker/docker-compose.yml up -d` 를 `RunAtLoad` + `KeepAlive` launchd job 에 넣으면 daemonize 직후 종료된 프로세스를 launchd 가 계속 다시 띄우는 restart loop가 생긴다.
|
||||
|
||||
따라서 서버 쪽은 Docker Desktop/Engine 자동 시작을 켜고 `docker compose ... up -d --build` 를 한 번 실행해 둔 뒤, `cloudflared tunnel run real-estate-mcp` 만 launchd 에 등록한다.
|
||||
|
||||
- `~/Library/LaunchAgents/com.kskill.real-estate-mcp.server.plist`
|
||||
- `~/Library/LaunchAgents/com.kskill.real-estate-mcp.tunnel.plist`
|
||||
|
||||
둘 다 `RunAtLoad` 와 `KeepAlive` 를 켜고, 서버 쪽은 `docker compose -f docker/docker-compose.yml up -d`, tunnel 쪽은 `cloudflared tunnel run real-estate-mcp` 를 실행하게 둔다.
|
||||
|
||||
```bash
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kskill.real-estate-mcp.server.plist
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kskill.real-estate-mcp.tunnel.plist
|
||||
launchctl enable gui/$(id -u)/com.kskill.real-estate-mcp.server
|
||||
launchctl enable gui/$(id -u)/com.kskill.real-estate-mcp.tunnel
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ metadata:
|
|||
- 단독/다가구 매매/전월세: `get_single_house_trades`, `get_single_house_rent`
|
||||
- 상업업무용 매매: `get_commercial_trade`
|
||||
- 청약홈 분양/당첨: `get_apt_subscription_info`, `get_apt_subscription_results`
|
||||
- 공공경매/온비드: `get_public_auction_items`, `get_public_auction_item_detail`
|
||||
- 공공경매/온비드 입찰결과: `get_public_auction_items`, `get_public_auction_item_detail` (`⚠️ WIP`, upstream README 기준)
|
||||
- 지역코드 조회: `get_region_code`
|
||||
|
||||
## When to use
|
||||
|
|
@ -52,6 +52,7 @@ metadata:
|
|||
|
||||
`DATA_GO_KR_API_KEY` 하나만 넣어도 기본 부동산 조회는 시작할 수 있다.
|
||||
청약홈/온비드 키를 분리하고 싶으면 upstream 문서대로 `ODCLOUD_API_KEY`, `ODCLOUD_SERVICE_KEY`, `ONBID_API_KEY` 를 추가한다.
|
||||
다만 `get_public_auction_items`, `get_public_auction_item_detail` 는 2026-04-05 기준 upstream README 에서 아직 `⚠️ WIP` 로 표시돼 있으니, production-ready 라고 단정하지 않고 preview 성격으로만 안내한다.
|
||||
|
||||
## Codex CLI setup (stdio)
|
||||
|
||||
|
|
@ -164,27 +165,10 @@ public 인터넷에 노출한다면 upstream `docs/setup-oauth.md` 대로 `AUTH_
|
|||
|
||||
### 3. macOS launchd 자동 실행
|
||||
|
||||
부팅 후 안정적으로 다시 뜨게 하려면 upstream 서버와 tunnel을 각각 launchd 로 올린다.
|
||||
부팅 후 안정적으로 다시 뜨게 하려면 **launchd 는 Cloudflare Tunnel만 담당**하게 두고, upstream 서버 컨테이너는 Docker 쪽 재시작 정책에 맡긴다.
|
||||
`docker/docker-compose.yml` 에 이미 `restart: unless-stopped` 가 들어 있으므로, `docker compose ... up -d` 를 `RunAtLoad` + `KeepAlive` launchd job 으로 감싸면 오히려 즉시 종료된 프로세스를 launchd 가 반복 재실행하게 된다.
|
||||
|
||||
`~/Library/LaunchAgents/com.kskill.real-estate-mcp.server.plist`
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key><string>com.kskill.real-estate-mcp.server</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/zsh</string>
|
||||
<string>-lc</string>
|
||||
<string>cd $HOME/src/real-estate-mcp && docker compose -f docker/docker-compose.yml up -d</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
즉, 서버 쪽은 Docker Desktop/Engine 이 로그인 후 자동 기동되도록 설정한 다음 위의 `docker compose ... up -d --build` 를 한 번 실행해 두고, macOS launchd 에는 long-running 프로세스인 `cloudflared tunnel run ...` 만 등록한다.
|
||||
|
||||
`~/Library/LaunchAgents/com.kskill.real-estate-mcp.tunnel.plist`
|
||||
|
||||
|
|
@ -208,13 +192,11 @@ public 인터넷에 노출한다면 upstream `docs/setup-oauth.md` 대로 `AUTH_
|
|||
```
|
||||
|
||||
```bash
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kskill.real-estate-mcp.server.plist
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kskill.real-estate-mcp.tunnel.plist
|
||||
launchctl enable gui/$(id -u)/com.kskill.real-estate-mcp.server
|
||||
launchctl enable gui/$(id -u)/com.kskill.real-estate-mcp.tunnel
|
||||
```
|
||||
|
||||
위 예시는 macOS 기준이다. Linux/Windows에서는 systemd 또는 서비스 관리자로 같은 역할을 분리해서 등록한다.
|
||||
위 예시는 macOS 기준이다. Linux/Windows에서는 Docker 서비스 자동 시작 + systemd/서비스 관리자로 tunnel 같은 long-running 프로세스를 따로 등록한다.
|
||||
|
||||
## Response policy
|
||||
|
||||
|
|
|
|||
|
|
@ -1257,6 +1257,30 @@ test("repository docs advertise the real-estate-search skill and upstream self-h
|
|||
assert.equal(fs.existsSync(path.join(repoRoot, "packages", "real-estate-search")), false);
|
||||
});
|
||||
|
||||
test("real-estate-search docs keep the upstream Onbid WIP caveat and avoid launchd daemonize loops", () => {
|
||||
const featureDoc = read(path.join("docs", "features", "real-estate-search.md"));
|
||||
const skill = read(path.join("real-estate-search", "SKILL.md"));
|
||||
|
||||
for (const doc of [skill, featureDoc]) {
|
||||
assert.match(doc, /get_public_auction_items/);
|
||||
assert.match(doc, /get_public_auction_item_detail/);
|
||||
assert.match(doc, /WIP|작업 중|준비 중/);
|
||||
}
|
||||
|
||||
const skillLaunchdSection = skill.match(/##\s+.*launchd[\s\S]*?(?=\n##\s+|\n#\s+|$)/i)?.[0];
|
||||
const featureLaunchdSection = featureDoc.match(/###+\s+.*launchd[\s\S]*?(?=\n##\s+|\n#\s+|$)/i)?.[0];
|
||||
|
||||
assert.ok(skillLaunchdSection, "expected skill launchd section");
|
||||
assert.ok(featureLaunchdSection, "expected feature guide launchd section");
|
||||
|
||||
for (const section of [skillLaunchdSection, featureLaunchdSection]) {
|
||||
assert.doesNotMatch(section, /com\.kskill\.real-estate-mcp\.server/);
|
||||
assert.doesNotMatch(section, /launchctl .*real-estate-mcp\.server/i);
|
||||
assert.match(section, /restart:\s*unless-stopped|Docker (Desktop|Engine).*재기동|Docker.*자동 재시작/i);
|
||||
assert.match(section, /cloudflared[\s\S]*tunnel[\s\S]*run[\s\S]*real-estate-mcp/i);
|
||||
}
|
||||
});
|
||||
|
||||
test("repository docs advertise the shipped korean-spell-check helper assets", () => {
|
||||
const readme = read("README.md");
|
||||
const install = read(path.join("docs", "install.md"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue