tripinned-mcp 1.0.0 → 1.0.2
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 +35 -4
- package/dist/limits.js +2 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import { TRIP_LIMIT, ITEM_PER_DAY_LIMIT } from "./limits.js";
|
|
5
6
|
const API_KEY = process.env.TRIPINNED_API_KEY;
|
|
6
7
|
const BASE_URL = process.env.TRIPINNED_API_URL ?? "https://api.tripinned.com/v1";
|
|
7
8
|
if (!API_KEY) {
|
|
@@ -44,7 +45,7 @@ server.tool("get_trip", "특정 여행 플랜의 상세 정보(날짜별 일정
|
|
|
44
45
|
const data = await call("GET", `/trips/${trip_id}`);
|
|
45
46
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
46
47
|
});
|
|
47
|
-
server.tool("create_trip",
|
|
48
|
+
server.tool("create_trip", `새 여행 플랜을 만듭니다. 날짜 범위에 맞는 Day가 자동 생성됩니다. 계정당 최대 ${TRIP_LIMIT}개까지 생성 가능합니다.`, {
|
|
48
49
|
title: z.string().max(30).describe("플랜 제목 (최대 30자)"),
|
|
49
50
|
start_date: z.string().describe("시작일 (YYYY-MM-DD)"),
|
|
50
51
|
end_date: z.string().describe("종료일 (YYYY-MM-DD), 시작일 포함 최대 30일"),
|
|
@@ -85,7 +86,7 @@ server.tool("delete_trip", "여행 플랜을 삭제합니다. 포함된 모든 D
|
|
|
85
86
|
return { content: [{ type: "text", text: `플랜 ${trip_id}이(가) 삭제되었습니다.` }] };
|
|
86
87
|
});
|
|
87
88
|
// ── Items ────────────────────────────────────────────────────────────────────
|
|
88
|
-
server.tool("add_item",
|
|
89
|
+
server.tool("add_item", `특정 Day에 일정을 추가합니다. Day당 최대 ${ITEM_PER_DAY_LIMIT}개까지 추가 가능합니다.`, {
|
|
89
90
|
trip_id: z.string().describe("플랜 ID"),
|
|
90
91
|
day_id: z.string().describe("Day ID (get_trip으로 확인 가능)"),
|
|
91
92
|
title: z.string().max(50).describe("일정 제목 (최대 50자)"),
|
|
@@ -95,9 +96,14 @@ server.tool("add_item", "특정 Day에 일정을 추가합니다.", {
|
|
|
95
96
|
]).optional().describe("아이콘 종류 (기본값: ETC)"),
|
|
96
97
|
start_time: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("시작 시간 (HH:MM)"),
|
|
97
98
|
end_time: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("종료 시간 (HH:MM)"),
|
|
99
|
+
end_day_offset: z.number().int().min(0).optional().describe("도착일 오프셋 (0=당일, 1=다음날 등)"),
|
|
98
100
|
place: z.string().optional().describe("장소명"),
|
|
99
101
|
memo: z.string().max(1000).optional().describe("메모 (최대 1000자)"),
|
|
100
|
-
|
|
102
|
+
from_place: z.string().optional().describe("출발지 IATA 코드 (항공편 전용, 예: ICN)"),
|
|
103
|
+
to_place: z.string().optional().describe("도착지 IATA 코드 (항공편 전용, 예: MXP)"),
|
|
104
|
+
layovers: z.string().optional().describe('경유지 JSON 배열 (항공편 전용). 예: [{"iata":"HAN","arrTime":"21:35","arrOffset":0,"depTime":"00:45","depOffset":1}]'),
|
|
105
|
+
flight_no: z.string().optional().describe("항공편 번호 (예: KE447)"),
|
|
106
|
+
}, async ({ trip_id, day_id, title, icon, start_time, end_time, end_day_offset, place, memo, from_place, to_place, layovers, flight_no }) => {
|
|
101
107
|
const body = { title };
|
|
102
108
|
if (icon)
|
|
103
109
|
body.icon = icon;
|
|
@@ -105,10 +111,20 @@ server.tool("add_item", "특정 Day에 일정을 추가합니다.", {
|
|
|
105
111
|
body.startTime = start_time;
|
|
106
112
|
if (end_time)
|
|
107
113
|
body.endTime = end_time;
|
|
114
|
+
if (end_day_offset !== undefined)
|
|
115
|
+
body.endDayOffset = end_day_offset;
|
|
108
116
|
if (place)
|
|
109
117
|
body.place = place;
|
|
110
118
|
if (memo)
|
|
111
119
|
body.memo = memo;
|
|
120
|
+
if (from_place)
|
|
121
|
+
body.fromPlace = from_place;
|
|
122
|
+
if (to_place)
|
|
123
|
+
body.toPlace = to_place;
|
|
124
|
+
if (layovers)
|
|
125
|
+
body.layovers = layovers;
|
|
126
|
+
if (flight_no)
|
|
127
|
+
body.flightNo = flight_no;
|
|
112
128
|
const data = await call("POST", `/trips/${trip_id}/days/${day_id}/items`, body);
|
|
113
129
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
114
130
|
});
|
|
@@ -123,9 +139,14 @@ server.tool("update_item", "일정을 수정합니다. 변경할 필드만 보
|
|
|
123
139
|
]).optional().describe("새 아이콘"),
|
|
124
140
|
start_time: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("새 시작 시간 (HH:MM)"),
|
|
125
141
|
end_time: z.string().regex(/^\d{2}:\d{2}$/).optional().describe("새 종료 시간 (HH:MM)"),
|
|
142
|
+
end_day_offset: z.number().int().min(0).optional().describe("도착일 오프셋 (0=당일, 1=다음날 등)"),
|
|
126
143
|
place: z.string().optional().describe("새 장소명"),
|
|
127
144
|
memo: z.string().max(1000).optional().describe("새 메모"),
|
|
128
|
-
|
|
145
|
+
from_place: z.string().optional().describe("출발지 IATA 코드 (항공편 전용, 예: ICN)"),
|
|
146
|
+
to_place: z.string().optional().describe("도착지 IATA 코드 (항공편 전용, 예: MXP)"),
|
|
147
|
+
layovers: z.string().nullable().optional().describe('경유지 JSON 배열 (항공편 전용). 예: [{"iata":"HAN","arrTime":"21:35","arrOffset":0,"depTime":"00:45","depOffset":1}] / null로 초기화'),
|
|
148
|
+
flight_no: z.string().optional().describe("항공편 번호 (예: KE447)"),
|
|
149
|
+
}, async ({ trip_id, day_id, item_id, title, icon, start_time, end_time, end_day_offset, place, memo, from_place, to_place, layovers, flight_no }) => {
|
|
129
150
|
const body = {};
|
|
130
151
|
if (title !== undefined)
|
|
131
152
|
body.title = title;
|
|
@@ -135,10 +156,20 @@ server.tool("update_item", "일정을 수정합니다. 변경할 필드만 보
|
|
|
135
156
|
body.startTime = start_time;
|
|
136
157
|
if (end_time !== undefined)
|
|
137
158
|
body.endTime = end_time;
|
|
159
|
+
if (end_day_offset !== undefined)
|
|
160
|
+
body.endDayOffset = end_day_offset;
|
|
138
161
|
if (place !== undefined)
|
|
139
162
|
body.place = place;
|
|
140
163
|
if (memo !== undefined)
|
|
141
164
|
body.memo = memo;
|
|
165
|
+
if (from_place !== undefined)
|
|
166
|
+
body.fromPlace = from_place;
|
|
167
|
+
if (to_place !== undefined)
|
|
168
|
+
body.toPlace = to_place;
|
|
169
|
+
if (layovers !== undefined)
|
|
170
|
+
body.layovers = layovers;
|
|
171
|
+
if (flight_no !== undefined)
|
|
172
|
+
body.flightNo = flight_no;
|
|
142
173
|
const data = await call("PATCH", `/trips/${trip_id}/days/${day_id}/items/${item_id}`, body);
|
|
143
174
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
144
175
|
});
|
package/dist/limits.js
ADDED
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tripinned-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "MCP server for Tripinned — manage your travel plans with AI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"tripinned-mcp": "dist/index.js"
|
|
9
9
|
},
|
|
10
|
+
"files": ["dist"],
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "tsc",
|
|
12
13
|
"dev": "node --loader ts-node/esm src/index.ts",
|