@kintone/mcp-server 1.0.0

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.
@@ -0,0 +1,141 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ const inputSchema = {
6
+ app: z
7
+ .string()
8
+ .describe("The ID of the app to retrieve form fields from (numeric value as string)"),
9
+ lang: z
10
+ .enum(["ja", "en", "zh", "default", "user"])
11
+ .optional()
12
+ .describe("The language for field names"),
13
+ };
14
+ const fieldPropertySchema = z.object({
15
+ type: z.string().describe("The field type"),
16
+ code: z.string().describe("The field code"),
17
+ label: z.string().describe("The field name"),
18
+ enabled: z
19
+ .boolean()
20
+ .optional()
21
+ .describe("Whether the field is enabled (for STATUS and CATEGORY fields)"),
22
+ noLabel: z.boolean().optional().describe("Whether to hide the field name"),
23
+ required: z.boolean().optional().describe("Whether the field is required"),
24
+ unique: z.boolean().optional().describe("Whether the field must be unique"),
25
+ maxValue: z.string().optional().describe("Maximum value"),
26
+ minValue: z.string().optional().describe("Minimum value"),
27
+ maxLength: z.string().optional().describe("Maximum length"),
28
+ minLength: z.string().optional().describe("Minimum length"),
29
+ defaultValue: z.any().optional().describe("Default value"),
30
+ defaultNowValue: z
31
+ .boolean()
32
+ .optional()
33
+ .describe("Whether to use current date/time as default"),
34
+ entities: z
35
+ .array(z.object({
36
+ type: z.enum(["USER", "GROUP", "ORGANIZATION"]),
37
+ code: z.string(),
38
+ }))
39
+ .optional()
40
+ .describe("Default entities for user/group/organization selection fields"),
41
+ options: z
42
+ .record(z.object({
43
+ label: z.string(),
44
+ index: z.string(),
45
+ }))
46
+ .optional()
47
+ .describe("Options for selection fields"),
48
+ align: z
49
+ .enum(["HORIZONTAL", "VERTICAL"])
50
+ .optional()
51
+ .describe("Option alignment for radio/checkbox fields"),
52
+ expression: z.string().optional().describe("Calculation formula"),
53
+ hideExpression: z
54
+ .boolean()
55
+ .optional()
56
+ .describe("Whether to hide the formula"),
57
+ format: z.string().optional().describe("Display format"),
58
+ displayScale: z.string().optional().describe("Number of decimal places"),
59
+ unit: z.string().optional().describe("Unit symbol"),
60
+ unitPosition: z
61
+ .enum(["BEFORE", "AFTER"])
62
+ .optional()
63
+ .describe("Unit position"),
64
+ digit: z.boolean().optional().describe("Whether to use thousands separator"),
65
+ thumbnailSize: z.string().optional().describe("Image thumbnail size"),
66
+ protocol: z
67
+ .enum(["WEB", "CALL", "MAIL"])
68
+ .optional()
69
+ .describe("Link protocol"),
70
+ lookup: z
71
+ .object({
72
+ relatedApp: z.object({
73
+ app: z.string(),
74
+ code: z.string(),
75
+ }),
76
+ relatedKeyField: z.string(),
77
+ fieldMappings: z.array(z.object({
78
+ field: z.string(),
79
+ relatedField: z.string(),
80
+ })),
81
+ lookupPickerFields: z.array(z.string()),
82
+ filterCond: z.string().optional(),
83
+ sort: z.string().optional(),
84
+ })
85
+ .optional()
86
+ .describe("Lookup settings"),
87
+ referenceTable: z
88
+ .object({
89
+ relatedApp: z.object({
90
+ app: z.string(),
91
+ code: z.string(),
92
+ }),
93
+ condition: z.object({
94
+ field: z.string(),
95
+ relatedField: z.string(),
96
+ }),
97
+ filterCond: z.string().optional(),
98
+ displayFields: z.array(z.string()),
99
+ sort: z.string().optional(),
100
+ size: z.string().optional(),
101
+ })
102
+ .optional()
103
+ .describe("Related records settings"),
104
+ fields: z.record(z.any()).optional().describe("Fields in subtable"),
105
+ openGroup: z
106
+ .boolean()
107
+ .optional()
108
+ .describe("Whether the group is expanded by default"),
109
+ });
110
+ const outputSchema = {
111
+ properties: z
112
+ .record(fieldPropertySchema)
113
+ .describe("Object containing field configurations"),
114
+ revision: z.string().describe("App configuration revision number"),
115
+ };
116
+ export const getFormFields = createTool("kintone-get-form-fields", {
117
+ title: "Get Form Fields",
118
+ description: "Get form field settings from a kintone app",
119
+ inputSchema,
120
+ outputSchema,
121
+ }, async ({ app, lang }) => {
122
+ const config = parseKintoneClientConfig();
123
+ const client = getKintoneClient(config);
124
+ const response = await client.app.getFormFields({
125
+ app,
126
+ lang,
127
+ });
128
+ const result = {
129
+ properties: response.properties,
130
+ revision: response.revision,
131
+ };
132
+ return {
133
+ structuredContent: result,
134
+ content: [
135
+ {
136
+ type: "text",
137
+ text: JSON.stringify(result, null, 2),
138
+ },
139
+ ],
140
+ };
141
+ });
@@ -0,0 +1,88 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ const inputSchema = {
6
+ app: z
7
+ .string()
8
+ .describe("The ID of the app to retrieve process management settings from (numeric value as string)"),
9
+ lang: z
10
+ .enum(["ja", "en", "zh", "default", "user"])
11
+ .optional()
12
+ .describe("The language for field names"),
13
+ };
14
+ const entitySchema = z.object({
15
+ type: z.enum([
16
+ "USER",
17
+ "GROUP",
18
+ "ORGANIZATION",
19
+ "FIELD_ENTITY",
20
+ "CREATOR",
21
+ "CUSTOM_FIELD",
22
+ ]),
23
+ code: z.string().nullable(),
24
+ });
25
+ const entityWithSubsSchema = z.object({
26
+ entity: entitySchema,
27
+ includeSubs: z.boolean(),
28
+ });
29
+ const stateAssigneeSchema = z.object({
30
+ type: z.enum(["ONE", "ALL", "ANY"]).describe("Assignee type"),
31
+ entities: z.array(entityWithSubsSchema).describe("Assignee entities"),
32
+ });
33
+ const stateSchema = z.object({
34
+ name: z.string().describe("Status name"),
35
+ index: z.string().describe("Display order"),
36
+ assignee: stateAssigneeSchema
37
+ .optional()
38
+ .describe("Default assignee for the status"),
39
+ });
40
+ const actionSchema = z.object({
41
+ name: z.string().describe("Action name"),
42
+ from: z.string().describe("Source status name"),
43
+ to: z.string().describe("Destination status name"),
44
+ filterCond: z.string().describe("Branch condition"),
45
+ type: z.enum(["PRIMARY", "SECONDARY"]).describe("Action type"),
46
+ executableUser: z
47
+ .object({
48
+ entities: z
49
+ .array(entityWithSubsSchema)
50
+ .describe("Users who can execute the action"),
51
+ })
52
+ .optional()
53
+ .describe("Executable user settings"),
54
+ });
55
+ const outputSchema = {
56
+ enable: z.boolean().describe("Whether process management is enabled"),
57
+ states: z
58
+ .record(stateSchema)
59
+ .nullable()
60
+ .describe("Object containing status configurations"),
61
+ actions: z
62
+ .array(actionSchema)
63
+ .nullable()
64
+ .describe("Array containing action configurations"),
65
+ revision: z.string().describe("App settings revision number"),
66
+ };
67
+ export const getProcessManagement = createTool("kintone-get-process-management", {
68
+ title: "Get Process Management",
69
+ description: "Get process management settings from a kintone app",
70
+ inputSchema,
71
+ outputSchema,
72
+ }, async ({ app, lang }) => {
73
+ const config = parseKintoneClientConfig();
74
+ const client = getKintoneClient(config);
75
+ const response = await client.app.getProcessManagement({
76
+ app,
77
+ lang,
78
+ });
79
+ return {
80
+ structuredContent: response,
81
+ content: [
82
+ {
83
+ type: "text",
84
+ text: JSON.stringify(response, null, 2),
85
+ },
86
+ ],
87
+ };
88
+ });
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ import { recordSchemaForParameterWithoutFile } from "../../../schema/record/record-for-parameter.js";
6
+ const inputSchema = {
7
+ app: z
8
+ .string()
9
+ .describe("The ID of the app to add records to (numeric value as string)"),
10
+ records: z
11
+ .array(recordSchemaForParameterWithoutFile)
12
+ .min(1)
13
+ .max(100)
14
+ .describe("Array of records to add (min 1, max 100). Each record is an object with field codes as keys. Use kintone-get-form-fields tool first to discover available field codes and their types."),
15
+ };
16
+ const outputSchema = {
17
+ ids: z.array(z.string()).describe("Array of IDs of the created records"),
18
+ revisions: z
19
+ .array(z.string())
20
+ .describe("Array of revision numbers of the created records"),
21
+ };
22
+ export const addRecords = createTool("kintone-add-records", {
23
+ title: "Add Records",
24
+ description: "Add multiple records to a kintone app. Use kintone-get-form-fields tool first to discover available field codes and their required formats. Note: Some fields cannot be registered (LOOKUP copies, STATUS, CATEGORY, CALC, ASSIGNEE, auto-calculated fields).",
25
+ inputSchema,
26
+ outputSchema,
27
+ }, async ({ app, records }) => {
28
+ const config = parseKintoneClientConfig();
29
+ const client = getKintoneClient(config);
30
+ const response = await client.record.addRecords({
31
+ app,
32
+ records,
33
+ });
34
+ const result = {
35
+ ids: response.ids,
36
+ revisions: response.revisions,
37
+ };
38
+ return {
39
+ structuredContent: result,
40
+ content: [
41
+ {
42
+ type: "text",
43
+ text: JSON.stringify(result, null, 2),
44
+ },
45
+ ],
46
+ };
47
+ });
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ const inputSchema = {
6
+ app: z.string().describe("The ID of the app (numeric value as string)"),
7
+ ids: z
8
+ .array(z.string())
9
+ .describe("Array of record IDs to delete (numeric values as strings)")
10
+ .min(1, "At least one record ID is required")
11
+ .max(100, "Maximum 100 records can be deleted at once"),
12
+ revisions: z
13
+ .array(z.string())
14
+ .optional()
15
+ .describe("Array of expected revision numbers for each record (numeric values as strings). If specified, must have the same length as ids array. Deletion will fail if current revisions don't match. Specify -1 or omit to skip revision validation."),
16
+ };
17
+ const outputSchema = {};
18
+ export const deleteRecords = createTool("kintone-delete-records", {
19
+ title: "Delete Records",
20
+ description: "Delete multiple records from a kintone app. Maximum 100 records can be deleted at once.",
21
+ inputSchema,
22
+ outputSchema,
23
+ }, async ({ app, ids, revisions }) => {
24
+ const config = parseKintoneClientConfig();
25
+ const client = getKintoneClient(config);
26
+ await client.record.deleteRecords({ app, ids, revisions });
27
+ return {
28
+ structuredContent: {},
29
+ content: [],
30
+ };
31
+ });
@@ -0,0 +1,166 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ import { recordSchema } from "../../../schema/record/records.js";
6
+ const filtersSchema = z
7
+ .object({
8
+ textContains: z
9
+ .array(z.object({
10
+ field: z.string().describe("Field code"),
11
+ value: z.string().describe("Text to search for"),
12
+ }))
13
+ .optional()
14
+ .describe("Text fields containing specified values"),
15
+ equals: z
16
+ .array(z.object({
17
+ field: z.string().describe("Field code"),
18
+ value: z.string().describe("Exact value to match"),
19
+ }))
20
+ .optional()
21
+ .describe("Fields equal to specified values"),
22
+ dateRange: z
23
+ .array(z.object({
24
+ field: z.string().describe("Field code"),
25
+ from: z.string().optional().describe("Start date (YYYY-MM-DD)"),
26
+ to: z.string().optional().describe("End date (YYYY-MM-DD)"),
27
+ }))
28
+ .optional()
29
+ .describe("Date fields within specified range"),
30
+ numberRange: z
31
+ .array(z.object({
32
+ field: z.string().describe("Field code"),
33
+ min: z.number().optional().describe("Minimum value"),
34
+ max: z.number().optional().describe("Maximum value"),
35
+ }))
36
+ .optional()
37
+ .describe("Number fields within specified range"),
38
+ inValues: z
39
+ .array(z.object({
40
+ field: z.string().describe("Field code"),
41
+ values: z.array(z.string()).describe("List of values to match"),
42
+ }))
43
+ .optional()
44
+ .describe("Fields matching any of the specified values"),
45
+ notInValues: z
46
+ .array(z.object({
47
+ field: z.string().describe("Field code"),
48
+ values: z.array(z.string()).describe("List of values to exclude"),
49
+ }))
50
+ .optional()
51
+ .describe("Fields not matching any of the specified values"),
52
+ })
53
+ .optional()
54
+ .describe("Filter conditions for records. Use kintone-get-form-fields tool to discover available field codes and types for an app");
55
+ const orderBySchema = z
56
+ .array(z.object({
57
+ field: z.string().describe("Field code to sort by"),
58
+ order: z
59
+ .enum(["asc", "desc"])
60
+ .optional()
61
+ .describe("Sort order (default: asc)"),
62
+ }))
63
+ .optional()
64
+ .describe("Sort order for results");
65
+ const inputSchema = {
66
+ app: z
67
+ .string()
68
+ .describe("The ID of the app to retrieve records from (numeric value as string)"),
69
+ filters: filtersSchema,
70
+ fields: z
71
+ .array(z.string())
72
+ .optional()
73
+ .describe("Array of field codes to retrieve. If not specified, all fields are retrieved. Use kintone-get-form-fields tool to see available fields"),
74
+ orderBy: orderBySchema,
75
+ limit: z
76
+ .number()
77
+ .min(1)
78
+ .max(500)
79
+ .optional()
80
+ .describe("Maximum number of records to retrieve (1-500)"),
81
+ offset: z.number().min(0).optional().describe("Number of records to skip"),
82
+ };
83
+ const outputSchema = {
84
+ records: z
85
+ .array(recordSchema)
86
+ .describe("Array of records matching the query"),
87
+ totalCount: z.string().describe("Total count of records matching the query"),
88
+ };
89
+ function buildQueryFromFilters(filters) {
90
+ const conditions = [];
91
+ filters.textContains?.forEach((f) => {
92
+ conditions.push(`${f.field} like "${f.value}"`);
93
+ });
94
+ filters.equals?.forEach((f) => {
95
+ if (typeof f.value === "string") {
96
+ conditions.push(`${f.field} = "${f.value}"`);
97
+ }
98
+ else {
99
+ conditions.push(`${f.field} = ${f.value}`);
100
+ }
101
+ });
102
+ filters.dateRange?.forEach((f) => {
103
+ if (f.from)
104
+ conditions.push(`${f.field} >= "${f.from}"`);
105
+ if (f.to)
106
+ conditions.push(`${f.field} <= "${f.to}"`);
107
+ });
108
+ filters.numberRange?.forEach((f) => {
109
+ if (f.min !== undefined)
110
+ conditions.push(`${f.field} >= ${f.min}`);
111
+ if (f.max !== undefined)
112
+ conditions.push(`${f.field} <= ${f.max}`);
113
+ });
114
+ filters.inValues?.forEach((f) => {
115
+ const values = f.values.map((v) => `"${v}"`).join(", ");
116
+ conditions.push(`${f.field} in (${values})`);
117
+ });
118
+ filters.notInValues?.forEach((f) => {
119
+ const values = f.values.map((v) => `"${v}"`).join(", ");
120
+ conditions.push(`${f.field} not in (${values})`);
121
+ });
122
+ return conditions.length > 0 ? conditions.join(" and ") : undefined;
123
+ }
124
+ export const getRecords = createTool("kintone-get-records", {
125
+ title: "Get Records",
126
+ description: "Get multiple records from a kintone app with structured filtering. Use kintone-get-form-fields tool first to discover available fields and their types.",
127
+ inputSchema,
128
+ outputSchema,
129
+ }, async ({ app, filters, fields, orderBy, limit, offset }) => {
130
+ const config = parseKintoneClientConfig();
131
+ const client = getKintoneClient(config);
132
+ let query = filters ? buildQueryFromFilters(filters) : undefined;
133
+ if (orderBy && orderBy.length > 0) {
134
+ const orderClauses = orderBy
135
+ .map((o) => `${o.field} ${o.order || "asc"}`)
136
+ .join(", ");
137
+ query = query
138
+ ? `${query} order by ${orderClauses}`
139
+ : `order by ${orderClauses}`;
140
+ }
141
+ if (limit !== undefined) {
142
+ query = query ? `${query} limit ${limit}` : `limit ${limit}`;
143
+ }
144
+ if (offset !== undefined) {
145
+ query = query ? `${query} offset ${offset}` : `offset ${offset}`;
146
+ }
147
+ const response = await client.record.getRecords({
148
+ app,
149
+ query,
150
+ fields,
151
+ totalCount: true,
152
+ });
153
+ const result = {
154
+ records: response.records,
155
+ totalCount: response.totalCount,
156
+ };
157
+ return {
158
+ structuredContent: result,
159
+ content: [
160
+ {
161
+ type: "text",
162
+ text: JSON.stringify(result, null, 2),
163
+ },
164
+ ],
165
+ };
166
+ });
@@ -0,0 +1,58 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ import { recordSchemaForParameter } from "../../../schema/record/record-for-parameter.js";
6
+ const updateRecordSchema = z.object({
7
+ // updateKey指定は対象外
8
+ id: z.string().describe("Record ID to update (numeric value as string)"),
9
+ record: recordSchemaForParameter.describe("Record data with field codes as keys. Use kintone-get-form-fields tool first to discover available field codes and their types."),
10
+ revision: z
11
+ .string()
12
+ .optional()
13
+ .describe("Expected revision number (numeric value as string). If specified, the update will fail if the current revision doesn't match. Specify -1 or omit to skip revision validation."),
14
+ });
15
+ const inputSchema = {
16
+ app: z
17
+ .string()
18
+ .describe("The ID of the app to update records in (numeric value as string)"),
19
+ records: z
20
+ .array(updateRecordSchema)
21
+ .min(1)
22
+ .max(100)
23
+ .describe("Array of records to update (min 1, max 100). Each record must have an ID to identify which record to update."),
24
+ };
25
+ const outputSchema = {
26
+ records: z
27
+ .array(z.object({
28
+ id: z.string().describe("Record ID"),
29
+ revision: z.string().describe("New revision number after update"),
30
+ }))
31
+ .describe("Array of updated record information"),
32
+ };
33
+ export const updateRecords = createTool("kintone-update-records", {
34
+ title: "Update Records",
35
+ description: "Update multiple records in a kintone app. Use kintone-get-form-fields tool first to discover available field codes and their required formats. Note: Some fields cannot be updated (LOOKUP copies, STATUS, CATEGORY, CALC, ASSIGNEE, auto-calculated fields).",
36
+ inputSchema,
37
+ outputSchema,
38
+ }, async ({ app, records }) => {
39
+ const config = parseKintoneClientConfig();
40
+ const client = getKintoneClient(config);
41
+ const response = await client.record.updateRecords({
42
+ app,
43
+ records,
44
+ upsert: false, // upsertモードは対象外
45
+ });
46
+ const result = {
47
+ records: response.records,
48
+ };
49
+ return {
50
+ structuredContent: result,
51
+ content: [
52
+ {
53
+ type: "text",
54
+ text: JSON.stringify(result, null, 2),
55
+ },
56
+ ],
57
+ };
58
+ });
@@ -0,0 +1,61 @@
1
+ import { z } from "zod";
2
+ import { createTool } from "../../utils.js";
3
+ import { getKintoneClient } from "../../../client.js";
4
+ import { parseKintoneClientConfig } from "../../../config/index.js";
5
+ const statusRecordSchema = z.object({
6
+ id: z.string().describe("Record ID (numeric value as string)"),
7
+ action: z
8
+ .string()
9
+ .describe("Action name to execute. Must be specified in the user's display language if multiple languages are configured. If multiple actions with the same name exist for the current status, an error will occur."),
10
+ assignee: z
11
+ .string()
12
+ .optional()
13
+ .describe("User login name to assign as the assignee. Required when: 1) The destination status has 'Select assignee from these users' enabled and selectable users exist, 2) Setting an assignee for the initial status when returning to it."),
14
+ revision: z
15
+ .string()
16
+ .optional()
17
+ .describe("Expected revision number (numeric value as string). If it doesn't match the actual revision, an error occurs and status is not updated. Specify -1 or omit to skip revision validation."),
18
+ });
19
+ const inputSchema = {
20
+ app: z.string().describe("The ID of the app (numeric value as string)"),
21
+ records: z
22
+ .array(statusRecordSchema)
23
+ .min(1)
24
+ .max(100)
25
+ .describe("Array of records to update status (min 1, max 100). Each record contains id, action, and optionally assignee and revision."),
26
+ };
27
+ const outputSchema = {
28
+ records: z
29
+ .array(z.object({
30
+ id: z.string().describe("Record ID"),
31
+ revision: z
32
+ .string()
33
+ .describe("New revision number after status change. The revision increases by 2 (one for action execution, one for status update)."),
34
+ }))
35
+ .describe("Array of updated record information"),
36
+ };
37
+ export const updateStatuses = createTool("kintone-update-statuses", {
38
+ title: "Update Statuses",
39
+ description: "Update status of multiple records in a kintone app. Requires process management feature to be enabled. Maximum 100 records can be updated at once.",
40
+ inputSchema,
41
+ outputSchema,
42
+ }, async ({ app, records }) => {
43
+ const config = parseKintoneClientConfig();
44
+ const client = getKintoneClient(config);
45
+ const response = await client.record.updateRecordsStatus({
46
+ app,
47
+ records,
48
+ });
49
+ const result = {
50
+ records: response.records,
51
+ };
52
+ return {
53
+ structuredContent: result,
54
+ content: [
55
+ {
56
+ type: "text",
57
+ text: JSON.stringify(result, null, 2),
58
+ },
59
+ ],
60
+ };
61
+ });
@@ -0,0 +1,8 @@
1
+ // Tool creation helper function
2
+ export function createTool(name, config, callback) {
3
+ return {
4
+ name,
5
+ config,
6
+ callback,
7
+ };
8
+ }
@@ -0,0 +1,2 @@
1
+ // This file is auto-generated. Do not edit manually.
2
+ export const version = "1.0.0"; // x-release-please-version