@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.
- package/CHANGELOG.md +49 -0
- package/LICENSE +202 -0
- package/README.md +228 -0
- package/dist/client.js +75 -0
- package/dist/config/command-line.js +25 -0
- package/dist/config/index.js +66 -0
- package/dist/config/schema.js +81 -0
- package/dist/index.js +14 -0
- package/dist/schema/record/record-for-parameter.js +119 -0
- package/dist/schema/record/records.js +182 -0
- package/dist/server.js +20 -0
- package/dist/tool-filters.js +14 -0
- package/dist/tools/index.js +20 -0
- package/dist/tools/kintone/app/get-app.js +70 -0
- package/dist/tools/kintone/app/get-apps.js +112 -0
- package/dist/tools/kintone/app/get-form-fields.js +141 -0
- package/dist/tools/kintone/app/get-process-management.js +88 -0
- package/dist/tools/kintone/record/add-records.js +47 -0
- package/dist/tools/kintone/record/delete-records.js +31 -0
- package/dist/tools/kintone/record/get-records.js +166 -0
- package/dist/tools/kintone/record/update-records.js +58 -0
- package/dist/tools/kintone/record/update-statuses.js +61 -0
- package/dist/tools/utils.js +8 -0
- package/dist/version.js +2 -0
- package/package.json +86 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const PACKAGE_NAME = "@kintone/mcp-server";
|
|
3
|
+
export const configSchema = z
|
|
4
|
+
.object({
|
|
5
|
+
KINTONE_BASE_URL: z
|
|
6
|
+
.string()
|
|
7
|
+
.url()
|
|
8
|
+
.describe("The base URL of your kintone environment (e.g., https://example.cybozu.com)"),
|
|
9
|
+
KINTONE_USERNAME: z
|
|
10
|
+
.string()
|
|
11
|
+
.min(1)
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("Username for authentication"),
|
|
14
|
+
KINTONE_PASSWORD: z
|
|
15
|
+
.string()
|
|
16
|
+
.min(1)
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Password for authentication"),
|
|
19
|
+
KINTONE_API_TOKEN: z
|
|
20
|
+
.string()
|
|
21
|
+
.optional()
|
|
22
|
+
.refine((value) => {
|
|
23
|
+
if (!value)
|
|
24
|
+
return true;
|
|
25
|
+
const tokens = value.split(",").map((t) => t.trim());
|
|
26
|
+
return (tokens.length <= 9 &&
|
|
27
|
+
tokens.every((token) => /^[a-zA-Z0-9]+$/.test(token)));
|
|
28
|
+
}, {
|
|
29
|
+
message: "API tokens must be comma-separated alphanumeric strings (max 9 tokens)",
|
|
30
|
+
})
|
|
31
|
+
.describe("API tokens for authentication (comma-separated, max 9 alphanumeric tokens)"),
|
|
32
|
+
KINTONE_BASIC_AUTH_USERNAME: z
|
|
33
|
+
.string()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Username for Basic authentication"),
|
|
36
|
+
KINTONE_BASIC_AUTH_PASSWORD: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Password for Basic authentication"),
|
|
40
|
+
HTTPS_PROXY: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.refine((value) => !value || value === "" || z.string().url().safeParse(value).success, { message: "Invalid proxy URL format" })
|
|
44
|
+
.describe("HTTPS proxy URL (e.g., http://proxy.example.com:8080)"),
|
|
45
|
+
KINTONE_PFX_FILE_PATH: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Path to PFX client certificate file"),
|
|
49
|
+
KINTONE_PFX_FILE_PASSWORD: z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Password for PFX client certificate file"),
|
|
53
|
+
})
|
|
54
|
+
.refine((data) => {
|
|
55
|
+
// Either username/password or API token must be provided
|
|
56
|
+
const hasUserAuth = data.KINTONE_USERNAME && data.KINTONE_PASSWORD;
|
|
57
|
+
const hasApiToken = data.KINTONE_API_TOKEN;
|
|
58
|
+
return hasUserAuth || hasApiToken;
|
|
59
|
+
}, {
|
|
60
|
+
message: "Either KINTONE_USERNAME/KINTONE_PASSWORD or KINTONE_API_TOKEN must be provided",
|
|
61
|
+
path: [],
|
|
62
|
+
})
|
|
63
|
+
.refine((data) => {
|
|
64
|
+
const hasPath = data.KINTONE_PFX_FILE_PATH;
|
|
65
|
+
const hasPassword = data.KINTONE_PFX_FILE_PASSWORD;
|
|
66
|
+
// Both must be provided together or both must be omitted
|
|
67
|
+
return (hasPath && hasPassword) || (!hasPath && !hasPassword);
|
|
68
|
+
}, {
|
|
69
|
+
message: "Both KINTONE_PFX_FILE_PATH and KINTONE_PFX_FILE_PASSWORD must be provided together",
|
|
70
|
+
path: ["KINTONE_PFX_FILE_PATH"],
|
|
71
|
+
})
|
|
72
|
+
.refine((data) => {
|
|
73
|
+
const hasBasicUsername = data.KINTONE_BASIC_AUTH_USERNAME;
|
|
74
|
+
const hasBasicPassword = data.KINTONE_BASIC_AUTH_PASSWORD;
|
|
75
|
+
// Both must be provided together or both must be omitted
|
|
76
|
+
return ((hasBasicUsername && hasBasicPassword) ||
|
|
77
|
+
(!hasBasicUsername && !hasBasicPassword));
|
|
78
|
+
}, {
|
|
79
|
+
message: "Both KINTONE_BASIC_AUTH_USERNAME and KINTONE_BASIC_AUTH_PASSWORD must be provided together",
|
|
80
|
+
path: ["KINTONE_BASIC_AUTH_USERNAME"],
|
|
81
|
+
});
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createServer } from "./server.js";
|
|
4
|
+
import { parseKintoneClientConfig } from "./config/index.js";
|
|
5
|
+
import { getKintoneClient } from "./client.js";
|
|
6
|
+
const main = async () => {
|
|
7
|
+
const transport = new StdioServerTransport();
|
|
8
|
+
console.error("Starting server...");
|
|
9
|
+
const config = parseKintoneClientConfig();
|
|
10
|
+
getKintoneClient(config);
|
|
11
|
+
const server = createServer();
|
|
12
|
+
await server.connect(transport);
|
|
13
|
+
};
|
|
14
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// kintoneレコードのフィールド値用共通スキーマ
|
|
3
|
+
const _recordValueSchema = z.union([
|
|
4
|
+
// 文字列系フィールド (SINGLE_LINE_TEXT, MULTI_LINE_TEXT, RICH_TEXT, LINK)
|
|
5
|
+
z.object({
|
|
6
|
+
value: z
|
|
7
|
+
.string()
|
|
8
|
+
.nullable()
|
|
9
|
+
.describe("Text value for string fields (SINGLE_LINE_TEXT, MULTI_LINE_TEXT, RICH_TEXT, LINK)"),
|
|
10
|
+
}),
|
|
11
|
+
// 数値フィールド (NUMBER) - 文字列として送信
|
|
12
|
+
z.object({
|
|
13
|
+
value: z
|
|
14
|
+
.string()
|
|
15
|
+
.nullable()
|
|
16
|
+
.describe("Numeric value as string for NUMBER fields (e.g., '123.45'). Only half-width numbers, +/- signs, decimal point (.), and exponential notation (e/E) are allowed. Empty string, null, or undefined for empty values."),
|
|
17
|
+
}),
|
|
18
|
+
// 日付・時間系フィールド (DATE, TIME, DATETIME)
|
|
19
|
+
z.object({
|
|
20
|
+
value: z
|
|
21
|
+
.string()
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe("Date/time value for DATE, TIME, DATETIME fields (DATE: 'YYYY-MM-DD', TIME: 'HH:mm', DATETIME: 'YYYY-MM-DDTHH:mm:ssZ')"),
|
|
24
|
+
}),
|
|
25
|
+
// 単一選択フィールド (RADIO_BUTTON, DROP_DOWN)
|
|
26
|
+
z.object({
|
|
27
|
+
value: z
|
|
28
|
+
.string()
|
|
29
|
+
.nullable()
|
|
30
|
+
.describe("Selected option value for RADIO_BUTTON and DROP_DOWN fields"),
|
|
31
|
+
}),
|
|
32
|
+
// 複数選択系フィールド (CHECK_BOX, MULTI_SELECT)
|
|
33
|
+
z.object({
|
|
34
|
+
value: z
|
|
35
|
+
.array(z.string())
|
|
36
|
+
.min(0)
|
|
37
|
+
.nullable()
|
|
38
|
+
.describe("Array of selected option values for CHECK_BOX and MULTI_SELECT fields"),
|
|
39
|
+
}),
|
|
40
|
+
// ユーザー選択フィールド (USER_SELECT)
|
|
41
|
+
z.object({
|
|
42
|
+
value: z
|
|
43
|
+
.array(z.object({
|
|
44
|
+
code: z.string().describe("User code/login name"),
|
|
45
|
+
}))
|
|
46
|
+
.nullable()
|
|
47
|
+
.describe("Array of selected users for USER_SELECT fields"),
|
|
48
|
+
}),
|
|
49
|
+
// 組織選択フィールド (ORGANIZATION_SELECT)
|
|
50
|
+
z.object({
|
|
51
|
+
value: z
|
|
52
|
+
.array(z.object({
|
|
53
|
+
code: z.string().describe("Organization code"),
|
|
54
|
+
}))
|
|
55
|
+
.nullable()
|
|
56
|
+
.describe("Array of selected organizations for ORGANIZATION_SELECT fields"),
|
|
57
|
+
}),
|
|
58
|
+
// グループ選択フィールド (GROUP_SELECT)
|
|
59
|
+
z.object({
|
|
60
|
+
value: z
|
|
61
|
+
.array(z.object({
|
|
62
|
+
code: z.string().describe("Group code"),
|
|
63
|
+
}))
|
|
64
|
+
.nullable()
|
|
65
|
+
.describe("Array of selected groups for GROUP_SELECT fields"),
|
|
66
|
+
}),
|
|
67
|
+
// 作成者・更新者フィールド (CREATOR, MODIFIER) - 登録時はcodeのみ
|
|
68
|
+
z.object({
|
|
69
|
+
value: z
|
|
70
|
+
.object({
|
|
71
|
+
code: z.string().describe("User code/login name"),
|
|
72
|
+
})
|
|
73
|
+
.nullable()
|
|
74
|
+
.describe("User information for CREATOR and MODIFIER fields (registration format with code only)"),
|
|
75
|
+
}),
|
|
76
|
+
// サブテーブルフィールド (SUBTABLE - kintone specific table field type)
|
|
77
|
+
z.object({
|
|
78
|
+
value: z
|
|
79
|
+
.array(z.object({
|
|
80
|
+
id: z.string().optional().describe("Row ID (optional for new rows)"),
|
|
81
|
+
value: z
|
|
82
|
+
.record(z.any())
|
|
83
|
+
.describe("Field values within this subtable row"),
|
|
84
|
+
}))
|
|
85
|
+
.nullable()
|
|
86
|
+
.describe("Array of subtable rows for SUBTABLE fields"),
|
|
87
|
+
}),
|
|
88
|
+
// ルックアップフィールド (LOOKUP) - キー項目の型に応じて文字列または数値文字列
|
|
89
|
+
z.object({
|
|
90
|
+
value: z
|
|
91
|
+
.string()
|
|
92
|
+
.nullable()
|
|
93
|
+
.describe("Lookup field value for LOOKUP fields (string for SINGLE_LINE_TEXT key, numeric string for NUMBER key)"),
|
|
94
|
+
}),
|
|
95
|
+
// 作成日時・更新日時フィールド (CREATED_TIME, UPDATED_TIME) - 登録時のみ指定可能
|
|
96
|
+
z.object({
|
|
97
|
+
value: z
|
|
98
|
+
.string()
|
|
99
|
+
.nullable()
|
|
100
|
+
.describe("Date/time value for CREATED_TIME and UPDATED_TIME fields (ISO 8601 format, only for registration)"),
|
|
101
|
+
}),
|
|
102
|
+
]);
|
|
103
|
+
export const recordSchemaForParameter = z.record(_recordValueSchema.or(z.object({
|
|
104
|
+
value: z
|
|
105
|
+
.array(z.object({
|
|
106
|
+
fileKey: z
|
|
107
|
+
.string()
|
|
108
|
+
.describe("File key obtained from file upload API"),
|
|
109
|
+
}))
|
|
110
|
+
.nullable()
|
|
111
|
+
.describe("Array of uploaded files for FILE fields"),
|
|
112
|
+
})));
|
|
113
|
+
// ファイルアップロードツール未実装のため現在はinputとしては指定不可
|
|
114
|
+
// TODO: ファイルアップロードツール実装後に調整
|
|
115
|
+
export const recordSchemaForParameterWithoutFile = z.record(_recordValueSchema.or(z.object({
|
|
116
|
+
value: z
|
|
117
|
+
.never()
|
|
118
|
+
.describe("FILE fields are not supported yet (file upload tool not implemented)"),
|
|
119
|
+
})));
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const recordValueSchema = z.union([
|
|
3
|
+
z.object({
|
|
4
|
+
type: z.literal("SINGLE_LINE_TEXT"),
|
|
5
|
+
value: z.string().nullable(),
|
|
6
|
+
}),
|
|
7
|
+
z.object({
|
|
8
|
+
type: z.literal("MULTI_LINE_TEXT"),
|
|
9
|
+
value: z.string().nullable(),
|
|
10
|
+
}),
|
|
11
|
+
z.object({
|
|
12
|
+
type: z.literal("RICH_TEXT"),
|
|
13
|
+
value: z.string().nullable(),
|
|
14
|
+
}),
|
|
15
|
+
z.object({
|
|
16
|
+
type: z.literal("NUMBER"),
|
|
17
|
+
value: z.string().nullable(),
|
|
18
|
+
}),
|
|
19
|
+
z.object({
|
|
20
|
+
type: z.literal("DATE"),
|
|
21
|
+
value: z.string().nullable(),
|
|
22
|
+
}),
|
|
23
|
+
z.object({
|
|
24
|
+
type: z.literal("DATETIME"),
|
|
25
|
+
value: z.string().nullable(),
|
|
26
|
+
}),
|
|
27
|
+
z.object({
|
|
28
|
+
type: z.literal("DROP_DOWN"),
|
|
29
|
+
value: z.string().nullable(),
|
|
30
|
+
}),
|
|
31
|
+
z.object({
|
|
32
|
+
type: z.literal("CHECK_BOX"),
|
|
33
|
+
value: z.array(z.string()).nullable(),
|
|
34
|
+
}),
|
|
35
|
+
z.object({
|
|
36
|
+
type: z.literal("MULTI_SELECT"),
|
|
37
|
+
value: z.array(z.string()).nullable(),
|
|
38
|
+
}),
|
|
39
|
+
z.object({
|
|
40
|
+
type: z.literal("RADIO_BUTTON"),
|
|
41
|
+
value: z.string().nullable(),
|
|
42
|
+
}),
|
|
43
|
+
z.object({
|
|
44
|
+
type: z.literal("USER_SELECT"),
|
|
45
|
+
value: z
|
|
46
|
+
.array(z.object({
|
|
47
|
+
code: z.string(),
|
|
48
|
+
name: z.string(),
|
|
49
|
+
}))
|
|
50
|
+
.nullable(),
|
|
51
|
+
}),
|
|
52
|
+
z.object({
|
|
53
|
+
type: z.literal("CREATOR"),
|
|
54
|
+
value: z
|
|
55
|
+
.object({
|
|
56
|
+
code: z.string(),
|
|
57
|
+
name: z.string(),
|
|
58
|
+
})
|
|
59
|
+
.nullable(),
|
|
60
|
+
}),
|
|
61
|
+
z.object({
|
|
62
|
+
type: z.literal("CREATED_TIME"),
|
|
63
|
+
value: z.string().nullable(),
|
|
64
|
+
}),
|
|
65
|
+
z.object({
|
|
66
|
+
type: z.literal("MODIFIER"),
|
|
67
|
+
value: z
|
|
68
|
+
.object({
|
|
69
|
+
code: z.string(),
|
|
70
|
+
name: z.string(),
|
|
71
|
+
})
|
|
72
|
+
.nullable(),
|
|
73
|
+
}),
|
|
74
|
+
z.object({
|
|
75
|
+
type: z.literal("UPDATED_TIME"),
|
|
76
|
+
value: z.string().nullable(),
|
|
77
|
+
}),
|
|
78
|
+
z.object({
|
|
79
|
+
type: z.literal("RECORD_NUMBER"),
|
|
80
|
+
value: z.string().nullable(),
|
|
81
|
+
}),
|
|
82
|
+
z.object({
|
|
83
|
+
type: z.literal("__ID__"),
|
|
84
|
+
value: z.string().nullable(),
|
|
85
|
+
}),
|
|
86
|
+
z.object({
|
|
87
|
+
type: z.literal("__REVISION__"),
|
|
88
|
+
value: z.string().nullable(),
|
|
89
|
+
}),
|
|
90
|
+
z.object({
|
|
91
|
+
type: z.literal("CATEGORY"),
|
|
92
|
+
value: z.array(z.string()).nullable(),
|
|
93
|
+
}),
|
|
94
|
+
z.object({
|
|
95
|
+
type: z.literal("STATUS"),
|
|
96
|
+
value: z.string().nullable(),
|
|
97
|
+
}),
|
|
98
|
+
z.object({
|
|
99
|
+
type: z.literal("STATUS_ASSIGNEE"),
|
|
100
|
+
value: z
|
|
101
|
+
.array(z.object({
|
|
102
|
+
code: z.string(),
|
|
103
|
+
name: z.string(),
|
|
104
|
+
}))
|
|
105
|
+
.nullable(),
|
|
106
|
+
}),
|
|
107
|
+
z.object({
|
|
108
|
+
type: z.literal("FILE"),
|
|
109
|
+
value: z
|
|
110
|
+
.array(z.object({
|
|
111
|
+
contentType: z.string(),
|
|
112
|
+
fileKey: z.string(),
|
|
113
|
+
name: z.string(),
|
|
114
|
+
size: z.string(),
|
|
115
|
+
}))
|
|
116
|
+
.nullable(),
|
|
117
|
+
}),
|
|
118
|
+
z.object({
|
|
119
|
+
type: z.literal("LINK"),
|
|
120
|
+
value: z.string().nullable(),
|
|
121
|
+
}),
|
|
122
|
+
z.object({
|
|
123
|
+
type: z.literal("CALC"),
|
|
124
|
+
value: z.string().nullable(),
|
|
125
|
+
}),
|
|
126
|
+
z.object({
|
|
127
|
+
type: z.literal("LOOKUP"),
|
|
128
|
+
value: z.string().nullable(),
|
|
129
|
+
}),
|
|
130
|
+
z.object({
|
|
131
|
+
type: z.literal("TIME"),
|
|
132
|
+
value: z.string().nullable(),
|
|
133
|
+
}),
|
|
134
|
+
z.object({
|
|
135
|
+
type: z.literal("SUBTABLE"),
|
|
136
|
+
value: z
|
|
137
|
+
.array(z.object({
|
|
138
|
+
id: z.string(),
|
|
139
|
+
value: z.record(z.any()),
|
|
140
|
+
}))
|
|
141
|
+
.nullable(),
|
|
142
|
+
}),
|
|
143
|
+
z.object({
|
|
144
|
+
type: z.literal("GROUP"),
|
|
145
|
+
value: z.array(z.any()).nullable(),
|
|
146
|
+
}),
|
|
147
|
+
z.object({
|
|
148
|
+
type: z.literal("REFERENCE_TABLE"),
|
|
149
|
+
value: z.null(),
|
|
150
|
+
}),
|
|
151
|
+
z.object({
|
|
152
|
+
type: z.literal("ORGANIZATION_SELECT"),
|
|
153
|
+
value: z
|
|
154
|
+
.array(z.object({
|
|
155
|
+
code: z.string(),
|
|
156
|
+
name: z.string(),
|
|
157
|
+
}))
|
|
158
|
+
.nullable(),
|
|
159
|
+
}),
|
|
160
|
+
z.object({
|
|
161
|
+
type: z.literal("GROUP_SELECT"),
|
|
162
|
+
value: z
|
|
163
|
+
.array(z.object({
|
|
164
|
+
code: z.string(),
|
|
165
|
+
name: z.string(),
|
|
166
|
+
}))
|
|
167
|
+
.nullable(),
|
|
168
|
+
}),
|
|
169
|
+
z.object({
|
|
170
|
+
type: z.literal("SPACER"),
|
|
171
|
+
value: z.null(),
|
|
172
|
+
}),
|
|
173
|
+
z.object({
|
|
174
|
+
type: z.literal("HR"),
|
|
175
|
+
value: z.null(),
|
|
176
|
+
}),
|
|
177
|
+
z.object({
|
|
178
|
+
type: z.literal("LABEL"),
|
|
179
|
+
value: z.null(),
|
|
180
|
+
}),
|
|
181
|
+
]);
|
|
182
|
+
export const recordSchema = z.record(recordValueSchema);
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { tools } from "./tools/index.js";
|
|
3
|
+
import { version } from "./version.js";
|
|
4
|
+
import { PACKAGE_NAME, parseKintoneClientConfig } from "./config/index.js";
|
|
5
|
+
import { shouldEnableTool } from "./tool-filters.js";
|
|
6
|
+
export const createServer = () => {
|
|
7
|
+
const server = new McpServer({
|
|
8
|
+
name: PACKAGE_NAME,
|
|
9
|
+
version,
|
|
10
|
+
}, {
|
|
11
|
+
capabilities: {
|
|
12
|
+
tools: {},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
const config = parseKintoneClientConfig();
|
|
16
|
+
tools
|
|
17
|
+
.filter((tool) => shouldEnableTool(tool.name, config))
|
|
18
|
+
.forEach((tool) => server.registerTool(tool.name, tool.config, tool.callback));
|
|
19
|
+
return server;
|
|
20
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const filterRules = [
|
|
2
|
+
{
|
|
3
|
+
condition: (config) => config.isApiTokenAuth,
|
|
4
|
+
excludeTools: ["kintone-get-apps"],
|
|
5
|
+
},
|
|
6
|
+
];
|
|
7
|
+
export function shouldEnableTool(toolName, config) {
|
|
8
|
+
for (const rule of filterRules) {
|
|
9
|
+
if (rule.condition(config) && rule.excludeTools.includes(toolName)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { addRecords } from "./kintone/record/add-records.js";
|
|
2
|
+
import { deleteRecords } from "./kintone/record/delete-records.js";
|
|
3
|
+
import { getRecords } from "./kintone/record/get-records.js";
|
|
4
|
+
import { updateRecords } from "./kintone/record/update-records.js";
|
|
5
|
+
import { getApp } from "./kintone/app/get-app.js";
|
|
6
|
+
import { getApps } from "./kintone/app/get-apps.js";
|
|
7
|
+
import { getFormFields } from "./kintone/app/get-form-fields.js";
|
|
8
|
+
import { getProcessManagement } from "./kintone/app/get-process-management.js";
|
|
9
|
+
import { updateStatuses } from "./kintone/record/update-statuses.js";
|
|
10
|
+
export const tools = [
|
|
11
|
+
getApp,
|
|
12
|
+
getApps,
|
|
13
|
+
getFormFields,
|
|
14
|
+
getProcessManagement,
|
|
15
|
+
updateStatuses,
|
|
16
|
+
addRecords,
|
|
17
|
+
deleteRecords,
|
|
18
|
+
getRecords,
|
|
19
|
+
updateRecords,
|
|
20
|
+
];
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
appId: z
|
|
7
|
+
.string()
|
|
8
|
+
.describe("The ID of the app to retrieve (numeric value as string)"),
|
|
9
|
+
};
|
|
10
|
+
const outputSchema = {
|
|
11
|
+
appId: z.string().describe("The app ID"),
|
|
12
|
+
code: z.string().describe("The app code (empty string if not set)"),
|
|
13
|
+
name: z.string().describe("The app name"),
|
|
14
|
+
description: z
|
|
15
|
+
.string()
|
|
16
|
+
.describe("The app description (empty string if not set)"),
|
|
17
|
+
spaceId: z
|
|
18
|
+
.string()
|
|
19
|
+
.nullable()
|
|
20
|
+
.describe("The space ID (null if not in a space)"),
|
|
21
|
+
threadId: z
|
|
22
|
+
.string()
|
|
23
|
+
.nullable()
|
|
24
|
+
.describe("The thread ID (null if not in a space)"),
|
|
25
|
+
createdAt: z.string().describe("The creation date and time"),
|
|
26
|
+
creator: z
|
|
27
|
+
.object({
|
|
28
|
+
code: z.string().describe("The creator's user code"),
|
|
29
|
+
name: z.string().describe("The creator's display name"),
|
|
30
|
+
})
|
|
31
|
+
.describe("The creator information"),
|
|
32
|
+
modifiedAt: z.string().describe("The last modified date and time"),
|
|
33
|
+
modifier: z
|
|
34
|
+
.object({
|
|
35
|
+
code: z.string().describe("The modifier's user code"),
|
|
36
|
+
name: z.string().describe("The modifier's display name"),
|
|
37
|
+
})
|
|
38
|
+
.describe("The modifier information"),
|
|
39
|
+
};
|
|
40
|
+
export const getApp = createTool("kintone-get-app", {
|
|
41
|
+
title: "Get App",
|
|
42
|
+
description: "Get app settings from kintone",
|
|
43
|
+
inputSchema,
|
|
44
|
+
outputSchema,
|
|
45
|
+
}, async ({ appId }) => {
|
|
46
|
+
const config = parseKintoneClientConfig();
|
|
47
|
+
const client = getKintoneClient(config);
|
|
48
|
+
const app = await client.app.getApp({ id: appId });
|
|
49
|
+
const result = {
|
|
50
|
+
appId: app.appId,
|
|
51
|
+
code: app.code,
|
|
52
|
+
name: app.name,
|
|
53
|
+
description: app.description,
|
|
54
|
+
spaceId: app.spaceId,
|
|
55
|
+
threadId: app.threadId,
|
|
56
|
+
createdAt: app.createdAt,
|
|
57
|
+
creator: app.creator,
|
|
58
|
+
modifiedAt: app.modifiedAt,
|
|
59
|
+
modifier: app.modifier,
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
structuredContent: result,
|
|
63
|
+
content: [
|
|
64
|
+
{
|
|
65
|
+
type: "text",
|
|
66
|
+
text: JSON.stringify(result, null, 2),
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
ids: z
|
|
7
|
+
.array(z.string())
|
|
8
|
+
.max(100)
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Array of app IDs (numeric values as strings, max 100)"),
|
|
11
|
+
codes: z
|
|
12
|
+
.array(z.string().max(64))
|
|
13
|
+
.max(100)
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Array of app codes (max 64 characters each)"),
|
|
16
|
+
name: z
|
|
17
|
+
.string()
|
|
18
|
+
.max(64)
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("App name for partial match search"),
|
|
21
|
+
spaceIds: z
|
|
22
|
+
.array(z.string())
|
|
23
|
+
.max(100)
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Array of space IDs (numeric values as strings, max 100)"),
|
|
26
|
+
offset: z
|
|
27
|
+
.number()
|
|
28
|
+
.min(0)
|
|
29
|
+
.optional()
|
|
30
|
+
.default(0)
|
|
31
|
+
.describe("Offset for pagination (default: 0)"),
|
|
32
|
+
limit: z
|
|
33
|
+
.number()
|
|
34
|
+
.min(1)
|
|
35
|
+
.max(100)
|
|
36
|
+
.optional()
|
|
37
|
+
.default(100)
|
|
38
|
+
.describe("Number of apps to retrieve (1-100, default: 100)"),
|
|
39
|
+
};
|
|
40
|
+
const appSchema = z.object({
|
|
41
|
+
appId: z.string().describe("The app ID"),
|
|
42
|
+
code: z.string().describe("The app code (empty string if not set)"),
|
|
43
|
+
name: z.string().describe("The app name"),
|
|
44
|
+
description: z
|
|
45
|
+
.string()
|
|
46
|
+
.describe("The app description (empty string if not set)"),
|
|
47
|
+
spaceId: z
|
|
48
|
+
.string()
|
|
49
|
+
.nullable()
|
|
50
|
+
.describe("The space ID (null if not in a space)"),
|
|
51
|
+
threadId: z
|
|
52
|
+
.string()
|
|
53
|
+
.nullable()
|
|
54
|
+
.describe("The thread ID (null if not in a space)"),
|
|
55
|
+
createdAt: z.string().describe("The creation date and time"),
|
|
56
|
+
creator: z
|
|
57
|
+
.object({
|
|
58
|
+
code: z.string().describe("The creator's user code"),
|
|
59
|
+
name: z.string().describe("The creator's display name"),
|
|
60
|
+
})
|
|
61
|
+
.describe("The creator information"),
|
|
62
|
+
modifiedAt: z.string().describe("The last modified date and time"),
|
|
63
|
+
modifier: z
|
|
64
|
+
.object({
|
|
65
|
+
code: z.string().describe("The modifier's user code"),
|
|
66
|
+
name: z.string().describe("The modifier's display name"),
|
|
67
|
+
})
|
|
68
|
+
.describe("The modifier information"),
|
|
69
|
+
});
|
|
70
|
+
const outputSchema = {
|
|
71
|
+
apps: z.array(appSchema).describe("Array of app information"),
|
|
72
|
+
};
|
|
73
|
+
export const getApps = createTool("kintone-get-apps", {
|
|
74
|
+
title: "Get Apps",
|
|
75
|
+
description: "Get multiple app settings from kintone",
|
|
76
|
+
inputSchema,
|
|
77
|
+
outputSchema,
|
|
78
|
+
}, async ({ ids, codes, name, spaceIds, offset, limit }) => {
|
|
79
|
+
const config = parseKintoneClientConfig();
|
|
80
|
+
const client = getKintoneClient(config);
|
|
81
|
+
const response = await client.app.getApps({
|
|
82
|
+
ids,
|
|
83
|
+
codes,
|
|
84
|
+
name,
|
|
85
|
+
spaceIds,
|
|
86
|
+
offset,
|
|
87
|
+
limit,
|
|
88
|
+
});
|
|
89
|
+
const result = {
|
|
90
|
+
apps: response.apps.map((app) => ({
|
|
91
|
+
appId: app.appId,
|
|
92
|
+
code: app.code,
|
|
93
|
+
name: app.name,
|
|
94
|
+
description: app.description,
|
|
95
|
+
spaceId: app.spaceId,
|
|
96
|
+
threadId: app.threadId,
|
|
97
|
+
createdAt: app.createdAt,
|
|
98
|
+
creator: app.creator,
|
|
99
|
+
modifiedAt: app.modifiedAt,
|
|
100
|
+
modifier: app.modifier,
|
|
101
|
+
})),
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
structuredContent: result,
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: JSON.stringify(result, null, 2),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
});
|