dodo-mcp 1.0.2 → 1.0.3
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 +31 -18
- package/dist/cli/main.js +63 -66
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/menu.js +9 -16
- package/dist/cli/menu.js.map +1 -1
- package/dist/config/globalConfig.js +23 -1
- package/dist/config/globalConfig.js.map +1 -1
- package/dist/config/stateImport.js +2 -2
- package/dist/config/stateImport.js.map +1 -1
- package/dist/config/tunnelConfig.js +2 -3
- package/dist/config/tunnelConfig.js.map +1 -1
- package/dist/server/appServer.js +38 -26
- package/dist/server/appServer.js.map +1 -1
- package/dist/server/configUi/app.js +35 -58
- package/dist/server/configUi/index.html +21 -22
- package/dist/server/localConfig.js +50 -63
- package/dist/server/localConfig.js.map +1 -1
- package/dist/tunnel/control.js +4 -6
- package/dist/tunnel/control.js.map +1 -1
- package/dist/tunnel/credentials.js +5 -19
- package/dist/tunnel/credentials.js.map +1 -1
- package/dist/tunnel/runtime.js +3 -4
- package/dist/tunnel/runtime.js.map +1 -1
- package/dist/tunnel/supervisor.js +8 -10
- package/dist/tunnel/supervisor.js.map +1 -1
- package/docs/AI_PROVIDERS.md +1 -1
- package/docs/ARCHITECTURE.md +14 -14
- package/docs/COMPATIBILITY.md +6 -2
- package/docs/MANUAL_ACCEPTANCE.md +21 -16
- package/docs/RELEASE_1.0.0.md +3 -0
- package/docs/RELEASE_1.0.3.md +57 -0
- package/docs/RELEASE_NOTES.md +19 -0
- package/docs/SECURITY.md +20 -10
- package/docs/TEST_REPORT.md +33 -1
- package/docs/TUNNEL.md +102 -80
- package/docs/WINDOWS.md +1 -1
- package/docs/adr/031-owner-selected-tunnel-supervision.md +8 -2
- package/docs/adr/044-global-launcher-and-cli-menu.md +3 -3
- package/docs/adr/047-temporary-remote-config.md +4 -4
- package/docs/adr/048-persistent-connection-mode.md +58 -0
- package/docs/adr/README.md +1 -0
- package/package.json +2 -1
- package/schemas/global-config.schema.json +6 -12
package/docs/TUNNEL.md
CHANGED
|
@@ -1,51 +1,104 @@
|
|
|
1
|
-
# DODO MCP — Tunnel
|
|
1
|
+
# DODO MCP — Local และ Cloudflare Tunnel
|
|
2
2
|
|
|
3
|
-
DODO
|
|
3
|
+
DODO มีโหมดเชื่อมต่อระดับ installation เพียงหนึ่งโหมดในแต่ละเวลา:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- `local` — ใช้ MCP ที่ `http://127.0.0.1:21730/mcp` และไม่เริ่ม `cloudflared`
|
|
6
|
+
- `tunnel` — ใช้ public HTTPS origin เป็น MCP URL หลัก และ DODO เริ่ม/หยุด
|
|
7
|
+
`cloudflared` ของตัวเองพร้อมทุก `dodo start`
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- managed readiness/metrics: `http://127.0.0.1:21732` โดยค่าเริ่มต้น
|
|
9
|
+
การเลือกจะถูกบันทึกใน private global config และไม่มี fallback อัตโนมัติ หากเลือก
|
|
10
|
+
`tunnel` แล้ว credential, executable หรือ readiness ไม่พร้อม การเริ่ม DODO จะล้มเหลว
|
|
11
|
+
พร้อมคำอธิบาย โดยไม่เปลี่ยนไปเปิด local แทน
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
health, discovery, OAuth และ MCP ทำงานครบ ห้าม route Local Config `21731`, metrics
|
|
14
|
-
`21732`, private IPC หรือ debug endpoint ออก public Namespace `/config` บน `21730`
|
|
15
|
-
ตอบ 404 ตามค่าเริ่มต้นและเปิดได้ชั่วคราวเฉพาะเมื่อเจ้าของสั่งตามหัวข้อถัดไป
|
|
13
|
+
## พอร์ตและขอบเขต
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
| บริการ | ค่าเริ่มต้น | การเปิดเผย |
|
|
16
|
+
|---|---:|---|
|
|
17
|
+
| MCP + OAuth upstream | `127.0.0.1:21730` | Local เท่านั้น; Tunnel route มาที่พอร์ตนี้ |
|
|
18
|
+
| Local Config | `127.0.0.1:21731` | Loopback เท่านั้นเสมอ |
|
|
19
|
+
| Tunnel readiness/metrics | `127.0.0.1:21732` | Loopback เท่านั้นเสมอ |
|
|
20
|
+
|
|
21
|
+
Cloudflare public hostname ต้อง route **ทุก path** มาที่
|
|
22
|
+
`http://127.0.0.1:21730` เพื่อให้ health, OAuth discovery, authorization และ `/mcp`
|
|
23
|
+
ทำงานครบ ห้าม route พอร์ต 21731, 21732, private IPC หรือ debug endpoint ออก public
|
|
24
|
+
|
|
25
|
+
แม้โหมด Tunnel ยังต้องมี listener 21730 เป็น private upstream ให้ `cloudflared`
|
|
26
|
+
แต่ DODO จะ advertise public HTTPS URL เป็น endpoint ที่มีผล ส่วน Local Config ยังคง
|
|
27
|
+
เข้าผ่าน loopback ยกเว้น bounded `/config` lease ที่เจ้าของเปิดชั่วคราวเอง
|
|
28
|
+
|
|
29
|
+
## เลือก Local
|
|
18
30
|
|
|
19
31
|
```bash
|
|
20
|
-
dodo
|
|
21
|
-
dodo start
|
|
32
|
+
dodo tunnel configure --local
|
|
33
|
+
dodo start
|
|
22
34
|
```
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
ตรวจค่าที่ใช้อยู่:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
dodo tunnel status
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Local mode ไม่ใช้ public origin และไม่เริ่ม Tunnel หากต้องการกลับไป Tunnel ต้องเลือก
|
|
43
|
+
ใหม่อย่างชัดเจนด้วยคำสั่งหรือหน้า Local Config แล้ว restart DODO
|
|
44
|
+
|
|
45
|
+
## เลือก DODO Tunnel
|
|
46
|
+
|
|
47
|
+
เจ้าของต้องสร้าง remotely-managed Tunnel, public hostname และ DNS ใน Cloudflare ก่อน
|
|
48
|
+
DODO ไม่สร้าง/ลบ Tunnel, เปลี่ยน DNS, เปิด firewall หรือติดตั้ง system service
|
|
49
|
+
|
|
50
|
+
บน macOS ตรวจหรือติดตั้ง executable ผ่าน setup:
|
|
25
51
|
|
|
26
52
|
```bash
|
|
27
53
|
dodo setup --check --components cloudflared
|
|
28
|
-
dodo
|
|
29
|
-
dodo start --root /path/to/project
|
|
30
|
-
# Cloudflare Tunnel token (temporary; Enter = local only):
|
|
54
|
+
dodo setup --yes --components cloudflared
|
|
31
55
|
```
|
|
32
56
|
|
|
33
|
-
|
|
34
|
-
|
|
57
|
+
จากนั้นเลือก Tunnel และบันทึก token ใน macOS Keychain ผ่าน hidden prompt:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
dodo tunnel configure \
|
|
61
|
+
--tunnel \
|
|
62
|
+
--public-url https://mcp.example.com \
|
|
63
|
+
--os-credential
|
|
64
|
+
|
|
65
|
+
dodo start
|
|
66
|
+
```
|
|
35
67
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
หยุด child จะหยุดตาม กด Enter โดยไม่กรอกหรือใช้คำสั่งต่อไปนี้เพื่อเปิด local MCP เท่านั้น:
|
|
68
|
+
Windows ใช้ Credential Manager และ Linux ใช้ Secret Service เมื่อเลือก
|
|
69
|
+
`--os-credential` สำหรับ headless environment สามารถใช้ owner-controlled reference:
|
|
39
70
|
|
|
40
71
|
```bash
|
|
41
|
-
dodo
|
|
72
|
+
dodo tunnel configure --tunnel --public-url https://mcp.example.com --token-env DODO_OWNER_TUNNEL_TOKEN
|
|
73
|
+
# หรือไฟล์ private regular file ที่เป็น absolute path
|
|
74
|
+
dodo tunnel configure --tunnel --public-url https://mcp.example.com --token-file /private/path/tunnel-token
|
|
42
75
|
```
|
|
43
76
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
77
|
+
ค่า environment/file เป็น reference ที่เจ้าของดูแลเอง คำสั่งตรวจค่าและไฟล์ก่อนบันทึก
|
|
78
|
+
แต่ไม่คัดลอก token เข้า config เมื่อใช้หน้า Local Config token จะเป็น write-only และ
|
|
79
|
+
ถูกส่งตรงไปยัง OS credential store; หลังบันทึก UI แสดงเพียงว่ามี credential
|
|
47
80
|
|
|
48
|
-
|
|
81
|
+
ทุก `dodo start` ใน Tunnel mode จะอ่าน credential จาก reference เริ่ม `cloudflared`
|
|
82
|
+
ผ่าน child environment และรอ readiness ก่อนถือว่า startup สำเร็จ Token ไม่อยู่ใน
|
|
83
|
+
CLI argument, config JSON, log, audit, MCP response, browser storage หรือ environment
|
|
84
|
+
ของ MCP jobs เมื่อ DODO หยุด child ที่ process นี้เป็นเจ้าของจะหยุดตาม
|
|
85
|
+
|
|
86
|
+
## เปลี่ยนโหมดจากหน้าเว็บ
|
|
87
|
+
|
|
88
|
+
เปิด Local Config จาก URL ที่ DODO แสดงบนเครื่องเจ้าของ แล้วใช้ส่วน
|
|
89
|
+
**การเชื่อมต่อ MCP**:
|
|
90
|
+
|
|
91
|
+
1. ตั้ง Public origin เป็น HTTPS origin ของ Tunnel
|
|
92
|
+
2. เลือก `DODO Tunnel`
|
|
93
|
+
3. ใส่ Cloudflare Tunnel token หากยังไม่มี credential ที่บันทึกไว้
|
|
94
|
+
4. กดบันทึกและ restart DODO
|
|
95
|
+
|
|
96
|
+
หรือเลือก `Local` แล้วบันทึกและ restart ค่าในหน้าเว็บไม่เปลี่ยน endpoint ของ process
|
|
97
|
+
ที่กำลังรันอยู่ทันที หน้าเว็บจะแสดงสถานะ restart ที่ตรงกับ runtime จริง
|
|
98
|
+
|
|
99
|
+
## Remote Config ไม่เกินหนึ่งชั่วโมง
|
|
100
|
+
|
|
101
|
+
Remote Config ใช้ได้เฉพาะเมื่อเลือก Tunnel และ DODO-owned Tunnel กำลังรันอยู่:
|
|
49
102
|
|
|
50
103
|
```bash
|
|
51
104
|
dodo --web
|
|
@@ -56,27 +109,17 @@ dodo web --status
|
|
|
56
109
|
dodo web --close
|
|
57
110
|
```
|
|
58
111
|
|
|
59
|
-
`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
URL ไม่มี query/fragment secret ผู้ใช้ต้องกรอก pairing code ที่ terminal แสดง Code
|
|
66
|
-
มีอายุไม่เกิน 10 นาทีและใช้ได้ครั้งเดียว จากนั้น server ออก session cookie ที่เป็น
|
|
67
|
-
`Secure`, `HttpOnly`, `SameSite=Strict` และ `Path=/config` ตัว lease ปิดอัตโนมัติ
|
|
68
|
-
ภายใน 1 ชั่วโมง เมื่อหมดอายุ `/config`, assets และ owner API ใต้ namespace นี้กลับ
|
|
69
|
-
เป็น 404 การรัน `dodo --web` อีกครั้งยกเลิก code/session เดิมและออกชุดใหม่
|
|
70
|
-
|
|
71
|
-
Remote Config เป็น authenticated bridge ไปยัง Local Config เดิม การเขียนทุกครั้งยัง
|
|
72
|
-
ตรวจ workspace ID/epoch, owner validation และ policy ของ Local Config ไม่มี MCP tool
|
|
73
|
-
สำหรับเปิด lease และ `dodo web --close` ปิดเฉพาะหน้าเว็บ โดยไม่หยุด MCP หรือ Tunnel
|
|
112
|
+
`/config` ตอบ 404 ตามค่าเริ่มต้น คำสั่ง `dodo --web` เปิดหรือเปลี่ยน lease ผ่าน
|
|
113
|
+
authenticated private IPC โดยไม่ restart MCP และไม่รับ Tunnel token ผ่าน IPC URL ไม่มี
|
|
114
|
+
query/fragment secret Pairing code มีอายุสั้นและใช้ได้ครั้งเดียว หลังจับคู่ browser ได้
|
|
115
|
+
cookie แบบ `Secure`, `HttpOnly`, `SameSite=Strict`, `Path=/config` Lease ปิดเองภายใน
|
|
116
|
+
หนึ่งชั่วโมง การเปิดใหม่ยกเลิก code/session เดิม
|
|
74
117
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
Remote Config proxy ไปยัง Local Config loopback โดยคง Host/Origin/proxy-header checks,
|
|
119
|
+
private capability, rate limit, workspace ID/epoch และ owner policy เดิม การปิด lease
|
|
120
|
+
ไม่หยุด MCP หรือ Tunnel และไม่มี MCP tool สำหรับเปิดหน้า owner นี้
|
|
78
121
|
|
|
79
|
-
|
|
122
|
+
## ตรวจสถานะและแก้ปัญหา
|
|
80
123
|
|
|
81
124
|
```bash
|
|
82
125
|
dodo tunnel status
|
|
@@ -85,41 +128,20 @@ dodo tunnel logs --lines 100
|
|
|
85
128
|
dodo tunnel stop
|
|
86
129
|
```
|
|
87
130
|
|
|
88
|
-
`status`
|
|
131
|
+
`status` ไม่อ่าน credential ส่วน `doctor` ตรวจ executable, credential, local health,
|
|
132
|
+
Tunnel readiness และ public health แยกกัน Public health ที่ผ่านพิสูจน์เพียงว่า origin
|
|
133
|
+
ตอบ DODO health ไม่ได้พิสูจน์ว่า AI client เชื่อมต่อแล้ว `stop` ส่งสัญญาณเฉพาะ live
|
|
134
|
+
child handle ที่ supervisor ปัจจุบันสร้าง ไม่ค้นหรือ kill process ตามชื่อ/PID เก่า
|
|
89
135
|
|
|
90
|
-
##
|
|
136
|
+
## ตั้งค่า MCP client
|
|
91
137
|
|
|
92
|
-
|
|
93
|
-
มาตรฐานไม่ใช้ macOS Keychain, Windows Credential Manager, Linux Secret Service,
|
|
94
|
-
token file หรือ shell environment Token จาก terminal และ Local Config ถูกส่งผ่าน
|
|
95
|
-
environment ของ child ที่สร้างเองเท่านั้น Tunnel diagnostics ถูกจำกัดขนาดและ redact
|
|
96
|
-
ก่อนเขียนลง private state MCP jobs จะไม่ได้รับ `TUNNEL_TOKEN` หรือ
|
|
97
|
-
`TUNNEL_TOKEN_FILE` แม้ owner จะใส่ชื่อไว้ใน environment allowlist
|
|
98
|
-
|
|
99
|
-
คำสั่ง `dodo tunnel configure/start` และ credential reference รุ่นเดิมยังคงอยู่เพื่อ
|
|
100
|
-
advanced/headless compatibility แต่ไม่ถูกเรียกโดย `dodo start`, `dodo --cli` หรือ
|
|
101
|
-
Local Config และต้องเกิดจากคำสั่ง owner โดยตรง
|
|
102
|
-
|
|
103
|
-
runtime ใช้ bounded restart หลัง `cloudflared` จบ retry ของตัวเอง และ `stop` ส่งสัญญาณเฉพาะ live child handle ที่ supervisor เป็นผู้สร้าง ไม่มีการ kill saved PID หรือ process ชื่อเหมือนกัน
|
|
104
|
-
|
|
105
|
-
## Client setup
|
|
106
|
-
|
|
107
|
-
1. ใช้ `https://mcp.example.com/mcp` ใน MCP client
|
|
138
|
+
1. ใช้ `https://mcp.example.com/mcp`
|
|
108
139
|
2. เลือก OAuth
|
|
109
|
-
3. คัดลอก exact callback จาก client
|
|
110
|
-
4. ลงทะเบียนด้วย `dodo auth add-client --redirect-uri
|
|
111
|
-
5. ทำ browser authorization และ approve interaction จาก terminal
|
|
140
|
+
3. คัดลอก exact callback URL จาก client
|
|
141
|
+
4. ลงทะเบียนด้วย `dodo auth add-client --redirect-uri <exact-callback>`
|
|
142
|
+
5. ทำ browser authorization และ approve interaction จาก owner terminal
|
|
112
143
|
6. scan tools และตรวจ surface ที่ client รายงาน
|
|
113
144
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
explicit target runtimes หลายโปรเจกต์พร้อมกันได้ภายใต้ project registry และ target
|
|
118
|
-
authority เดียวกัน จึงไม่ต้องสร้าง Tunnel แยกต่อโปรเจกต์ งานแต่ละ target ใช้
|
|
119
|
-
workspace identity/epoch, jobs และ mutation queue ของตัวเอง
|
|
120
|
-
|
|
121
|
-
## Security
|
|
122
|
-
|
|
123
|
-
ห้ามปิด OAuth, ใช้ Tunnel token แทน MCP OAuth, ส่ง token/pairing/session ใน URL หรือ
|
|
124
|
-
เปิด CORS กว้าง Tunnel provider ไม่ได้แทน owner consent ของ DODO และ DODO ไม่เรียก
|
|
125
|
-
Cloudflare API, ไม่จัดการ DNS, ไม่สร้าง/ลบ Tunnel และไม่เปิด firewall
|
|
145
|
+
หนึ่ง Tunnel รองรับ project registry ทั้ง installation ไม่ต้องสร้าง Tunnel ต่อโปรเจกต์
|
|
146
|
+
แต่ทุก target ยังตรวจ OAuth identity, target ACL/scopes, workspace identity/epoch,
|
|
147
|
+
trust/approval, path/secret guards, sandbox และ expected hash ตามเดิม
|
package/docs/WINDOWS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DODO Windows Candidate — Deferred
|
|
2
2
|
|
|
3
|
-
DODO MCP 1.0.
|
|
3
|
+
DODO MCP 1.0.3 ยังไม่ประกาศ native Windows support โค้ดและ tests สำหรับ Windows
|
|
4
4
|
บางส่วนมีอยู่เป็น candidate สำหรับ phase สุดท้าย แต่ยังไม่มีหลักฐานจาก Windows 11 จริง
|
|
5
5
|
และ Linux Docker ไม่สามารถใช้แทนหลักฐาน Windows ได้
|
|
6
6
|
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# ADR-031 — Owner-selected Cloudflare Tunnel supervision
|
|
2
2
|
|
|
3
|
-
**Status:**
|
|
3
|
+
**Status:** superseded in credential/lifecycle selection by ADR-048. Process ownership,
|
|
4
|
+
readiness, redaction and bounded-stop decisions remain accepted.
|
|
4
5
|
|
|
5
6
|
**Decision.** DODO starts only an owner-selected, trusted `cloudflared` executable owned by the current HTTP process. `dodo start` can attach it immediately; the authenticated Local Config can start or stop the same process-owned runtime. The owner still creates the remotely-managed Tunnel, public hostname and DNS in Cloudflare.
|
|
6
7
|
|
|
7
|
-
The
|
|
8
|
+
The original flow used a run-scoped token entered through a hidden terminal prompt or
|
|
9
|
+
the authenticated loopback Local Config. ADR-048 replaces that credential flow with one
|
|
10
|
+
persistent Local/Tunnel selection and a reviewed credential reference. The invariant
|
|
11
|
+
retained from this ADR is that a process-owned `TunnelRuntime` forwards the resolved
|
|
12
|
+
credential through the child environment, stops that child with DODO and keeps the
|
|
13
|
+
credential out of argv, logs, MCP, audit and job environments.
|
|
8
14
|
|
|
9
15
|
The supervisor uses a separate authenticated singleton owner IPC endpoint, loopback readiness, bounded restarts, private bounded/redacted logs and live child handles for termination. It never signals a saved PID or searches by process name. Local Config and the metrics listener remain loopback-only and are not part of the public route.
|
|
10
16
|
|
|
@@ -29,9 +29,9 @@ in-flight drain, running-job refusal, resource teardown และ fresh workspac
|
|
|
29
29
|
data plane หากล้มเหลว launcher ยังคงปิด data plane ไม่มี half-switched state
|
|
30
30
|
|
|
31
31
|
`dodo --cli` เป็น terminal menu ที่เรียก owner operations เดิม ไม่ใช่ MCP tool
|
|
32
|
-
เมนูไม่เปลี่ยน OAuth grant, access mode หรือ OS permission
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
เมนูไม่เปลี่ยน OAuth grant, access mode หรือ OS permission เมนูเริ่ม DODO ตาม
|
|
33
|
+
persistent `connectionMode` ที่เจ้าของบันทึกไว้ การเลือก/เก็บ Tunnel credential ใช้
|
|
34
|
+
Local Config หรือ `dodo tunnel configure` ตาม ADR-048 และไม่ผ่าน readline menu/argv
|
|
35
35
|
|
|
36
36
|
STDIO คง contract `dodo stdio --root PATH` เพราะ client เป็นเจ้าของ subprocess
|
|
37
37
|
lifecycle และต้องกำหนด root อย่างชัดเจน
|
|
@@ -25,10 +25,10 @@ and leaves Local Config's workspace/epoch checks, validation, policy and audit a
|
|
|
25
25
|
authority. Pairing never grants MCP scopes, project access, trust or approvals. No MCP
|
|
26
26
|
tool can open the lease.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
ADR-048 supersedes the temporary-token handoff: current source opens Remote Config only
|
|
29
|
+
when the saved connection mode is Tunnel and the DODO-owned Tunnel is already running.
|
|
30
|
+
Owner IPC cannot carry a Tunnel credential or switch the connection mode. Closing or
|
|
31
|
+
expiry still affects only Remote Config; MCP, OAuth and Tunnel continue running.
|
|
32
32
|
|
|
33
33
|
## Consequences
|
|
34
34
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ADR-048 — Persistent exclusive Local/Tunnel connection mode
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted in source; unreleased.
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The prior launch flow asked for a run-scoped Cloudflare Tunnel token each time and could
|
|
10
|
+
start locally when the owner omitted it. That made the advertised endpoint depend on an
|
|
11
|
+
interactive answer and allowed a configuration mistake to change the connection path.
|
|
12
|
+
Owners need one installation-wide choice: always use the DODO Tunnel or always use the
|
|
13
|
+
local endpoint until they explicitly change it.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
Global owner config stores one authoritative `connectionMode`: `local` or `tunnel`.
|
|
18
|
+
Legacy `mode` and `startWithDodo` fields are accepted only during load-time migration
|
|
19
|
+
and are removed from newly saved config.
|
|
20
|
+
|
|
21
|
+
In Local mode DODO advertises `http://127.0.0.1:<port>/mcp`, uses the loopback origin as
|
|
22
|
+
its OAuth issuer/resource and never starts `cloudflared`. In Tunnel mode DODO advertises
|
|
23
|
+
the configured public HTTPS origin, starts one process-owned supervisor on every
|
|
24
|
+
`dodo start`, waits for readiness and stops that child with DODO. Missing credentials,
|
|
25
|
+
executable failure or readiness failure aborts startup; there is no Local fallback.
|
|
26
|
+
|
|
27
|
+
The standard credential path is a reviewed OS store: macOS Keychain, Windows Credential
|
|
28
|
+
Manager or Linux Secret Service. Global config stores only an opaque reference. Explicit
|
|
29
|
+
environment/private-file references remain for owner-controlled headless deployments.
|
|
30
|
+
The token reaches `cloudflared` through its dedicated child environment and never enters
|
|
31
|
+
argv, config, logs, audit, browser storage, MCP output or MCP-job environments.
|
|
32
|
+
|
|
33
|
+
Local Config may select the mode and accept a write-only token after its existing owner,
|
|
34
|
+
Host, Origin, proxy-header, rate and workspace-context checks. The backend writes it to
|
|
35
|
+
the OS store and returns only presence/provider. A saved change requires restart and the
|
|
36
|
+
UI distinguishes saved mode from the active runtime endpoint.
|
|
37
|
+
|
|
38
|
+
Remote Config remains a bounded one-hour `/config` lease. It is available only while
|
|
39
|
+
Tunnel mode and the DODO-owned supervisor are active. Installation IPC cannot transmit a
|
|
40
|
+
Tunnel token or change mode, and public MCP routes expose no owner control operation.
|
|
41
|
+
|
|
42
|
+
## Consequences
|
|
43
|
+
|
|
44
|
+
- Startup and endpoint selection are deterministic and auditable.
|
|
45
|
+
- Tunnel mode fails closed instead of silently changing how clients reach DODO.
|
|
46
|
+
- Credential unlock may still require an owner/OS interaction at startup.
|
|
47
|
+
- The loopback MCP listener remains present as the private Tunnel upstream, but the
|
|
48
|
+
public URL is the only advertised active MCP endpoint in Tunnel mode.
|
|
49
|
+
- Switching modes or public origin requires a DODO restart and client reconnect/rescan.
|
|
50
|
+
|
|
51
|
+
## Evidence
|
|
52
|
+
|
|
53
|
+
- `tests/integration/connectionMode.test.ts`
|
|
54
|
+
- `tests/security/tunnelCredentials.test.ts`
|
|
55
|
+
- `tests/security/localConfig.test.ts`
|
|
56
|
+
- `tests/integration/tunnelSupervisor.test.ts`
|
|
57
|
+
- `tests/security/remoteConfig.test.ts`
|
|
58
|
+
- `tests/integration/remoteConfigUi.test.ts`
|
package/docs/adr/README.md
CHANGED
|
@@ -63,3 +63,4 @@ decisions; ADR-011+ resolve implementation ambiguities without reducing security
|
|
|
63
63
|
- [045 — Explicit project runtimes and provider-backed sub-agents](045-ai-providers-multiproject.md)
|
|
64
64
|
- [046 — Personal add-and-use mode](046-personal-access-mode.md)
|
|
65
65
|
- [047 — Temporary Remote Config on the tunneled listener](047-temporary-remote-config.md)
|
|
66
|
+
- [048 — Persistent exclusive Local/Tunnel connection mode](048-persistent-connection-mode.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dodo-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"author": "Arthittakun",
|
|
5
5
|
"description": "DODO — local-first MCP server with multi-project coding, AI providers, sub-agents, context, memory, media and workflow tools; embedded OAuth and workspace permissions.",
|
|
6
6
|
"type": "module",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"docs/RELEASE_1.0.0.md",
|
|
42
42
|
"docs/RELEASE_1.0.1.md",
|
|
43
43
|
"docs/RELEASE_1.0.2.md",
|
|
44
|
+
"docs/RELEASE_1.0.3.md",
|
|
44
45
|
"docs/RELEASE_NOTES.md",
|
|
45
46
|
"docs/SCHEDULES.md",
|
|
46
47
|
"docs/SECURITY.md",
|
|
@@ -359,25 +359,20 @@
|
|
|
359
359
|
},
|
|
360
360
|
"tunnel": {
|
|
361
361
|
"default": {
|
|
362
|
-
"
|
|
363
|
-
"startWithDodo": true,
|
|
362
|
+
"connectionMode": "local",
|
|
364
363
|
"metricsPort": 21732,
|
|
365
364
|
"maxRestarts": 2
|
|
366
365
|
},
|
|
367
366
|
"type": "object",
|
|
368
367
|
"properties": {
|
|
369
|
-
"
|
|
370
|
-
"default": "
|
|
368
|
+
"connectionMode": {
|
|
369
|
+
"default": "local",
|
|
371
370
|
"type": "string",
|
|
372
371
|
"enum": [
|
|
373
|
-
"
|
|
374
|
-
"
|
|
372
|
+
"local",
|
|
373
|
+
"tunnel"
|
|
375
374
|
]
|
|
376
375
|
},
|
|
377
|
-
"startWithDodo": {
|
|
378
|
-
"default": true,
|
|
379
|
-
"type": "boolean"
|
|
380
|
-
},
|
|
381
376
|
"credentialRef": {
|
|
382
377
|
"oneOf": [
|
|
383
378
|
{
|
|
@@ -456,8 +451,7 @@
|
|
|
456
451
|
}
|
|
457
452
|
},
|
|
458
453
|
"required": [
|
|
459
|
-
"
|
|
460
|
-
"startWithDodo",
|
|
454
|
+
"connectionMode",
|
|
461
455
|
"metricsPort",
|
|
462
456
|
"maxRestarts"
|
|
463
457
|
],
|