dodo-mcp 1.1.0 → 1.2.1
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/README.md +71 -14
- package/dist/cli/main.js +92 -28
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/menu.js +2 -2
- package/dist/cli/menu.js.map +1 -1
- package/dist/config/globalConfig.js +16 -2
- package/dist/config/globalConfig.js.map +1 -1
- package/dist/config/tunnelConfig.js +2 -1
- package/dist/config/tunnelConfig.js.map +1 -1
- package/dist/projects/ownerAdmin.js +86 -0
- package/dist/projects/ownerAdmin.js.map +1 -0
- package/dist/projects/registry.js +90 -9
- package/dist/projects/registry.js.map +1 -1
- package/dist/security/projectAccess.js +69 -0
- package/dist/security/projectAccess.js.map +1 -0
- package/dist/security/projectAuthority.js +5 -1
- package/dist/security/projectAuthority.js.map +1 -1
- package/dist/server/aiAdmin.js +32 -8
- package/dist/server/aiAdmin.js.map +1 -1
- package/dist/server/appServer.js +37 -12
- package/dist/server/appServer.js.map +1 -1
- package/dist/server/bootstrap.js +5 -1
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/configUi/app.css +8 -0
- package/dist/server/configUi/app.js +93 -18
- package/dist/server/configUi/index.html +22 -13
- package/dist/server/configUi/workbench.css +28 -1
- package/dist/server/configUi/workbench.js +113 -18
- package/dist/server/installationRuntime.js +6 -2
- package/dist/server/installationRuntime.js.map +1 -1
- package/dist/server/instructions.js +7 -3
- package/dist/server/instructions.js.map +1 -1
- package/dist/server/ipcDispatch.js.map +1 -1
- package/dist/server/localConfig.js +55 -13
- package/dist/server/localConfig.js.map +1 -1
- package/dist/server/stdioServer.js +14 -3
- package/dist/server/stdioServer.js.map +1 -1
- package/dist/services/ai/subagents.js +1 -1
- package/dist/services/ai/subagents.js.map +1 -1
- package/dist/services/multimodal/storage.js +10 -1
- package/dist/services/multimodal/storage.js.map +1 -1
- package/dist/services/schedules/scheduleService.js +8 -1
- package/dist/services/schedules/scheduleService.js.map +1 -1
- package/dist/store/db.js +14 -0
- package/dist/store/db.js.map +1 -1
- package/dist/tools/agentRuntimeTools.js +2 -3
- package/dist/tools/agentRuntimeTools.js.map +1 -1
- package/dist/tools/context.js +85 -5
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/surface.js +97 -46
- package/dist/tools/surface.js.map +1 -1
- package/dist/tunnel/control.js +11 -4
- package/dist/tunnel/control.js.map +1 -1
- package/dist/tunnel/log.js +32 -0
- package/dist/tunnel/log.js.map +1 -1
- package/dist/tunnel/supervisor.js +103 -24
- package/dist/tunnel/supervisor.js.map +1 -1
- package/docs/AI_PROVIDERS.md +6 -3
- package/docs/ARCHITECTURE.md +18 -6
- package/docs/AUTH.md +6 -0
- package/docs/COMPATIBILITY.md +3 -2
- package/docs/MANUAL_ACCEPTANCE.md +22 -6
- package/docs/PROJECTS.md +73 -2
- package/docs/RELEASE_1.2.0.md +75 -0
- package/docs/RELEASE_1.2.1.md +47 -0
- package/docs/RELEASE_NOTES.md +33 -0
- package/docs/SECURITY.md +37 -6
- package/docs/TEST_REPORT.md +101 -0
- package/docs/TUNNEL.md +79 -16
- package/docs/WEB_CLIENTS.md +6 -1
- package/docs/adr/048-persistent-connection-mode.md +3 -1
- package/docs/adr/050-cloudflare-local-and-project-access.md +67 -0
- package/docs/adr/README.md +1 -0
- package/package.json +3 -1
- package/schemas/global-config.schema.json +11 -0
- package/schemas/tools.compact.json +123 -3
- package/schemas/tools.hybrid.json +297 -3
- package/schemas/tools.json +828 -0
package/docs/PROJECTS.md
CHANGED
|
@@ -7,13 +7,84 @@ project ID แบบ opaque และคงที่เพื่ออ้าง
|
|
|
7
7
|
## คำสั่ง
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
dodo project add /absolute/path/to/project
|
|
11
|
-
dodo project add
|
|
10
|
+
dodo project add /absolute/path/to/project --name "auto-upload" --access full
|
|
11
|
+
dodo project add "C:\\Users\\User\\Desktop\\auto-upload" --name "auto-upload" --access edit
|
|
12
|
+
dodo project access "auto-upload" --mode edit
|
|
12
13
|
dodo project list
|
|
13
14
|
dodo project info prj_xxxxxxxxxxxx
|
|
14
15
|
dodo project remove prj_xxxxxxxxxxxx --yes
|
|
15
16
|
```
|
|
16
17
|
|
|
18
|
+
`dodo project access` รับได้ทั้ง **ชื่อโปรเจกต์** และ project ID เว็บ Local Config
|
|
19
|
+
และ CLI เรียก owner-administration service ตัวเดียวกัน (`src/projects/ownerAdmin.ts`)
|
|
20
|
+
จึงใช้ validation, การยืนยันและ audit ชุดเดียวกัน ไม่มี permission logic แยกสองชุด
|
|
21
|
+
|
|
22
|
+
## Simple Project Access Policy
|
|
23
|
+
|
|
24
|
+
ตอนเพิ่มโปรเจกต์ให้เลือก **ระดับการเข้าถึง** เพียงค่าเดียว:
|
|
25
|
+
|
|
26
|
+
| ระดับ | ความหมาย | OAuth scopes ที่เป็นเพดาน |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `read` | อ่านอย่างเดียว — อ่าน ค้นหา วิเคราะห์ | `dodo:read` |
|
|
29
|
+
| `edit` | แก้ไข — อ่านและแก้ไฟล์ | `dodo:read` + `dodo:write` |
|
|
30
|
+
| `full` | ทำงานเต็มรูปแบบ — อ่าน แก้ไฟล์ และรันคำสั่ง/ทดสอบ | `dodo:read` + `dodo:write` + `dodo:exec` |
|
|
31
|
+
|
|
32
|
+
ระดับนี้เป็น **เพดาน ไม่ใช่การให้สิทธิ์** สิทธิ์จริงคือส่วนที่ทับกันของ
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
OAuth token scopes ∩ grant scopes ∩ (personal ? grant : client ACL ของ workspace) ∩ ระดับของโปรเจกต์
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
ดังนั้น token ที่มีแค่ `dodo:read` จะยังอ่านได้อย่างเดียวแม้โปรเจกต์เป็น `full`
|
|
39
|
+
และโปรเจกต์ `read` ก็เขียนไม่ได้แม้ token จะมี `dodo:write` การเปลี่ยนระดับไม่แตะ
|
|
40
|
+
OAuth, trust, approval, path/secret guards, expected hash, sandbox หรือ audit
|
|
41
|
+
|
|
42
|
+
ใน **โหมดส่วนตัว** (ค่าเริ่มต้น) เพิ่มโปรเจกต์แล้วใช้ได้ทันที ไม่ต้องตั้ง client ACL
|
|
43
|
+
หรือ trust ซ้ำต่อโปรเจกต์ ใน **โหมดแยกสิทธิ์** ยังต้องอนุญาต client ต่อโปรเจกต์ตามเดิม
|
|
44
|
+
และระดับของโปรเจกต์จะบีบให้แคบลงอีกชั้น (ไม่เคยขยาย)
|
|
45
|
+
|
|
46
|
+
### การอัปเกรดจากรุ่นก่อนหน้า
|
|
47
|
+
|
|
48
|
+
โปรเจกต์ที่ลงทะเบียนไว้ก่อนมีนโยบายนี้จะได้ระดับ `full` — เพราะ `full` **ไม่บีบอะไรเพิ่ม**
|
|
49
|
+
สิทธิ์จริงจึงเท่าเดิมทุกประการ (ยังถูกจำกัดด้วย OAuth scopes, client ACL ในโหมดแยกสิทธิ์,
|
|
50
|
+
trust และ guards ทั้งหมด) การบีบให้แคบลงเงียบ ๆ จะเป็นการถอนสิทธิ์ที่เจ้าของไม่ได้สั่ง
|
|
51
|
+
ระดับจะแสดงในหน้า Projects และ `dodo project list` เพื่อให้ลดลงได้เอง
|
|
52
|
+
|
|
53
|
+
## เรียกโปรเจกต์ด้วยชื่อ
|
|
54
|
+
|
|
55
|
+
ชื่อโปรเจกต์ต้องไม่ซ้ำกัน (เทียบแบบไม่สนตัวพิมพ์) เพราะใช้อ้างอิงโปรเจกต์ในการสั่งงาน AI
|
|
56
|
+
|
|
57
|
+
พูดกับ AI ได้ตรง ๆ ว่า **"ใช้ DODO แก้โปรเจกต์ auto-upload"** แล้ว AI จะ:
|
|
58
|
+
|
|
59
|
+
1. เรียก `project_overview` พร้อม `targetProject: "auto-upload"` — DODO resolve ชื่อ
|
|
60
|
+
เป็นโปรเจกต์เดียวที่ client นั้นมีสิทธิ์เห็น
|
|
61
|
+
2. รับ `workspaceId` / `workspaceEpoch` ของโปรเจกต์นั้นกลับมา
|
|
62
|
+
3. ส่ง `targetProject` พร้อม context นั้นไปกับทุก operation ถัดไป
|
|
63
|
+
|
|
64
|
+
```jsonc
|
|
65
|
+
project_overview({ targetProject: "auto-upload" })
|
|
66
|
+
|
|
67
|
+
dodo_write({
|
|
68
|
+
targetProject: "auto-upload",
|
|
69
|
+
workspaceId: "ws_…", workspaceEpoch: "boot_…",
|
|
70
|
+
operation: "edit_file",
|
|
71
|
+
args: { /* … */ }
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
กฎของการ resolve:
|
|
76
|
+
|
|
77
|
+
- เทียบชื่อแบบตัดช่องว่างหัวท้ายและไม่สนตัวพิมพ์
|
|
78
|
+
- ค้นเฉพาะโปรเจกต์ที่ principal นั้นอ่านได้อยู่แล้ว จึงไม่เปิดเผยชื่อหรือ path
|
|
79
|
+
ของโปรเจกต์ที่ไม่มีสิทธิ์
|
|
80
|
+
- ชื่อกำกวม (เช่นข้อมูลเก่าที่ชื่อซ้ำ) → error พร้อมรายชื่อ candidate ที่เห็นได้ ไม่เดา
|
|
81
|
+
- ส่งทั้ง `targetProjectId` และ `targetProject` ที่ชี้คนละโปรเจกต์ → ปฏิเสธ
|
|
82
|
+
- `targetProject` อยู่ระดับบนสุดเท่านั้น ใส่ใน `args` ที่ซ้อนอยู่จะถูกปฏิเสธ
|
|
83
|
+
- หลัง resolve แล้วผ่าน invocation/security pipeline เดิมครบทุกด่าน
|
|
84
|
+
|
|
85
|
+
เจ้าของไม่ต้องรู้หรือพิมพ์ project ID เอง (`targetProjectId` ยังใช้ได้ตามเดิมเพื่อ
|
|
86
|
+
ความเข้ากันได้ย้อนหลัง)
|
|
87
|
+
|
|
17
88
|
ทุกคำสั่งรองรับข้อมูล local owner เท่านั้น `list`, `info` และ `add` รองรับ
|
|
18
89
|
`--json`; `remove` ต้องมี `--yes` หลังตรวจ project ID และ path แล้ว
|
|
19
90
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# DODO MCP 1.2.0
|
|
2
|
+
|
|
3
|
+
รุ่น 1.2.0 แก้ความกำกวมระหว่าง MCP เฉพาะเครื่องกับ `cloudflared` ที่ติดตั้งในเครื่อง
|
|
4
|
+
และนำสิทธิ์ `อ่าน / แก้ไข / เต็ม` กลับมาแสดงในการ์ดของทุกโปรเจกต์
|
|
5
|
+
|
|
6
|
+
## การเชื่อมต่อสามโหมด
|
|
7
|
+
|
|
8
|
+
| หน้าเว็บ | ค่า config | ผู้ดูแล `cloudflared` | ใช้ Tunnel token ใน DODO |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| เฉพาะเครื่อง (Loopback) | `local` | ไม่มี | ไม่ใช้ |
|
|
11
|
+
| Cloudflare Local (ติดตั้งในเครื่อง) | `external` | ผู้ใช้ | ไม่รับและไม่อ่าน |
|
|
12
|
+
| DODO Tunnel | `tunnel` | DODO | write-only ผ่าน OS credential store |
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# AI ในเครื่องเท่านั้น
|
|
16
|
+
dodo tunnel configure --loopback
|
|
17
|
+
|
|
18
|
+
# เจ้าของติดตั้งและรัน cloudflared เอง
|
|
19
|
+
dodo tunnel configure --cloudflare-local --public-url https://mcp.example.com
|
|
20
|
+
|
|
21
|
+
# DODO เริ่มและหยุด cloudflared พร้อมตัวเอง
|
|
22
|
+
dodo tunnel configure --tunnel --public-url https://mcp.example.com --os-credential
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
ทั้ง Cloudflare Local และ DODO Tunnel ใช้ public origin เป็น OAuth issuer/MCP URL
|
|
26
|
+
แต่มีเพียง DODO Tunnel ที่แตะ credential หรือ supervisor Cloudflare Local ไม่อ้างว่า
|
|
27
|
+
connected เพียงเพราะบันทึก URL และ `dodo tunnel doctor` รายงาน process ownership แยก
|
|
28
|
+
จาก public health
|
|
29
|
+
|
|
30
|
+
## สิทธิ์แต่ละโปรเจกต์
|
|
31
|
+
|
|
32
|
+
หน้า **โปรเจกต์** แสดงระดับของแต่ละรายการเสมอ:
|
|
33
|
+
|
|
34
|
+
- `read` — อ่าน ค้นหา วิเคราะห์
|
|
35
|
+
- `edit` — เพิ่มสิทธิ์แก้ไฟล์
|
|
36
|
+
- `full` — เพิ่มสิทธิ์รันคำสั่งและทดสอบ
|
|
37
|
+
|
|
38
|
+
ระดับเป็นเพดานเท่านั้น สิทธิ์จริงยังเป็น intersection ของ OAuth token, live grant,
|
|
39
|
+
managed ACL (เมื่อเปิดโหมด managed) และระดับโปรเจกต์ จึงไม่ทำให้ read-only token เขียน
|
|
40
|
+
ได้ และไม่ข้าม workspace ID/epoch, approval, sandbox, path/secret guards, expected hash,
|
|
41
|
+
idempotency หรือ audit
|
|
42
|
+
|
|
43
|
+
โปรเจกต์เดิม migrate เป็น `full` เพื่อไม่ถอนสิทธิ์เงียบ ๆ เจ้าของลดระดับได้จากการ์ด
|
|
44
|
+
โปรเจกต์หรือ CLI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
dodo project access "ชื่อโปรเจกต์" --mode read
|
|
48
|
+
dodo project access "ชื่อโปรเจกต์" --mode edit
|
|
49
|
+
dodo project access "ชื่อโปรเจกต์" --mode full
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## อัปเดต
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install -g dodo-mcp@1.2.0
|
|
56
|
+
dodo --version
|
|
57
|
+
dodo start
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
หลังอัปเดตให้ restart DODO ค่า connection mode หรือ public origin ที่เปลี่ยนจากหน้าเว็บ
|
|
61
|
+
ไม่มีผลกับ process เดิมจนกว่าจะ restart
|
|
62
|
+
|
|
63
|
+
## ผลตรวจรับ
|
|
64
|
+
|
|
65
|
+
- typecheck/lint: `AUTOMATED_PASS`
|
|
66
|
+
- focused connection/project/OAuth/security/Chromium tests: `AUTOMATED_PASS` —
|
|
67
|
+
92 passed, 1 skipped, 0 failed
|
|
68
|
+
- core/integration/security/compatibility: `AUTOMATED_PASS` — 726 passed,
|
|
69
|
+
35 skipped, 0 failed
|
|
70
|
+
- packaging: `AUTOMATED_PASS` — 16/16
|
|
71
|
+
- production dependency audit: `AUTOMATED_PASS` — 0 vulnerabilities
|
|
72
|
+
- immutable release gate และ fresh registry install: ดูผลล่าสุดใน
|
|
73
|
+
[TEST_REPORT.md](TEST_REPORT.md) (ยังไม่อ้างว่าผ่านจนกว่าจะ publish/verify จริง)
|
|
74
|
+
- Cloudflare Local ผ่าน public hostname จริง: `MANUAL_NOT_RUN`
|
|
75
|
+
- DODO Tunnel credential/public hostname จริงของ 1.2.0: `MANUAL_NOT_RUN`
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# DODO MCP 1.2.1
|
|
2
|
+
|
|
3
|
+
รุ่น 1.2.1 แก้ปัญหาหน้า Providers & Profiles ตอบเพียง `invalid request` เมื่อข้อมูล
|
|
4
|
+
Agent Profile ไม่ครบ ลดขั้นตอนสร้าง Agent สำหรับการใช้งานส่วนตัว และเพิ่มการเลือก
|
|
5
|
+
operation ที่ AI มองเห็นจากหน้าเว็บ
|
|
6
|
+
|
|
7
|
+
## สร้าง Agent แบบง่าย
|
|
8
|
+
|
|
9
|
+
1. บันทึก Provider connection และ API key
|
|
10
|
+
2. กด **โหลดรายชื่อโมเดล** หรือกรอก Model ID เอง
|
|
11
|
+
3. เลือกประเภท Agent: Coding, Review หรือ Research
|
|
12
|
+
4. กด **สร้าง Agent**
|
|
13
|
+
|
|
14
|
+
รายการโมเดลที่โหลดสำเร็จจะเข้า Agent form ทันที ถ้ามีโมเดลเดียว DODO เลือกให้
|
|
15
|
+
อัตโนมัติ ค่าที่ใช้ไม่บ่อย เช่น tool calling, ภาพ, token limits, จำนวนรอบ และราคา
|
|
16
|
+
อยู่ในส่วน **ตั้งค่าขั้นสูง**
|
|
17
|
+
|
|
18
|
+
Preset เป็นเพียงค่าตั้งต้นของ profile และทำได้เฉพาะลดขอบเขตจากสิทธิ์จริง ไม่เพิ่ม
|
|
19
|
+
OAuth scope, project access, trust หรือ approval และไม่ข้าม sandbox, path/secret
|
|
20
|
+
guards, expected hash หรือ audit
|
|
21
|
+
|
|
22
|
+
## Validation
|
|
23
|
+
|
|
24
|
+
- Browser ปฏิเสธ Agent ที่ไม่มีชื่อ, connection หรือ Model ID ก่อนส่ง request
|
|
25
|
+
- ตัวเลขทุกช่องตรวจช่วงเดียวกับ backend
|
|
26
|
+
- Backend ตอบชื่อ field ที่ผิด เช่น `model` โดยไม่สะท้อนค่าที่กรอกหรือ credential
|
|
27
|
+
- ปุ่มถูกปิดระหว่างบันทึกเพื่อป้องกันการสร้างซ้ำ
|
|
28
|
+
|
|
29
|
+
## Tool visibility
|
|
30
|
+
|
|
31
|
+
หน้า **Settings → Tools ที่ AI มองเห็น** มีสวิตช์ราย operation, ค้นหา, เปิด/ปิดทั้งหมวด
|
|
32
|
+
และตัวนับสถานะจริง เมื่อบันทึกแล้ว Compact/Hybrid จะตัด operation ออกจาก discover,
|
|
33
|
+
gateway schema และ direct duplicate ใน Hybrid หลัง restart/rescan หากปิดทั้งหมวด gateway
|
|
34
|
+
นั้นจะหายด้วย Full/STDIO ยังคงครบและ security checks เดิมไม่เปลี่ยน
|
|
35
|
+
|
|
36
|
+
## สถานะตรวจรับ
|
|
37
|
+
|
|
38
|
+
- Typecheck/lint: `AUTOMATED_PASS`
|
|
39
|
+
- Chromium end-to-end แบบ desktop และ 390px: `AUTOMATED_PASS`
|
|
40
|
+
- Provider/profile/project/agent/tool-call/write-file flow: `AUTOMATED_PASS`
|
|
41
|
+
- Tool visibility catalog/HTTP/security/Chromium (desktop และ 320px): `AUTOMATED_PASS`
|
|
42
|
+
- Full suite: 731 passed, 35 skipped; packaging 16/16: `AUTOMATED_PASS`
|
|
43
|
+
- Security regression ที่เกี่ยวข้อง: `AUTOMATED_PASS`
|
|
44
|
+
- Exact tarball install + config schema/UI asset manifest: `AUTOMATED_PASS`
|
|
45
|
+
- Production dependency audit: 0 vulnerabilities: `AUTOMATED_PASS`
|
|
46
|
+
- Live provider ของเจ้าของ: `MANUAL_NOT_RUN`
|
|
47
|
+
- npm publish: `MANUAL_NOT_RUN`
|
package/docs/RELEASE_NOTES.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# DODO MCP — Release Notes
|
|
2
2
|
|
|
3
|
+
## 1.2.1 — สร้าง Agent แบบง่ายและ error ที่แก้ได้ตรงจุด
|
|
4
|
+
|
|
5
|
+
- ลดขั้นตอนสร้าง Agent เหลือเลือกประเภท, Provider connection และ Model ID แล้วสร้างได้เลย
|
|
6
|
+
- รายชื่อโมเดลที่โหลดจาก Provider ถูกนำมาให้เลือกใน Agent form ทันที; endpoint ที่ไม่มี
|
|
7
|
+
model-list ยังพิมพ์ Model ID เองได้
|
|
8
|
+
- เพิ่ม Coding, Review และ Research presets โดยค่าละเอียดอยู่ในส่วนพับได้
|
|
9
|
+
- ตรวจ Model ID, connection และขีดจำกัดตัวเลขใน browser ก่อนส่ง จึงไม่เหลือข้อความ
|
|
10
|
+
`invalid request` แบบไม่บอกสาเหตุสำหรับกรณีข้อมูลฟอร์มไม่ครบ
|
|
11
|
+
- Owner API คืนเฉพาะชื่อ field ที่ไม่ถูกต้อง ไม่สะท้อน API key หรือค่าที่ผู้ใช้กรอก
|
|
12
|
+
- เพิ่มหน้า Settings สำหรับเปิด/ปิด operation รายตัวใน Compact/Hybrid พร้อมค้นหา,
|
|
13
|
+
สวิตช์รายรายการ, เปิด/ปิดทั้งหมวด และตัวนับที่มีผลจริง
|
|
14
|
+
- operation ที่ปิดหายจาก `dodo_discover`, gateway enum และ Hybrid direct duplicate;
|
|
15
|
+
gateway ที่ว่างจะไม่ถูกส่งให้ client ส่วน Full/STDIO ไม่เปลี่ยน
|
|
16
|
+
- การตั้งค่านี้เปลี่ยนเฉพาะ visibility ไม่ grant OAuth scope, project access, trust,
|
|
17
|
+
approval, sandbox หรือข้าม guards และต้อง restart/rescan หลังบันทึก
|
|
18
|
+
|
|
19
|
+
รุ่นนี้เตรียมเป็น patch `1.2.1`; การ publish และ live-provider manual test เป็น gate แยก
|
|
20
|
+
|
|
21
|
+
## 1.2.0 — Cloudflare Local และสิทธิ์ต่อโปรเจกต์ที่มองเห็นได้
|
|
22
|
+
|
|
23
|
+
- แยกการเชื่อมต่อเป็นสามโหมด: เฉพาะเครื่อง (Loopback), Cloudflare Local ที่ผู้ใช้
|
|
24
|
+
รัน `cloudflared` เอง และ DODO Tunnel ที่ DODO ดูแล process
|
|
25
|
+
- Cloudflare Local ใช้ public MCP/OAuth URL โดยไม่รับ/อ่าน Tunnel token และไม่รายงาน
|
|
26
|
+
supervisor connected จาก config อย่างเดียว
|
|
27
|
+
- หน้า Projects แสดงและบันทึกระดับ `read` / `edit` / `full` ของทุกโปรเจกต์จริง
|
|
28
|
+
ในโหมดส่วนตัว ไม่ต้องตามหา Trust/Client ACL หลายส่วน
|
|
29
|
+
- ระดับโปรเจกต์เป็นเพดานที่ intersect กับ OAuth/grant/managed ACL เท่านั้น ไม่เพิ่ม
|
|
30
|
+
สิทธิ์ ไม่ข้าม approval, sandbox, workspace context หรือ file guards
|
|
31
|
+
- Remote Config เปิดผ่าน public Cloudflare ได้ทั้ง owner-managed และ DODO-owned mode;
|
|
32
|
+
loopback-only ยังคงปฏิเสธ
|
|
33
|
+
|
|
34
|
+
ติดตั้งด้วย `npm install -g dodo-mcp@1.2.0` แล้ว restart DODO
|
|
35
|
+
|
|
3
36
|
## 1.1.0 — Android device tools through owner-approved ADB
|
|
4
37
|
|
|
5
38
|
- เพิ่ม Full 13 `android_*` operations และ Compact `dodo_mobile` gateway สำหรับ
|
package/docs/SECURITY.md
CHANGED
|
@@ -67,6 +67,20 @@ Launcher mode ไม่มี active AI workspace และไม่ใช้ CW
|
|
|
67
67
|
private inert root ไม่ถูกแสดงต่อ client; OAuth และ authenticated catalog เปิดให้ตั้ง
|
|
68
68
|
connection ได้ โหมดส่วนตัวซึ่งเป็นค่าเริ่มต้นอนุญาต owner-approved OAuth installation
|
|
69
69
|
ให้ใช้ target ที่ owner ลงทะเบียนตาม token/profile scopes โดยไม่ต้องสร้าง ACL ซ้ำ
|
|
70
|
+
Simple Project Access Policy เพิ่มเพดานอีกหนึ่งชั้นต่อโปรเจกต์ (`read`/`edit`/`full` →
|
|
71
|
+
`dodo:read` / `+dodo:write` / `+dodo:exec`) บังคับที่จุดเดียวใน
|
|
72
|
+
`src/security/projectAuthority.ts` โดย intersect กับ token scopes, grant scopes และ
|
|
73
|
+
client ACL สิทธิ์จริงจึงเป็นส่วนที่ทับกันทั้งหมด ระดับนี้ **บีบได้อย่างเดียว ไม่เคยขยาย**:
|
|
74
|
+
token ที่มีแค่ `dodo:read` ยังเขียนหรือ exec ไม่ได้แม้โปรเจกต์เป็น `full` workspace ที่
|
|
75
|
+
ไม่ได้อยู่ใน registry (launcher root, stdio cwd) ไม่ถูกบีบเพิ่ม และค่าที่อ่านไม่ออกจะถูก
|
|
76
|
+
ตีเป็น `read` (fail closed) การเพิ่มโปรเจกต์กับการตั้งระดับ commit ใน transaction เดียว
|
|
77
|
+
จึงไม่มีโปรเจกต์ที่ลงทะเบียนครึ่งเดียว
|
|
78
|
+
|
|
79
|
+
`targetProject` (ชื่อโปรเจกต์) route เหมือน `targetProjectId` ทุกประการ: resolve ก่อน
|
|
80
|
+
เข้า pipeline, ค้นเฉพาะโปรเจกต์ที่ principal อ่านได้อยู่แล้ว (ไม่เปิดเผยโปรเจกต์ที่ไม่มีสิทธิ์),
|
|
81
|
+
ชื่อกำกวมหรือ id/ชื่อขัดกันถูกปฏิเสธ, รับเฉพาะ top level และถูกปฏิเสธใน nested args
|
|
82
|
+
ผ่านรายการ routing key ชุดเดียวกัน (`ROUTING_CONTEXT_KEYS`) ทุก dispatcher
|
|
83
|
+
|
|
70
84
|
โหมด managed ต้องมี target ACL แยกตามเดิม Mutation จาก Local Config ยังผูกกับ current control context
|
|
71
85
|
workspace/epoch การเลือก startup project เป็น preference เท่านั้นและไม่คัดลอก trust,
|
|
72
86
|
OAuth grant, client ACL, approval, jobs หรือ workspace epoch
|
|
@@ -220,6 +234,16 @@ Full จะไม่ register สี่ Sub-agent definitions และ Compact/
|
|
|
220
234
|
ไม่เปลี่ยน trust/profile policy และไม่ข้าม approvals, sandbox, path/secret guards หรือ
|
|
221
235
|
workspace context ทุก call ที่เปิดให้เห็นยังผ่าน invocation pipeline เดิมทั้งหมด
|
|
222
236
|
|
|
237
|
+
### Per-operation Compact/Hybrid visibility
|
|
238
|
+
|
|
239
|
+
`disabledDiscoverOperations` เป็นการตั้งค่าของเจ้าของใน private Local Config และมีผล
|
|
240
|
+
เฉพาะ Compact/Hybrid catalog operation ที่ปิดจะไม่อยู่ใน `dodo_discover`, gateway enum
|
|
241
|
+
หรือ direct duplicate ของ Hybrid และ gateway ที่ไม่เหลือ operation จะไม่ถูก register
|
|
242
|
+
Full/STDIO direct definitions ไม่ถูกลบด้วยค่านี้ รายชื่อที่บันทึกต้องตรงกับ operation
|
|
243
|
+
จริงและ owner API ปฏิเสธชื่ออื่น การซ่อนหรือเปิดกลับไม่ grant OAuth scope, project ACL,
|
|
244
|
+
trust, approval, sandbox หรือสิทธิ์อื่น และ target ที่ยังเปิดอยู่ผ่าน invocation pipeline
|
|
245
|
+
เดิมทุกชั้น
|
|
246
|
+
|
|
223
247
|
## Android / ADB access
|
|
224
248
|
|
|
225
249
|
ADB ปิดโดยค่าเริ่มต้น การมี `adb` หรืออุปกรณ์ที่เชื่อมอยู่ไม่ใช่ permission เจ้าของต้อง
|
|
@@ -241,10 +265,16 @@ device-side shell สามารถเปลี่ยนข้อมูลด
|
|
|
241
265
|
## Cloudflare Tunnel
|
|
242
266
|
|
|
243
267
|
เจ้าของเป็นผู้สร้าง remotely-managed Tunnel, hostname และ DNS DODO ไม่ใช้ Cloudflare
|
|
244
|
-
API DODO บันทึกการเลือกแบบ exclusive
|
|
245
|
-
|
|
246
|
-
process
|
|
247
|
-
|
|
268
|
+
API DODO บันทึกการเลือกแบบ exclusive หนึ่งค่าใน private global config: `local` คือ
|
|
269
|
+
loopback-only, `external` คือ Cloudflare Local ที่เจ้าของรัน `cloudflared` เอง และ
|
|
270
|
+
`tunnel` คือ DODO-owned process เฉพาะ `tunnel` เท่านั้นที่ DODO อ่าน credential,
|
|
271
|
+
เริ่ม child, ตรวจ readiness และหยุด child พร้อม DODO หาก credential/readiness ไม่พร้อม
|
|
272
|
+
startup จะ fail closed และไม่ fallback ไปโหมดอื่น
|
|
273
|
+
|
|
274
|
+
ใน `external` DODO ใช้ public HTTPS origin เป็น OAuth issuer/MCP URL แต่ไม่รับ token,
|
|
275
|
+
ไม่ค้น process และไม่อ้างว่า Tunnel connected จากค่า config เพียงอย่างเดียว เจ้าของ
|
|
276
|
+
ต้องดูแล process และ route เอง `dodo tunnel doctor` แยก public health ออกจาก process
|
|
277
|
+
ownership และ public health ไม่ใช่หลักฐานว่า AI client เชื่อมอยู่
|
|
248
278
|
|
|
249
279
|
Token ถูกเก็บใน macOS Keychain, Windows Credential Manager หรือ Linux Secret Service
|
|
250
280
|
เมื่อใช้ `--os-credential`; config เก็บ opaque locator เท่านั้น Owner-controlled
|
|
@@ -253,11 +283,12 @@ headless deployment อาจเลือก env/private-file reference โด
|
|
|
253
283
|
browser storage หรือ setup receipt ค่า `TUNNEL_TOKEN` และ `TUNNEL_TOKEN_FILE` ถูก
|
|
254
284
|
ปฏิเสธจาก environment ของ MCP jobs เสมอ
|
|
255
285
|
|
|
256
|
-
Local Config รับ token แบบ write-only
|
|
286
|
+
Local Config รับ token แบบ write-only เฉพาะเมื่อเลือก DODO Tunnel และ POST ผ่าน private capability,
|
|
257
287
|
Host/Origin/proxy checks, rate limit และ control-context headers จากนั้นส่งตรงไปยัง
|
|
258
288
|
reviewed OS credential provider และล้าง request field Response/config/audit ส่งกลับ
|
|
259
289
|
เฉพาะ credential presence/provider ไม่มี MCP tool สำหรับส่ง token, เปลี่ยน connection
|
|
260
|
-
mode หรือควบคุม owner Tunnel
|
|
290
|
+
mode หรือควบคุม owner Tunnel การเลือก Cloudflare Local จะปิดช่อง token และ backend
|
|
291
|
+
ไม่รับหรืออ่าน credential สำหรับโหมดนั้น
|
|
261
292
|
|
|
262
293
|
Tunnel route ต้องชี้ทุก public path ไป MCP/OAuth listener `127.0.0.1:21730` เท่านั้น
|
|
263
294
|
Local Config `21731`, metrics `21732` และ private IPC ไม่ถูก expose `/config` ที่
|
package/docs/TEST_REPORT.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# DODO MCP — Test Report
|
|
2
2
|
|
|
3
|
+
## 1.2.1 Agent Profile creation and Compact/Hybrid visibility controls
|
|
4
|
+
|
|
5
|
+
วันที่ตรวจ: 2026-09-16
|
|
6
|
+
|
|
7
|
+
- Root cause reproduction: Agent form ส่ง `model: ""` หรือค่าตัวเลขที่ไม่ผ่าน schema
|
|
8
|
+
แล้ว owner API ตอบเพียง `invalid request fields`
|
|
9
|
+
- Chromium real UI: ตรวจ Model ID ว่างก่อนส่ง, backend ระบุ field `model`, โหลด model
|
|
10
|
+
fixture แล้วเลือกให้อัตโนมัติ, สร้าง Coding Agent, ทดสอบ tool calling, สร้างไฟล์จริง
|
|
11
|
+
และอ่านผลกลับ — `AUTOMATED_PASS`
|
|
12
|
+
- Responsive: desktop 1440px และ mobile 390px ไม่มี horizontal overflow —
|
|
13
|
+
`AUTOMATED_PASS`
|
|
14
|
+
- Per-operation visibility: ปิด `write_file` แล้วหายจาก discover, gateway enum และ
|
|
15
|
+
Hybrid direct duplicate; ปิด `git_commit` แล้ว gateway ที่ว่างหาย; Full ยังครบ —
|
|
16
|
+
`AUTOMATED_PASS`
|
|
17
|
+
- Owner-only API ปฏิเสธ unauthenticated/stale/unknown operation และบันทึกรายการแบบ
|
|
18
|
+
canonical; public MCP ไม่มี admin route — `AUTOMATED_PASS`
|
|
19
|
+
- Chromium real UI: สวิตช์ราย operation, search, เปิด/ปิดทั้งหมวด, restart notice,
|
|
20
|
+
desktop 1280px และ 320px ไม่มี horizontal overflow — `AUTOMATED_PASS`
|
|
21
|
+
- Focused catalog/HTTP/security/UI suites: 40/40 — `AUTOMATED_PASS`
|
|
22
|
+
- `npm run test:all`: 107 files passed, 3 skipped; 731 tests passed, 35 skipped;
|
|
23
|
+
packaging 16/16 — `AUTOMATED_PASS`
|
|
24
|
+
- `npm audit --omit=dev`: 0 vulnerabilities — `AUTOMATED_PASS`
|
|
25
|
+
- Fresh immutable tarball smoke: CLI 1.2.1, generated config schema และ Local Config
|
|
26
|
+
UI assets ครบ — `AUTOMATED_PASS`
|
|
27
|
+
- Live owner provider credentials: `MANUAL_NOT_RUN`
|
|
28
|
+
- npm publish: `MANUAL_NOT_RUN`
|
|
29
|
+
|
|
30
|
+
## Release 1.2.0 — Cloudflare Local และ Simple Project Access
|
|
31
|
+
|
|
32
|
+
ผล candidate บน macOS arm64 วันที่ 2026-09-16:
|
|
33
|
+
|
|
34
|
+
- build: **AUTOMATED_PASS** — Complete Full 138, live Full default 134, Compact 20,
|
|
35
|
+
Hybrid 49 และ config schemas 2 ชุด
|
|
36
|
+
- typecheck/lint: **AUTOMATED_PASS**
|
|
37
|
+
- core/integration/security/compatibility: **AUTOMATED_PASS** — 726 passed /
|
|
38
|
+
35 skipped / 0 failed ใน 107 ไฟล์ที่ผ่านและ 3 ไฟล์ที่ skip
|
|
39
|
+
- packaging: **AUTOMATED_PASS** — 16/16 รวม release document, ADR, generated UI
|
|
40
|
+
assets และ fresh tarball checks ตาม manifest
|
|
41
|
+
- focused connection/project/OAuth/security/Chromium: **AUTOMATED_PASS** — 92 passed,
|
|
42
|
+
1 skipped, 0 failed; ทดสอบสาม connection modes, write-only credential boundary,
|
|
43
|
+
Remote Config ผ่าน owner-managed public mode, per-project `read/edit/full`,
|
|
44
|
+
project-name routing และ real browser UI
|
|
45
|
+
- production dependency audit: **AUTOMATED_PASS** — 0 vulnerabilities
|
|
46
|
+
- Cloudflare Local ผ่าน public hostname/process จริงของเจ้าของ: **MANUAL_NOT_RUN**
|
|
47
|
+
- DODO Tunnel credential store/readiness ผ่าน public hostname จริงของ 1.2.0:
|
|
48
|
+
**MANUAL_NOT_RUN**
|
|
49
|
+
|
|
50
|
+
Regression รอบแรกพบ security fixture คาด marker `Project Registry` ที่หายจากหัวข้อไทย
|
|
51
|
+
จึงคืน marker ใน UI แล้วรัน focused และ full suite ใหม่จนผ่าน ไม่ได้ลด assertion
|
|
52
|
+
หรือ security requirement
|
|
53
|
+
|
|
3
54
|
## Release 1.1.0 — Android ADB tool family
|
|
4
55
|
|
|
5
56
|
ผล candidate บน macOS วันที่ 2026-09-16:
|
|
@@ -96,6 +147,56 @@ Hybrid 49 tools; `npm run test:all` ผ่าน core/security/compatibility 99
|
|
|
96
147
|
Live Cloudflare hostname และ OS credential store ด้วย credential ของเจ้าของสำหรับ source
|
|
97
148
|
นี้: **MANUAL_NOT_RUN** — ไม่ถือว่า fixture cloudflared เป็นหลักฐานของ public network จริง
|
|
98
149
|
|
|
150
|
+
## Pre-release project access, project names and tunnel readiness — 2026-09-16
|
|
151
|
+
|
|
152
|
+
หลักฐานชุดนี้สร้างก่อนรวมเข้า 1.2.0 งานรอบนี้: Simple Project Access Policy (read/edit/full),
|
|
153
|
+
เรียกโปรเจกต์ด้วยชื่อ (`targetProject`), แก้ข้อความที่บังคับ ACL ในโหมดส่วนตัว และแก้
|
|
154
|
+
Cloudflare readiness ที่สถานะกระพริบ
|
|
155
|
+
|
|
156
|
+
**รันจริงบน macOS arm64, Node v22.23.2:**
|
|
157
|
+
|
|
158
|
+
- `npm run typecheck` / `npm run lint` / `npm run build` — **AUTOMATED_PASS** (exit 0)
|
|
159
|
+
- `npm run test:all` — **AUTOMATED_PASS**: 705 passed / 34 skipped / 0 failed (106 ไฟล์)
|
|
160
|
+
+ packaging 16/16
|
|
161
|
+
- `npx vitest run tests/security/projectAccessLevel.test.ts` (ใหม่, 11 ข้อ) —
|
|
162
|
+
**AUTOMATED_PASS**: mapping ระดับ→scope, `full` token ถูกบีบตามระดับ, token `read`
|
|
163
|
+
เขียน/exec ไม่ได้แม้โปรเจกต์ `full`, managed mode ยังต้องมี ACL แล้วระดับบีบซ้ำ,
|
|
164
|
+
workspace ที่ไม่ได้ลงทะเบียนไม่ถูกบีบ, ค่าที่อ่านไม่ออก → `read` (fail closed),
|
|
165
|
+
row เก่า migrate เป็น `full` (ไม่ถอนสิทธิ์), ระดับผิด → ไม่มีโปรเจกต์ค้าง,
|
|
166
|
+
ชื่อซ้ำถูกปฏิเสธแบบไม่สนตัวพิมพ์, resolve ชื่อ/ชื่อกำกวม/ชื่อไม่รู้จัก
|
|
167
|
+
- `npx vitest run tests/integration/projectByName.test.ts` (ใหม่) — **AUTOMATED_PASS**
|
|
168
|
+
ผ่าน HTTP + OAuth จริง: route ด้วยชื่อ, เขียนลงโปรเจกต์ถูกตัว, ตัวพิมพ์/ช่องว่างไม่สำคัญ,
|
|
169
|
+
ระดับ `edit` บล็อก exec แล้วยกเป็น `full` ทำได้, ชื่อไม่รู้จัก → NOT_FOUND,
|
|
170
|
+
id+ชื่อขัดกัน → INVALID_INPUT, ชื่อกำกวม → CONFLICT พร้อม candidate,
|
|
171
|
+
`targetProject` ใน nested args ถูกปฏิเสธและไม่มีไฟล์ถูกเขียน
|
|
172
|
+
- `npx vitest run tests/unit/tunnelReadiness.test.ts` (ใหม่, 8 ข้อ) — **AUTOMATED_PASS**:
|
|
173
|
+
probe 200/503/ปิด/ค้าง, ไม่ใช้ socket ซ้ำ (นับ connection = 2), schema รองรับทุก phase,
|
|
174
|
+
state.json รุ่นเก่า parse ได้, ปฏิเสธ field แปลกปลอม
|
|
175
|
+
- `npx vitest run tests/integration/tunnelSupervisor.test.ts` (เพิ่ม 3 ข้อ) —
|
|
176
|
+
**AUTOMATED_PASS** ด้วย fake cloudflared จริง: readiness ตกชั่วคราว → `degraded`
|
|
177
|
+
และ `connected` ยังเป็น true, ไม่มีบรรทัด "is not connected"; ล้มติดกันครบเกณฑ์ →
|
|
178
|
+
`disconnected` แล้ว recover กลับ `connected`; ไม่เคยรายงาน connected โดยไม่มีหลักฐาน
|
|
179
|
+
- `npx vitest run tests/integration/projectAccessUi.test.ts` (ใหม่, 2 ข้อ) —
|
|
180
|
+
**AUTOMATED_PASS** ใน Chromium จริง: เพิ่มโปรเจกต์ครบในหน้าเดียว (path/ชื่อ/ระดับ),
|
|
181
|
+
การ์ดแสดงระดับที่ backend เก็บจริง, เปลี่ยนระดับแล้วยืนยันหลัง backend ตอบ,
|
|
182
|
+
reload ยังเห็นค่าเดิม, ชื่อซ้ำขึ้น error (ไม่ขึ้น success), personal ซ่อนฟอร์ม ACL /
|
|
183
|
+
managed แสดงครบ, 390px ไม่มี horizontal scroll, `pageerror` = 0
|
|
184
|
+
- `npm run test:linux:docker` — **AUTOMATED_PASS** (node v22.23.2, arm64, Chromium)
|
|
185
|
+
- `npm pack` + fresh install จาก tarball — **AUTOMATED_PASS**: 461 ไฟล์, ไม่มี
|
|
186
|
+
state.db/.env/jwks/.sock, `dist/projects/ownerAdmin.js` และ
|
|
187
|
+
`dist/security/projectAccess.js` อยู่ในแพ็กเกจ, และรัน
|
|
188
|
+
`dodo project add --access read` → `dodo project access "auto-upload" --mode full`
|
|
189
|
+
→ `dodo project list` ได้จริงจาก tarball ที่ติดตั้งสด
|
|
190
|
+
- `npm run test:windows` บน macOS — 56 passed / 30 skipped: **ไม่ใช่หลักฐาน Windows**
|
|
191
|
+
(ข้อที่เป็น Windows-only ถูก skip)
|
|
192
|
+
|
|
193
|
+
**MANUAL_NOT_RUN** (ยังไม่มีหลักฐาน):
|
|
194
|
+
- Windows native (windows-ci-02) — ยังไม่ได้รัน รอบนี้แก้สาเหตุที่เป็น Windows-specific
|
|
195
|
+
ไว้แล้ว (event-loop starvation จากการเขียน log, keep-alive socket) แต่ยังไม่มีหลักฐานจริง
|
|
196
|
+
- การยืนยันบน tunnel จริง `https://mcp.baanseriesnow.com/mcp` กับ cloudflared จริง
|
|
197
|
+
(เทสต์ใช้ fake cloudflared ที่ควบคุม `/ready` ได้)
|
|
198
|
+
- การอัปเกรดจาก state ของ 1.0.2/1.0.3 จริง (migration ตรวจด้วย fixture เท่านั้น)
|
|
199
|
+
|
|
99
200
|
## Scope
|
|
100
201
|
|
|
101
202
|
รายงานนี้ใช้กับ DODO MCP 1.0.3 source และแยกผล automated กับ manual อย่างชัดเจน
|
package/docs/TUNNEL.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
# DODO MCP — Local และ
|
|
1
|
+
# DODO MCP — Loopback, Cloudflare Local และ DODO Tunnel
|
|
2
2
|
|
|
3
3
|
DODO มีโหมดเชื่อมต่อระดับ installation เพียงหนึ่งโหมดในแต่ละเวลา:
|
|
4
4
|
|
|
5
|
-
- `local` — ใช้ MCP ที่
|
|
5
|
+
- `local` — **เฉพาะเครื่อง (Loopback)** ใช้ MCP ที่
|
|
6
|
+
`http://127.0.0.1:21730/mcp` และไม่ใช้ Cloudflare
|
|
7
|
+
- `external` — **Cloudflare Local (ติดตั้งในเครื่อง)** เจ้าของติดตั้งและรัน `cloudflared` เอง
|
|
8
|
+
DODO advertise public HTTPS origin แต่ไม่รับ token และไม่เริ่ม/หยุด process
|
|
6
9
|
- `tunnel` — ใช้ public HTTPS origin เป็น MCP URL หลัก และ DODO เริ่ม/หยุด
|
|
7
10
|
`cloudflared` ของตัวเองพร้อมทุก `dodo start`
|
|
8
11
|
|
|
@@ -14,7 +17,7 @@ DODO มีโหมดเชื่อมต่อระดับ installation
|
|
|
14
17
|
|
|
15
18
|
| บริการ | ค่าเริ่มต้น | การเปิดเผย |
|
|
16
19
|
|---|---:|---|
|
|
17
|
-
| MCP + OAuth upstream | `127.0.0.1:21730` |
|
|
20
|
+
| MCP + OAuth upstream | `127.0.0.1:21730` | bind loopback เสมอ; Cloudflare ทั้งสองโหมด route มาที่พอร์ตนี้ |
|
|
18
21
|
| Local Config | `127.0.0.1:21731` | Loopback เท่านั้นเสมอ |
|
|
19
22
|
| Tunnel readiness/metrics | `127.0.0.1:21732` | Loopback เท่านั้นเสมอ |
|
|
20
23
|
|
|
@@ -22,14 +25,14 @@ Cloudflare public hostname ต้อง route **ทุก path** มาที่
|
|
|
22
25
|
`http://127.0.0.1:21730` เพื่อให้ health, OAuth discovery, authorization และ `/mcp`
|
|
23
26
|
ทำงานครบ ห้าม route พอร์ต 21731, 21732, private IPC หรือ debug endpoint ออก public
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
แต่ DODO จะ advertise public HTTPS URL เป็น endpoint ที่มีผล ส่วน Local Config ยังคง
|
|
28
|
+
โหมด Cloudflare ทั้งสองแบบยังต้องมี listener 21730 เป็น private upstream ให้
|
|
29
|
+
`cloudflared` แต่ DODO จะ advertise public HTTPS URL เป็น endpoint ที่มีผล ส่วน Local Config ยังคง
|
|
27
30
|
เข้าผ่าน loopback ยกเว้น bounded `/config` lease ที่เจ้าของเปิดชั่วคราวเอง
|
|
28
31
|
|
|
29
|
-
##
|
|
32
|
+
## เลือกเฉพาะเครื่อง (Loopback)
|
|
30
33
|
|
|
31
34
|
```bash
|
|
32
|
-
dodo tunnel configure --
|
|
35
|
+
dodo tunnel configure --loopback
|
|
33
36
|
dodo start
|
|
34
37
|
```
|
|
35
38
|
|
|
@@ -39,9 +42,30 @@ dodo start
|
|
|
39
42
|
dodo tunnel status
|
|
40
43
|
```
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
Loopback mode ไม่ใช้ public origin และไม่เริ่ม Tunnel หากต้องการกลับไป Cloudflare ต้องเลือก
|
|
43
46
|
ใหม่อย่างชัดเจนด้วยคำสั่งหรือหน้า Local Config แล้ว restart DODO
|
|
44
47
|
|
|
48
|
+
`--local` ยังเป็น alias เดิมของ `--loopback` เพื่อไม่ทำให้สคริปต์เก่าตีความต่างไป
|
|
49
|
+
|
|
50
|
+
## เลือก Cloudflare Local (ติดตั้งในเครื่อง)
|
|
51
|
+
|
|
52
|
+
โหมดนี้ใช้เมื่อผู้ใช้ติดตั้งและรัน `cloudflared` เอง เช่นผ่าน terminal, launchd,
|
|
53
|
+
systemd หรือ Windows Service DODO ไม่ขอ Tunnel token และไม่อ้างว่า process เชื่อมต่อแล้ว
|
|
54
|
+
เพียงเพราะบันทึก public URL
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
dodo tunnel configure \
|
|
58
|
+
--cloudflare-local \
|
|
59
|
+
--public-url https://mcp.example.com
|
|
60
|
+
|
|
61
|
+
# รัน cloudflared ด้วยวิธีที่ผู้ใช้จัดการเอง แล้วจึงเปิด DODO
|
|
62
|
+
dodo start
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Cloudflare ต้อง route ทุก path ไป `http://127.0.0.1:21730` เช่นเดียวกับ DODO Tunnel
|
|
66
|
+
ตรวจปลายทางจริงด้วย `dodo tunnel doctor` ค่า public health ที่ผ่านยืนยันเพียงว่า origin
|
|
67
|
+
ตอบ DODO health ไม่ได้ยืนยันว่ามี AI client เชื่อมอยู่
|
|
68
|
+
|
|
45
69
|
## เลือก DODO Tunnel
|
|
46
70
|
|
|
47
71
|
เจ้าของต้องสร้าง remotely-managed Tunnel, public hostname และ DNS ใน Cloudflare ก่อน
|
|
@@ -89,16 +113,17 @@ CLI argument, config JSON, log, audit, MCP response, browser storage หรื
|
|
|
89
113
|
**การเชื่อมต่อ MCP**:
|
|
90
114
|
|
|
91
115
|
1. ตั้ง Public origin เป็น HTTPS origin ของ Tunnel
|
|
92
|
-
2. เลือก `DODO Tunnel`
|
|
93
|
-
|
|
116
|
+
2. เลือก `Cloudflare Local (ติดตั้งในเครื่อง)` หากจะรัน cloudflared เอง หรือ `DODO Tunnel` หากให้
|
|
117
|
+
DODO ดูแล process
|
|
118
|
+
3. ใส่ Cloudflare Tunnel token เฉพาะ `DODO Tunnel`
|
|
94
119
|
4. กดบันทึกและ restart DODO
|
|
95
120
|
|
|
96
|
-
หรือเลือก `
|
|
121
|
+
หรือเลือก `เฉพาะเครื่อง (Loopback)` แล้วบันทึกและ restart ค่าในหน้าเว็บไม่เปลี่ยน endpoint ของ process
|
|
97
122
|
ที่กำลังรันอยู่ทันที หน้าเว็บจะแสดงสถานะ restart ที่ตรงกับ runtime จริง
|
|
98
123
|
|
|
99
124
|
## Remote Config ไม่เกินหนึ่งชั่วโมง
|
|
100
125
|
|
|
101
|
-
Remote Config
|
|
126
|
+
Remote Config ใช้ได้เมื่อเลือก Cloudflare Local (ติดตั้งในเครื่อง) หรือ DODO Tunnel:
|
|
102
127
|
|
|
103
128
|
```bash
|
|
104
129
|
dodo --web
|
|
@@ -109,6 +134,9 @@ dodo web --status
|
|
|
109
134
|
dodo web --close
|
|
110
135
|
```
|
|
111
136
|
|
|
137
|
+
ในโหมด Cloudflare Local (ติดตั้งในเครื่อง) เจ้าของต้องรัน tunnel และ route ครบเอง ส่วน DODO Tunnel
|
|
138
|
+
จะตรวจว่า supervisor ที่ DODO เป็นเจ้าของกำลังรันก่อนเปิด lease
|
|
139
|
+
|
|
112
140
|
`/config` ตอบ 404 ตามค่าเริ่มต้น คำสั่ง `dodo --web` เปิดหรือเปลี่ยน lease ผ่าน
|
|
113
141
|
authenticated private IPC โดยไม่ restart MCP และไม่รับ Tunnel token ผ่าน IPC URL ไม่มี
|
|
114
142
|
query/fragment secret Pairing code มีอายุสั้นและใช้ได้ครั้งเดียว หลังจับคู่ browser ได้
|
|
@@ -128,10 +156,45 @@ dodo tunnel logs --lines 100
|
|
|
128
156
|
dodo tunnel stop
|
|
129
157
|
```
|
|
130
158
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
159
|
+
### สถานะของ Tunnel (state machine)
|
|
160
|
+
|
|
161
|
+
`phase` ของ supervisor มีค่าเหล่านี้ และเปลี่ยนตามหลักฐานจริงเท่านั้น:
|
|
162
|
+
|
|
163
|
+
| phase | ความหมาย |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `starting` | supervisor เริ่มทำงาน ยังไม่ spawn cloudflared |
|
|
166
|
+
| `connecting` | cloudflared รันแล้ว แต่ยัง **ไม่เคย** มีหลักฐาน readiness |
|
|
167
|
+
| `connected` | `/ready` ตอบ 200 — ต้องมีหลักฐานจริงเท่านั้นจึงแสดงสถานะนี้ |
|
|
168
|
+
| `degraded` | เคย connected แล้ว probe เริ่มล้ม แต่ยังไม่ถึงเกณฑ์ (กำลัง reconnect) |
|
|
169
|
+
| `disconnected` | probe ล้มติดกันครบเกณฑ์ หรือ cloudflared exit |
|
|
170
|
+
| `backoff` | รอ restart แบบมีขอบเขต |
|
|
171
|
+
| `stopping` / `stopped` / `failed` | เจ้าของสั่งหยุด / หยุดแล้ว / restart หมดโควตา |
|
|
172
|
+
|
|
173
|
+
สถานะยังมี `lastReadyAt`, `lastFailureAt` และ `consecutiveReadyFailures` เพื่อให้ดูได้ว่า
|
|
174
|
+
readiness สำเร็จครั้งสุดท้ายเมื่อไร
|
|
175
|
+
|
|
176
|
+
**ทำไมเมื่อก่อนสถานะกระพริบ** — เดิม probe ทุก 1 วินาทีโดย timeout 1.5 วินาที
|
|
177
|
+
จึงซ้อนกันได้ ผลเก่าเขียนทับผลใหม่ และ probe ที่ล้ม **ครั้งเดียว** ก็พลิกสถานะและพิมพ์
|
|
178
|
+
`readiness endpoint is not connected` ทันที ตอนนี้:
|
|
179
|
+
|
|
180
|
+
- probe ทำทีละครั้ง ไม่ซ้อนกัน และมี generation fence ผลจาก child เก่าถูกทิ้ง
|
|
181
|
+
- ต้องล้มติดกันครบเกณฑ์จึงจะเป็น `disconnected` — ล้มครั้งเดียวเป็นแค่ `degraded`
|
|
182
|
+
และ `connected` ยังเป็น true เพื่อไม่ให้ UI กระพริบ
|
|
183
|
+
- ใช้ socket ใหม่ทุกครั้ง (`agent: false`) กัน keep-alive socket ที่ถูกปิดแล้ว
|
|
184
|
+
กลายเป็น error ปลอม
|
|
185
|
+
- เขียน log ของ cloudflared แบบรวมกลุ่ม ไม่เขียนทับไฟล์ 512 KiB ทุกบรรทัด
|
|
186
|
+
(บน Windows การ retry rename ใช้ `Atomics.wait` ซึ่งบล็อก event loop จน probe timeout)
|
|
187
|
+
- cloudflared exit → `disconnected` ทันที, restart มีขอบเขตตาม `maxRestarts` เสมอ
|
|
188
|
+
- ไม่มี fallback เงียบ ๆ จาก tunnel ไป local และ token ไม่ปรากฏใน log หรือ error
|
|
189
|
+
|
|
190
|
+
Tunnel เป็นระดับ installation รองรับทุกโปรเจกต์ การเพิ่มหรือเลือกโปรเจกต์ไม่ restart tunnel
|
|
191
|
+
|
|
192
|
+
`status` ไม่อ่าน credential ส่วน `doctor` ตรวจ executable, local health และ public
|
|
193
|
+
health ทุกโหมด แต่ตรวจ credential/supervisor readiness เฉพาะ DODO Tunnel ใน
|
|
194
|
+
Cloudflare Local รายงาน process ownership เป็น `owner` และไม่ควบคุม process Public
|
|
195
|
+
health ที่ผ่านพิสูจน์เพียงว่า origin ตอบ DODO health ไม่ได้พิสูจน์ว่า AI client
|
|
196
|
+
เชื่อมต่อแล้ว `stop` ส่งสัญญาณเฉพาะ live child handle ที่ DODO supervisor ปัจจุบัน
|
|
197
|
+
สร้าง ไม่ค้นหรือ kill process ตามชื่อ/PID เก่า
|
|
135
198
|
|
|
136
199
|
## ตั้งค่า MCP client
|
|
137
200
|
|