@roottale/cms-mcp 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @roottale/cms-mcp
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 299c9b2: 문의 유입 어트리뷰션 (ADR-0048 §2). `submitInquiry` 에 `attribution` 필드 추가 — 비콘이 기억한 first-touch(처음 도착한 페이지·단축링크/QR 토큰·utm·외부 referrer 호스트명)를 문의와 함께 보내면 어드민 CRM 에 유입 경로가 표시된다. 신규: `@roottale/cms-client/attribution` 서브패스의 `readAttribution()`(브라우저 전용), 서버 엔트리의 `parseAttributionJson()`, intake API `attr_*` 폼 필드. cms-mcp docs(inquiries/api-reference) 및 예제(AttributionField) 동반 갱신.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- edba5a1: README 에 사람용 문서 경로 추가 — 공식 문서 사이트(roottale.com/docs) + unpkg 원문 열람
|
|
12
|
+
|
|
3
13
|
## 0.23.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -49,10 +49,14 @@ claude mcp add roottale-cms -- npx -y @roottale/cms-mcp
|
|
|
49
49
|
| `listPublishedPosts` | 공개 API로 발행 글 목록 조회 (키 필요) |
|
|
50
50
|
| `getPublishedPost` | 공개 API로 발행 글 1개 조회 (키 필요) |
|
|
51
51
|
|
|
52
|
-
## 사람용 문서
|
|
52
|
+
## 사람용 문서 (브라우저 열람)
|
|
53
53
|
|
|
54
|
-
문서
|
|
55
|
-
|
|
54
|
+
- **공식 문서 사이트**: <https://roottale.com/docs> — 본 패키지의 `docs/` 를
|
|
55
|
+
렌더한 것 (release 시 자동 갱신)
|
|
56
|
+
- 원문 파일: <https://unpkg.com/browse/@roottale/cms-mcp@latest/docs/>
|
|
57
|
+
- 예시 코드: <https://unpkg.com/browse/@roottale/cms-mcp@latest/examples/nextjs/>
|
|
58
|
+
|
|
59
|
+
로컬 설치본에서는 `node_modules/@roottale/cms-mcp/docs/` 를 직접 열면 됩니다.
|
|
56
60
|
|
|
57
61
|
## License
|
|
58
62
|
|
package/dist/index.js
CHANGED
|
@@ -256,7 +256,7 @@ function registerTools(server2) {
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
// src/server.ts
|
|
259
|
-
var VERSION = true ? "0.
|
|
259
|
+
var VERSION = true ? "0.24.0" : "dev";
|
|
260
260
|
var SERVER_INSTRUCTIONS = `
|
|
261
261
|
roottale-cms-mcp\uB294 RootTale CMS\uB97C \uC678\uBD80 \uC0AC\uC774\uD2B8(\uC8FC\uB85C Next.js)\uC5D0 \uC5F0\uB3D9\uD558\uAE30 \uC704\uD55C
|
|
262
262
|
\uD1B5\uD569 \uBB38\uC11C\xB7\uC608\uC2DC \uCF54\uB4DC\xB7\uACF5\uAC1C API \uC870\uD68C tool\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.
|
package/docs/api-reference.md
CHANGED
|
@@ -88,6 +88,7 @@ JS/TS 스택은 raw 호출 대신 `@roottale/cms-client`를 사용하세요 —
|
|
|
88
88
|
| `message`, `consultation_field`, `current_site_url` | | |
|
|
89
89
|
| `lead_kind` | | `patient`(기본) \| `sales` |
|
|
90
90
|
| `_redirect_url` | | 완료 후 redirect base (allowlist 검증) |
|
|
91
|
+
| `attr_landing_path`, `attr_rt_src`, `attr_utm_source`, `attr_utm_medium`, `attr_utm_campaign`, `attr_referrer`, `attr_first_touch_at` | | 유입 어트리뷰션 — CRM에 유입 경로 표시 (`inquiries.md` 참고). 그 외 `attr_*` 키는 무시 |
|
|
91
92
|
| 기타 임의 필드 | | 최대 50개, 암호화 보관, CRM 상세 노출 |
|
|
92
93
|
|
|
93
94
|
응답: `302` redirect — 성공 `?ok=1`, 실패 `?err=<code>`
|
package/docs/inquiries.md
CHANGED
|
@@ -81,9 +81,62 @@ export async function submitContact(
|
|
|
81
81
|
| `overseasTransferConsent` | medical 시 ✅ | 국외이전 동의 |
|
|
82
82
|
| `leadKind` | | `patient`(기본) \| `sales` |
|
|
83
83
|
| `extras` | | 임의 추가 항목 (최대 50개, 암호화 보관, CRM 상세에 노출) |
|
|
84
|
+
| `attribution` | | 유입 first-touch — 아래 [유입 어트리뷰션](#유입-어트리뷰션-attribution) 참고 |
|
|
84
85
|
|
|
85
86
|
`extras`에 개인정보가 담길 수 있으므로 폼의 동의 고지에 수집 항목을 반영하세요.
|
|
86
87
|
|
|
88
|
+
## 유입 어트리뷰션 (`attribution`)
|
|
89
|
+
|
|
90
|
+
문의가 **어느 글·검색·단축링크/QR에서 왔는지**를 CRM에 표시하려면 두 줄만
|
|
91
|
+
추가하면 됩니다. RootTale 비콘이 방문자의 first-touch(처음 도착한
|
|
92
|
+
경로·`rt_src` 토큰·utm·외부 referrer 호스트명)를 30일간 기억하며,
|
|
93
|
+
`readAttribution()`(브라우저 전용, `@roottale/cms-client/attribution`)으로
|
|
94
|
+
읽습니다. 식별자가 아니므로 개인정보가 아닙니다.
|
|
95
|
+
|
|
96
|
+
1. 폼 안에 hidden input 추가 (클라이언트 컴포넌트):
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
"use client";
|
|
100
|
+
import { useEffect, useState } from "react";
|
|
101
|
+
import { readAttribution } from "@roottale/cms-client/attribution";
|
|
102
|
+
|
|
103
|
+
export function AttributionField() {
|
|
104
|
+
const [value, setValue] = useState("");
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
const attribution = readAttribution();
|
|
107
|
+
if (attribution) setValue(JSON.stringify(attribution));
|
|
108
|
+
}, []);
|
|
109
|
+
return <input type="hidden" name="attribution" value={value} />;
|
|
110
|
+
}
|
|
111
|
+
// 사용: <form action={...}> ... <AttributionField /> ... </form>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
2. Server Action에서 파싱해 전달:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { parseAttributionJson, submitInquiry } from "@roottale/cms-client/server";
|
|
118
|
+
|
|
119
|
+
const attribution = parseAttributionJson(formData.get("attribution")); // 깨진 값은 null
|
|
120
|
+
const result = await submitInquiry({
|
|
121
|
+
apiKey: process.env.ROOTTALE_API_KEY!,
|
|
122
|
+
fields: { /* ...표준 필드 */ attribution },
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`InquiryAttribution` 형태 (모든 필드 선택):
|
|
127
|
+
|
|
128
|
+
| 필드 | 설명 |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `landing_path` | 첫 방문 landing pathname |
|
|
131
|
+
| `rt_src` | 단축링크/QR 토큰 (`roottale.link` 경유 시) |
|
|
132
|
+
| `utm_source` / `utm_medium` / `utm_campaign` | UTM 파라미터 |
|
|
133
|
+
| `referrer` | 외부 referrer **호스트명** (raw URL 아님) |
|
|
134
|
+
| `first_touch_at` | first-touch 시각 (ISO 8601) |
|
|
135
|
+
|
|
136
|
+
직접 HTTP 연동 시에는 같은 값을 `attr_landing_path`, `attr_rt_src`,
|
|
137
|
+
`attr_utm_source`, `attr_utm_medium`, `attr_utm_campaign`, `attr_referrer`,
|
|
138
|
+
`attr_first_touch_at` 폼 필드로 보내면 됩니다.
|
|
139
|
+
|
|
87
140
|
## 에러 처리
|
|
88
141
|
|
|
89
142
|
`submitInquiry`는 throw 하지 않고 구조화된 결과를 반환합니다:
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// 유입 어트리뷰션 hidden input — 문의 폼 <form> 안에 넣기만 하면 된다.
|
|
2
|
+
// RootTale 비콘이 localStorage 에 기억해 둔 first-touch(처음 도착한 페이지 ·
|
|
3
|
+
// 단축링크/QR 토큰 · utm · 외부 referrer 호스트명)를 JSON 으로 실어 보내고,
|
|
4
|
+
// 서버 액션이 parseAttributionJson(formData.get("attribution")) 으로 받는다.
|
|
5
|
+
// 값이 없으면 빈 문자열 → 서버에서 null 처리되므로 항상 안전하다.
|
|
6
|
+
"use client";
|
|
7
|
+
|
|
8
|
+
import { useEffect, useState } from "react";
|
|
9
|
+
|
|
10
|
+
import { readAttribution } from "@roottale/cms-client/attribution";
|
|
11
|
+
|
|
12
|
+
export function AttributionField() {
|
|
13
|
+
const [value, setValue] = useState("");
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const attribution = readAttribution();
|
|
16
|
+
if (attribution) setValue(JSON.stringify(attribution));
|
|
17
|
+
}, []);
|
|
18
|
+
return <input type="hidden" name="attribution" value={value} />;
|
|
19
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// 클라이언트 폼에서 useActionState(submitContact, { status: "idle" })로 연결.
|
|
3
3
|
"use server";
|
|
4
4
|
|
|
5
|
-
import { submitInquiry } from "@roottale/cms-client/server";
|
|
5
|
+
import { parseAttributionJson, submitInquiry } from "@roottale/cms-client/server";
|
|
6
6
|
|
|
7
7
|
export interface ContactState {
|
|
8
8
|
status: "idle" | "success" | "error";
|
|
@@ -19,6 +19,9 @@ export async function submitContact(
|
|
|
19
19
|
const field = (formData.get("field") as string | null)?.trim() ?? "";
|
|
20
20
|
const message = (formData.get("message") as string | null)?.trim() ?? "";
|
|
21
21
|
const privacyConsent = formData.get("privacyConsent") !== null;
|
|
22
|
+
// 유입 어트리뷰션 (선택) — 클라이언트 폼이 readAttribution() 값을 hidden
|
|
23
|
+
// input(name="attribution")에 JSON 으로 실어 보내면 CRM 에 유입 경로가 표시된다.
|
|
24
|
+
const attribution = parseAttributionJson(formData.get("attribution"));
|
|
22
25
|
|
|
23
26
|
const errors: ContactState["errors"] = {};
|
|
24
27
|
if (!name) errors.name = "이름을 입력해주세요.";
|
|
@@ -40,6 +43,7 @@ export async function submitContact(
|
|
|
40
43
|
consultationField: field || undefined,
|
|
41
44
|
message: message || undefined,
|
|
42
45
|
privacyConsent: true, // 사용자가 명시 동의한 경우에만
|
|
46
|
+
attribution,
|
|
43
47
|
},
|
|
44
48
|
});
|
|
45
49
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roottale/cms-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "RootTale CMS integration MCP server — bundled integration docs, Next.js example code, and public API lookup tools. Run with: npx @roottale/cms-mcp",
|
|
6
6
|
"bin": {
|