qingflow-mcp 0.2.4 → 0.2.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.
- package/README.md +6 -0
- package/dist/server.js +23 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,6 +105,12 @@ MCP client config example:
|
|
|
105
105
|
|
|
106
106
|
## List Query Tips
|
|
107
107
|
|
|
108
|
+
Strict mode (`qf_records_list`):
|
|
109
|
+
|
|
110
|
+
1. `select_columns` is required.
|
|
111
|
+
2. `include_answers=false` is not allowed.
|
|
112
|
+
3. Output `items[].answers` contains only selected columns, not full answers.
|
|
113
|
+
|
|
108
114
|
1. For `qf_records_list.sort[].que_id`, use a real field `que_id` (numeric) or exact field title from `qf_form_get`.
|
|
109
115
|
2. Avoid aliases like `create_time`; Qingflow often rejects them.
|
|
110
116
|
3. Use `max_rows` (or `max_items`) to cap returned rows.
|
package/dist/server.js
CHANGED
|
@@ -147,7 +147,8 @@ const formOutputSchema = z.object({
|
|
|
147
147
|
}),
|
|
148
148
|
meta: apiMetaSchema
|
|
149
149
|
});
|
|
150
|
-
const listInputSchema = z
|
|
150
|
+
const listInputSchema = z
|
|
151
|
+
.object({
|
|
151
152
|
app_key: z.string().min(1),
|
|
152
153
|
user_id: z.string().min(1).optional(),
|
|
153
154
|
page_num: z.number().int().positive().optional(),
|
|
@@ -193,12 +194,12 @@ const listInputSchema = z.object({
|
|
|
193
194
|
max_rows: z.number().int().positive().max(200).optional(),
|
|
194
195
|
max_items: z.number().int().positive().max(200).optional(),
|
|
195
196
|
max_columns: z.number().int().positive().max(200).optional(),
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
.min(1)
|
|
199
|
-
.max(200)
|
|
200
|
-
.optional(),
|
|
197
|
+
// Strict mode: callers must explicitly choose columns.
|
|
198
|
+
select_columns: z.array(z.union([z.string().min(1), z.number().int()])).min(1).max(200),
|
|
201
199
|
include_answers: z.boolean().optional()
|
|
200
|
+
})
|
|
201
|
+
.refine((value) => value.include_answers !== false, {
|
|
202
|
+
message: "include_answers=false is not allowed in strict column mode"
|
|
202
203
|
});
|
|
203
204
|
const listOutputSchema = z.object({
|
|
204
205
|
ok: z.literal(true),
|
|
@@ -216,7 +217,7 @@ const listOutputSchema = z.object({
|
|
|
216
217
|
include_answers: z.boolean(),
|
|
217
218
|
row_cap: z.number().int().nonnegative(),
|
|
218
219
|
column_cap: z.number().int().positive().nullable(),
|
|
219
|
-
selected_columns: z.array(z.string())
|
|
220
|
+
selected_columns: z.array(z.string())
|
|
220
221
|
})
|
|
221
222
|
.optional()
|
|
222
223
|
}),
|
|
@@ -392,7 +393,7 @@ server.registerTool("qf_records_list", {
|
|
|
392
393
|
const pageNum = args.page_num ?? 1;
|
|
393
394
|
const pageSize = args.page_size ?? DEFAULT_PAGE_SIZE;
|
|
394
395
|
const normalizedSort = await normalizeListSort(args.sort, args.app_key, args.user_id);
|
|
395
|
-
const includeAnswers =
|
|
396
|
+
const includeAnswers = true;
|
|
396
397
|
const payload = buildListPayload({
|
|
397
398
|
pageNum,
|
|
398
399
|
pageSize,
|
|
@@ -422,6 +423,11 @@ server.registerTool("qf_records_list", {
|
|
|
422
423
|
maxColumns: args.max_columns,
|
|
423
424
|
selectColumns: args.select_columns
|
|
424
425
|
});
|
|
426
|
+
if (items.length > 0 && columnProjection.matchedAnswersCount === 0) {
|
|
427
|
+
throw new Error(`No answers matched select_columns (${args.select_columns
|
|
428
|
+
.map((item) => String(item))
|
|
429
|
+
.join(", ")}). Check que_id/title from qf_form_get.`);
|
|
430
|
+
}
|
|
425
431
|
const fitted = fitListItemsWithinSize({
|
|
426
432
|
items: columnProjection.items,
|
|
427
433
|
limitBytes: MAX_LIST_ITEMS_BYTES
|
|
@@ -926,12 +932,17 @@ function projectRecordItemsColumns(params) {
|
|
|
926
932
|
return {
|
|
927
933
|
items: params.items,
|
|
928
934
|
reason: null,
|
|
929
|
-
selectedColumns:
|
|
935
|
+
selectedColumns: [],
|
|
936
|
+
matchedAnswersCount: 0
|
|
930
937
|
};
|
|
931
938
|
}
|
|
932
939
|
const normalizedSelectors = normalizeColumnSelectors(params.selectColumns);
|
|
940
|
+
if (normalizedSelectors.length === 0) {
|
|
941
|
+
throw new Error("select_columns must contain at least one non-empty column identifier");
|
|
942
|
+
}
|
|
933
943
|
const selectorSet = new Set(normalizedSelectors.map((item) => normalizeColumnSelector(item)));
|
|
934
944
|
let columnCapped = false;
|
|
945
|
+
let matchedAnswersCount = 0;
|
|
935
946
|
const projectedItems = params.items.map((item) => {
|
|
936
947
|
const answers = asArray(item.answers);
|
|
937
948
|
let projected = answers;
|
|
@@ -942,6 +953,7 @@ function projectRecordItemsColumns(params) {
|
|
|
942
953
|
projected = projected.slice(0, params.maxColumns);
|
|
943
954
|
columnCapped = true;
|
|
944
955
|
}
|
|
956
|
+
matchedAnswersCount += projected.length;
|
|
945
957
|
return {
|
|
946
958
|
...item,
|
|
947
959
|
answers: projected
|
|
@@ -953,7 +965,8 @@ function projectRecordItemsColumns(params) {
|
|
|
953
965
|
return {
|
|
954
966
|
items: projectedItems,
|
|
955
967
|
reason,
|
|
956
|
-
selectedColumns: normalizedSelectors
|
|
968
|
+
selectedColumns: normalizedSelectors,
|
|
969
|
+
matchedAnswersCount
|
|
957
970
|
};
|
|
958
971
|
}
|
|
959
972
|
function projectAnswersForOutput(params) {
|