@dodo-planet/mcp 0.1.4 → 0.1.6
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/dist/index.js +37 -11
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -185,7 +185,12 @@ var FUNCTION_CATALOG = [
|
|
|
185
185
|
{ name: "get_friends", category: "friend", verb: "list", requiresTrip: false, isWrite: false, isDestructive: false },
|
|
186
186
|
{ name: "add_friend", category: "friend", verb: "add", requiresTrip: false, isWrite: true, isDestructive: false },
|
|
187
187
|
{ name: "get_invitations", category: "invite", verb: "list", requiresTrip: true, isWrite: false, isDestructive: false },
|
|
188
|
-
{ name: "invite_to_trip", category: "invite", verb: "create", requiresTrip: true, isWrite: true, isDestructive: false }
|
|
188
|
+
{ name: "invite_to_trip", category: "invite", verb: "create", requiresTrip: true, isWrite: true, isDestructive: false },
|
|
189
|
+
// ── 여행 프로필 (4개, M2)
|
|
190
|
+
{ name: "get_travel_profile", category: "profile", verb: "show", requiresTrip: false, isWrite: false, isDestructive: false },
|
|
191
|
+
{ name: "update_travel_profile_section", category: "profile", verb: "update", requiresTrip: false, isWrite: true, isDestructive: false },
|
|
192
|
+
{ name: "finalize_travel_profile", category: "profile", verb: "finalize", requiresTrip: false, isWrite: false, isDestructive: false, isBuilderOnly: true },
|
|
193
|
+
{ name: "clear_travel_profile", category: "profile", verb: "clear", requiresTrip: false, isWrite: true, isDestructive: true }
|
|
189
194
|
];
|
|
190
195
|
var CATALOG_BY_NAME = new Map(
|
|
191
196
|
FUNCTION_CATALOG.map((meta) => [meta.name, meta])
|
|
@@ -214,7 +219,13 @@ async function executeOnServer(apiUrl, token, name, args, options = {}) {
|
|
|
214
219
|
const response = await fetch(new URL("/api/cli/execute", apiUrl).toString(), {
|
|
215
220
|
method: "POST",
|
|
216
221
|
headers,
|
|
217
|
-
body: JSON.stringify({
|
|
222
|
+
body: JSON.stringify({
|
|
223
|
+
name,
|
|
224
|
+
args,
|
|
225
|
+
tripId: options.tripId,
|
|
226
|
+
// builder-only 함수는 'profile_builder', 그 외는 undefined → general (T8)
|
|
227
|
+
mode: options.mode
|
|
228
|
+
})
|
|
218
229
|
});
|
|
219
230
|
const text = await response.text();
|
|
220
231
|
let parsed = text;
|
|
@@ -262,17 +273,22 @@ async function run() {
|
|
|
262
273
|
const meta = getFunctionMeta(decl.name) ?? decl.meta;
|
|
263
274
|
if (!meta) continue;
|
|
264
275
|
const inputSchema = zodShapeFromJsonSchema(decl.parametersJsonSchema);
|
|
265
|
-
if (meta.isDestructive) {
|
|
266
|
-
inputSchema.confirm = z2.literal(true).describe(
|
|
276
|
+
if (meta.isDestructive || meta.isBuilderOnly) {
|
|
277
|
+
inputSchema.confirm = z2.literal(true).describe(
|
|
278
|
+
meta.isDestructive ? "\uC774 \uC791\uC5C5\uC740 \uC601\uAD6C \uC0AD\uC81C\uC774\uBBC0\uB85C \uC0AC\uC6A9\uC790\uAC00 \uC758\uB3C4\uD55C \uACBD\uC6B0\uC5D0\uB9CC confirm: true \uB85C \uD638\uCD9C\uD558\uC138\uC694." : "\uC774 \uC791\uC5C5\uC740 \uBE4C\uB354 \uBAA8\uB4DC \uC804\uC6A9\uC785\uB2C8\uB2E4. \uC0AC\uC6A9\uC790\uAC00 \uD504\uB85C\uD544\uC744 \uB2E4\uB4EC\uC73C\uB824\uB294 \uC758\uB3C4\uB97C \uBA85\uD655\uD788 \uD45C\uD604\uD588\uC744 \uB54C\uB9CC confirm: true \uB85C \uD638\uCD9C\uD558\uC138\uC694."
|
|
279
|
+
);
|
|
267
280
|
}
|
|
268
281
|
if (meta.requiresTrip) {
|
|
269
282
|
inputSchema.tripId = z2.string().optional().describe(
|
|
270
283
|
"Trip UUID. \uBBF8\uC9C0\uC815 \uC2DC \uC0AC\uC6A9\uC790\uAC00 \uB9C8\uC9C0\uB9C9\uC73C\uB85C dodo trip switch \uD55C \uD65C\uC131 trip \uB610\uB294 DODO_TRIP_ID \uD658\uACBD\uBCC0\uC218 \uAC12\uC744 \uC0AC\uC6A9."
|
|
271
284
|
);
|
|
272
285
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
\u26A0\uFE0F DESTRUCTIVE: \uC774 \uB3C4\uAD6C\uB294 \uC601\uAD6C \uC0AD\uC81C\uB97C \uC218\uD589\uD569\uB2C8\uB2E4. \uD638\uCD9C \uC2DC args.confirm = true \uAC00 \uD544\uC694\uD558\uBA70, \uD638\uC2A4\uD2B8 \uC0AC\uC6A9\uC790\uC758 \uBA85\uC2DC \uB3D9\uC758\uAC00 \uC788\uC744 \uB54C\uB9CC \uC0AC\uC6A9\uD558\uC138\uC694
|
|
286
|
+
let description = decl.description;
|
|
287
|
+
if (meta.isDestructive) {
|
|
288
|
+
description += "\n\n\u26A0\uFE0F DESTRUCTIVE: \uC774 \uB3C4\uAD6C\uB294 \uC601\uAD6C \uC0AD\uC81C\uB97C \uC218\uD589\uD569\uB2C8\uB2E4. \uD638\uCD9C \uC2DC args.confirm = true \uAC00 \uD544\uC694\uD558\uBA70, \uD638\uC2A4\uD2B8 \uC0AC\uC6A9\uC790\uC758 \uBA85\uC2DC \uB3D9\uC758\uAC00 \uC788\uC744 \uB54C\uB9CC \uC0AC\uC6A9\uD558\uC138\uC694.";
|
|
289
|
+
} else if (meta.isBuilderOnly) {
|
|
290
|
+
description += "\n\n\u26A0\uFE0F \uBE4C\uB354 \uC804\uC6A9: \uC0AC\uC6A9\uC790\uAC00 \uC5EC\uD589 \uD504\uB85C\uD544\uC744 \uB9C8\uBB34\uB9AC\uD558\uB824\uACE0 \uD55C\uB2E4\uB294 \uBA85\uC2DC \uC758\uB3C4\uAC00 \uC788\uC744 \uB54C\uB9CC args.confirm = true \uB85C \uD638\uCD9C\uD558\uC138\uC694.";
|
|
291
|
+
}
|
|
276
292
|
server.registerTool(
|
|
277
293
|
decl.name,
|
|
278
294
|
{
|
|
@@ -288,10 +304,14 @@ async function run() {
|
|
|
288
304
|
},
|
|
289
305
|
async (args) => {
|
|
290
306
|
try {
|
|
291
|
-
const
|
|
292
|
-
|
|
307
|
+
const requiresConfirm = meta.isDestructive || meta.isBuilderOnly;
|
|
308
|
+
const confirmed = requiresConfirm && args?.confirm === true;
|
|
309
|
+
if (requiresConfirm && !confirmed) {
|
|
293
310
|
return {
|
|
294
|
-
content: [{
|
|
311
|
+
content: [{
|
|
312
|
+
type: "text",
|
|
313
|
+
text: meta.isDestructive ? "Error: destructive \uB3C4\uAD6C\uB294 args.confirm = true \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." : "Error: \uBE4C\uB354 \uC804\uC6A9 \uB3C4\uAD6C\uB294 args.confirm = true \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4."
|
|
314
|
+
}],
|
|
295
315
|
isError: true
|
|
296
316
|
};
|
|
297
317
|
}
|
|
@@ -309,7 +329,13 @@ async function run() {
|
|
|
309
329
|
isError: true
|
|
310
330
|
};
|
|
311
331
|
}
|
|
312
|
-
const result = await executeOnServer(apiUrl, token, decl.name, passArgs, {
|
|
332
|
+
const result = await executeOnServer(apiUrl, token, decl.name, passArgs, {
|
|
333
|
+
confirmDestructive: meta.isDestructive && confirmed,
|
|
334
|
+
tripId,
|
|
335
|
+
// builder-only 함수는 /api/cli/execute의 BUILDER_ONLY_FUNCTIONS 게이트(T1)
|
|
336
|
+
// 통과를 위해 mode='profile_builder' 명시. destructive 단독은 mode 미주입.
|
|
337
|
+
mode: meta.isBuilderOnly ? "profile_builder" : void 0
|
|
338
|
+
});
|
|
313
339
|
const text = humanizeResult(result);
|
|
314
340
|
return {
|
|
315
341
|
content: [{ type: "text", text }],
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dodo-planet/mcp",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Dodo Planet MCP server — exposes
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "Dodo Planet MCP server — exposes 47 family-trip functions to Claude Code, Cursor, Codex via stdio.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"dodo-mcp": "./bin/dodo-mcp.mjs"
|