@dodo-planet/mcp 0.1.4 → 0.1.5

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.
Files changed (2) hide show
  1. package/dist/index.js +37 -11
  2. 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({ name, args, tripId: options.tripId })
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("\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.");
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
- const description = meta.isDestructive ? `${decl.description}
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.` : decl.description;
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 confirmDestructive = meta.isDestructive && args?.confirm === true;
292
- if (meta.isDestructive && !confirmDestructive) {
307
+ const requiresConfirm = meta.isDestructive || meta.isBuilderOnly;
308
+ const confirmed = requiresConfirm && args?.confirm === true;
309
+ if (requiresConfirm && !confirmed) {
293
310
  return {
294
- content: [{ type: "text", text: "Error: destructive \uB3C4\uAD6C\uB294 args.confirm = true \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4." }],
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, { confirmDestructive, tripId });
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",
4
- "description": "Dodo Planet MCP server — exposes 43 family-trip functions to Claude Code, Cursor, Codex via stdio.",
3
+ "version": "0.1.5",
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"