@kintone/mcp-server 1.0.0 → 1.2.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +35 -14
  3. package/dist/{client.js → client/index.js} +4 -9
  4. package/dist/client/types/client.js +1 -0
  5. package/dist/config/command-line.js +2 -1
  6. package/dist/config/index.js +30 -62
  7. package/dist/config/parser.js +72 -0
  8. package/dist/config/schema.js +4 -0
  9. package/dist/config/types/config.js +1 -0
  10. package/dist/index.js +16 -6
  11. package/dist/lib/filesystem.js +47 -0
  12. package/dist/schema/app/field-properties.js +330 -0
  13. package/dist/schema/app/form-layout.js +105 -0
  14. package/dist/schema/app/index.js +3 -0
  15. package/dist/schema/app/properties-parameter.js +638 -0
  16. package/dist/schema/record/index.js +2 -0
  17. package/dist/schema/record/records.js +1 -1
  18. package/dist/server/index.js +17 -0
  19. package/dist/server/tool-filters.js +14 -0
  20. package/dist/server/types/server.js +1 -0
  21. package/dist/tools/factory.js +10 -0
  22. package/dist/tools/index.js +23 -0
  23. package/dist/tools/kintone/app/add-app.js +40 -0
  24. package/dist/tools/kintone/app/add-form-fields.js +50 -0
  25. package/dist/tools/kintone/app/delete-form-fields.js +51 -0
  26. package/dist/tools/kintone/app/deploy-app.js +48 -0
  27. package/dist/tools/kintone/app/get-app-deploy-status.js +42 -0
  28. package/dist/tools/kintone/app/get-app.js +7 -8
  29. package/dist/tools/kintone/app/get-apps.js +7 -8
  30. package/dist/tools/kintone/app/get-form-fields.js +20 -107
  31. package/dist/tools/kintone/app/get-form-layout.js +45 -0
  32. package/dist/tools/kintone/app/get-general-settings.js +119 -0
  33. package/dist/tools/kintone/app/get-process-management.js +12 -8
  34. package/dist/tools/kintone/app/update-form-fields.js +50 -0
  35. package/dist/tools/kintone/app/update-form-layout.js +48 -0
  36. package/dist/tools/kintone/app/update-general-settings.js +119 -0
  37. package/dist/tools/kintone/file/download-file.js +49 -0
  38. package/dist/tools/kintone/record/add-records.js +8 -9
  39. package/dist/tools/kintone/record/delete-records.js +7 -8
  40. package/dist/tools/kintone/record/get-records.js +8 -9
  41. package/dist/tools/kintone/record/update-records.js +8 -9
  42. package/dist/tools/kintone/record/update-statuses.js +7 -8
  43. package/dist/tools/types/tool.js +1 -0
  44. package/dist/version.js +1 -1
  45. package/package.json +11 -6
  46. package/dist/server.js +0 -20
  47. package/dist/tool-filters.js +0 -14
  48. package/dist/tools/utils.js +0 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.0](https://github.com/kintone/mcp-server/compare/1.1.0...1.2.0) (2025-10-01)
4
+
5
+
6
+ ### Features
7
+
8
+ * add app management tools ([#113](https://github.com/kintone/mcp-server/issues/113)) ([453bd50](https://github.com/kintone/mcp-server/commit/453bd50fc9080ee452dfeaf2524bd0374bd70d74))
9
+ * add update-form tools ([#115](https://github.com/kintone/mcp-server/issues/115)) ([c98b0cb](https://github.com/kintone/mcp-server/commit/c98b0cb3a7356cef2ee4314f76a3b8cde00b3ae3))
10
+
11
+ ## [1.1.0](https://github.com/kintone/mcp-server/compare/1.0.0...1.1.0) (2025-09-18)
12
+
13
+
14
+ ### Features
15
+
16
+ * add the tool for downloading file ([#80](https://github.com/kintone/mcp-server/issues/80)) ([6cead9e](https://github.com/kintone/mcp-server/commit/6cead9ed1891a4ce0aa26978a52dd7df27e195ff))
17
+ * add tools for get app settings ([#114](https://github.com/kintone/mcp-server/issues/114)) ([470e755](https://github.com/kintone/mcp-server/commit/470e75555cfeef9fbf582aab504e24528c3f94cd))
18
+ * supports preview ([#112](https://github.com/kintone/mcp-server/issues/112)) ([3bb032e](https://github.com/kintone/mcp-server/commit/3bb032e00bd0532cac832dbdd9fc6aec1e7255d8))
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **deps:** update dependency @modelcontextprotocol/sdk to ^1.17.5 ([#100](https://github.com/kintone/mcp-server/issues/100)) ([ad8ce6e](https://github.com/kintone/mcp-server/commit/ad8ce6e2557c4ccbf10f2d0895ceaebbde3d5083))
24
+
3
25
  ## [1.0.0](https://github.com/kintone/mcp-server/compare/0.1.0...1.0.0) (2025-08-27)
4
26
 
5
27
 
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  [ci-badge]: https://github.com/kintone/mcp-server/actions/workflows/ci.yaml/badge.svg
9
9
  [ci-url]: https://github.com/kintone/mcp-server/actions/workflows/ci.yaml
10
- [npm-badge]: https://badge.fury.io/js/@kintone%2Fmcp-server.svg
10
+ [npm-badge]: https://badge.fury.io/js/@kintone%2Fmcp-server.svg?icon=si%3Anpm
11
11
  [npm-url]: https://badge.fury.io/js/@kintone%2Fmcp-server
12
12
  [license-badge]: https://img.shields.io/badge/License-Apache_2.0-blue.svg
13
13
  [license-url]: LICENSE
@@ -38,9 +38,11 @@ kintoneの公式ローカルMCPサーバーです。
38
38
  - [プロキシ設定](#%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E8%A8%AD%E5%AE%9A)
39
39
  - [ツール一覧](#%E3%83%84%E3%83%BC%E3%83%AB%E4%B8%80%E8%A6%A7)
40
40
  - [ドキュメント](#%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88)
41
+ - [使用上の注意](#%E4%BD%BF%E7%94%A8%E4%B8%8A%E3%81%AE%E6%B3%A8%E6%84%8F)
42
+ - [`kintone-download-file`ツールの注意点](#kintone-download-file%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9)
41
43
  - [制限事項](#%E5%88%B6%E9%99%90%E4%BA%8B%E9%A0%85)
42
44
  - [レコード操作の制限](#%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E6%93%8D%E4%BD%9C%E3%81%AE%E5%88%B6%E9%99%90)
43
- - [機能制限](#%E6%A9%9F%E8%83%BD%E5%88%B6%E9%99%90)
45
+ - [その他の制限](#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E5%88%B6%E9%99%90)
44
46
  - [サポート方針](#%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E6%96%B9%E9%87%9D)
45
47
  - [コントリビューション](#%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)
46
48
  - [ライセンス](#%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9)
@@ -160,6 +162,7 @@ DXTファイルをインストールした場合、追加の手順は必要あ
160
162
  | `--pfx-file-path` | `KINTONE_PFX_FILE_PATH` | PFXファイルのパス(クライアント証明書認証用) | - |
161
163
  | `--pfx-file-password` | `KINTONE_PFX_FILE_PASSWORD` | PFXファイルのパスワード | - |
162
164
  | `--proxy` | `HTTPS_PROXY` | HTTPSプロキシのURL(例: `http://proxy.example.com:8080`) | - |
165
+ | `--attachments-dir` | `KINTONE_ATTACHMENTS_DIR` | ダウンロードしたファイルの保存先 | - |
163
166
 
164
167
  ※1: `KINTONE_USERNAME` & `KINTONE_PASSWORD` または `KINTONE_API_TOKEN` のいずれかが必須
165
168
 
@@ -183,22 +186,41 @@ export HTTPS_PROXY="http://username:password@proxy.example.com:8080"
183
186
 
184
187
  ## ツール一覧
185
188
 
186
- | ツール名 | 説明 |
187
- | -------------------------------- | -------------------------------- |
188
- | `kintone-get-apps` | 複数のアプリ情報を取得 |
189
- | `kintone-get-app` | 単一アプリの詳細情報を取得 |
190
- | `kintone-get-form-fields` | アプリのフィールド設定を取得 |
191
- | `kintone-get-process-management` | プロセス管理設定を取得 |
192
- | `kintone-get-records` | 複数のレコードを取得 |
193
- | `kintone-add-records` | 複数のレコードを追加 |
194
- | `kintone-update-records` | 複数のレコードを更新 |
195
- | `kintone-delete-records` | 複数のレコードを削除 |
196
- | `kintone-update-statuses` | 複数のレコードのステータスを更新 |
189
+ | ツール名 | 説明 |
190
+ | --------------------------------- | -------------------------------------- |
191
+ | `kintone-get-apps` | 複数のアプリ情報を取得 |
192
+ | `kintone-get-app` | 単一アプリの詳細情報を取得 |
193
+ | `kintone-get-form-fields` | アプリのフィールド設定を取得 |
194
+ | `kintone-get-form-layout` | アプリのフォームレイアウトを取得 |
195
+ | `kintone-update-form-fields` | アプリのフィールド設定を更新 |
196
+ | `kintone-update-form-layout` | アプリのフォームレイアウトを更新 |
197
+ | `kintone-delete-form-fields` | アプリのフィールドを削除 |
198
+ | `kintone-get-process-management` | プロセス管理設定を取得 |
199
+ | `kintone-get-app-deploy-status` | アプリ設定の運用環境への反映状況確認 |
200
+ | `kintone-get-general-settings` | アプリの一般設定を取得 |
201
+ | `kintone-add-form-fields` | アプリにフィールドを追加 |
202
+ | `kintone-get-records` | 複数のレコードを取得 |
203
+ | `kintone-add-records` | 複数のレコードを追加 |
204
+ | `kintone-update-records` | 複数のレコードを更新 |
205
+ | `kintone-delete-records` | 複数のレコードを削除 |
206
+ | `kintone-update-statuses` | 複数のレコードのステータスを更新 |
207
+ | `kintone-add-app` | 動作テスト環境にアプリを作成 |
208
+ | `kintone-deploy-app` | アプリ設定を運用環境へ反映 |
209
+ | `kintone-update-general-settings` | アプリの一般設定を変更 |
210
+ | `kintone-download-file` | 添付ファイルフィールドのファイルを保存 |
197
211
 
198
212
  ## ドキュメント
199
213
 
200
214
  - [認証設定ガイド](./docs/ja/authentication.md) - 認証方法の詳細と設定例
201
215
 
216
+ ## 使用上の注意
217
+
218
+ ### `kintone-download-file`ツールの注意点
219
+
220
+ - ダウンロードしたファイルは、`--attachments-dir`または`KINTONE_ATTACHMENTS_DIR`で指定したディレクトリに保存されます。
221
+ - `--attachments-dir`または`KINTONE_ATTACHMENTS_DIR`を指定しない場合はツール実行時にエラーになります。
222
+ - `--attachments-dir`または`KINTONE_ATTACHMENTS_DIR`に存在しないディレクトリを指定した場合は、ディレクトリを新規作成してからそこに保存されます。
223
+
202
224
  ## 制限事項
203
225
 
204
226
  ### レコード操作の制限
@@ -209,7 +231,6 @@ export HTTPS_PROXY="http://username:password@proxy.example.com:8080"
209
231
  ### その他の制限
210
232
 
211
233
  - **ゲストスペースに非対応**: ゲストスペース内のアプリにはアクセスできません
212
- - **動作テスト環境に非対応**: アプリの動作テスト環境(アプリ設定を本番環境に反映する前に検証できる環境)は利用できません
213
234
 
214
235
  ## サポート方針
215
236
 
@@ -1,20 +1,17 @@
1
1
  import { KintoneRestAPIClient } from "@kintone/rest-api-client";
2
- import { PACKAGE_NAME, } from "./config/index.js";
3
2
  import { HttpsProxyAgent } from "https-proxy-agent";
4
3
  import { Agent } from "https";
5
4
  import { readFileSync } from "fs";
6
- import { version } from "./version.js";
7
5
  let client = null;
8
6
  export const getKintoneClient = (config) => {
9
7
  if (client) {
10
8
  return client;
11
9
  }
12
- const { KINTONE_BASE_URL, KINTONE_USERNAME, KINTONE_PASSWORD, KINTONE_API_TOKEN, KINTONE_BASIC_AUTH_USERNAME, KINTONE_BASIC_AUTH_PASSWORD, HTTPS_PROXY, KINTONE_PFX_FILE_PATH, KINTONE_PFX_FILE_PASSWORD, } = config.config;
10
+ const { KINTONE_BASE_URL, KINTONE_USERNAME, KINTONE_PASSWORD, KINTONE_API_TOKEN, KINTONE_BASIC_AUTH_USERNAME, KINTONE_BASIC_AUTH_PASSWORD, HTTPS_PROXY, KINTONE_PFX_FILE_PATH, KINTONE_PFX_FILE_PASSWORD, USER_AGENT, } = config;
13
11
  const authParams = buildAuthParams({
14
12
  username: KINTONE_USERNAME,
15
13
  password: KINTONE_PASSWORD,
16
14
  apiToken: KINTONE_API_TOKEN,
17
- isApiTokenAuth: config.isApiTokenAuth,
18
15
  });
19
16
  client = new KintoneRestAPIClient({
20
17
  baseUrl: KINTONE_BASE_URL,
@@ -23,7 +20,7 @@ export const getKintoneClient = (config) => {
23
20
  basicAuthUsername: KINTONE_BASIC_AUTH_USERNAME,
24
21
  basicAuthPassword: KINTONE_BASIC_AUTH_PASSWORD,
25
22
  }),
26
- userAgent: `${PACKAGE_NAME}@${version}`,
23
+ userAgent: USER_AGENT,
27
24
  httpsAgent: buildHttpsAgent({
28
25
  proxy: HTTPS_PROXY,
29
26
  pfxFilePath: KINTONE_PFX_FILE_PATH,
@@ -32,11 +29,9 @@ export const getKintoneClient = (config) => {
32
29
  });
33
30
  return client;
34
31
  };
35
- export const resetKintoneClient = () => {
36
- client = null;
37
- };
38
32
  const buildAuthParams = (option) => {
39
- return option.isApiTokenAuth
33
+ const isApiTokenAuth = !(option.username && option.password) && !!option.apiToken;
34
+ return isApiTokenAuth
40
35
  ? { auth: { apiToken: option.apiToken } }
41
36
  : { auth: { username: option.username, password: option.password } };
42
37
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -5,7 +5,7 @@ import { parseArgs } from "node:util";
5
5
  * (process.argv[0]はnode、[1]はスクリプトパスなので除外されます)
6
6
  * @param args process.argv で取得した値
7
7
  */
8
- export const parseCommandLineOptions = (args) => {
8
+ export const parse = (args) => {
9
9
  const { values } = parseArgs({
10
10
  args: args.slice(2), // process.argv[0]はnode、[1]はスクリプトパスなので除外
11
11
  allowPositionals: true,
@@ -19,6 +19,7 @@ export const parseCommandLineOptions = (args) => {
19
19
  "pfx-file-path": { type: "string" },
20
20
  "pfx-file-password": { type: "string" },
21
21
  proxy: { type: "string" },
22
+ "attachments-dir": { type: "string" },
22
23
  },
23
24
  });
24
25
  return values;
@@ -1,66 +1,34 @@
1
- import { configSchema, } from "./schema.js";
2
- import { parseCommandLineOptions } from "./command-line.js";
3
- export { PACKAGE_NAME, } from "./schema.js";
4
- export { parseCommandLineOptions } from "./command-line.js";
5
- export const mergeEnvironmentAndCommandLine = (env, args) => {
6
- // 同等の変数の指定があればコマンドライン引数を優先
1
+ import { version } from "../version.js";
2
+ import { parseKintoneMcpServerConfig } from "./parser.js";
3
+ import { PACKAGE_NAME } from "./schema.js";
4
+ const config = parseKintoneMcpServerConfig();
5
+ export const getMcpServerConfig = () => {
7
6
  return {
8
- KINTONE_BASE_URL: args["base-url"] ?? env.KINTONE_BASE_URL,
9
- KINTONE_USERNAME: args.username ?? env.KINTONE_USERNAME,
10
- KINTONE_PASSWORD: args.password ?? env.KINTONE_PASSWORD,
11
- KINTONE_API_TOKEN: args["api-token"] ?? env.KINTONE_API_TOKEN,
12
- KINTONE_BASIC_AUTH_USERNAME: args["basic-auth-username"] ?? env.KINTONE_BASIC_AUTH_USERNAME,
13
- KINTONE_BASIC_AUTH_PASSWORD: args["basic-auth-password"] ?? env.KINTONE_BASIC_AUTH_PASSWORD,
14
- KINTONE_PFX_FILE_PATH: args["pfx-file-path"] ?? env.KINTONE_PFX_FILE_PATH,
15
- KINTONE_PFX_FILE_PASSWORD: args["pfx-file-password"] ?? env.KINTONE_PFX_FILE_PASSWORD,
16
- HTTPS_PROXY: args.proxy ?? env.HTTPS_PROXY ?? env.https_proxy,
7
+ name: PACKAGE_NAME,
8
+ version: version,
17
9
  };
18
10
  };
19
- export const parseKintoneClientConfig = () => {
20
- const cmdArgs = parseCommandLineOptions(process.argv);
21
- const mergedConfig = mergeEnvironmentAndCommandLine(process.env, cmdArgs);
22
- const result = configSchema.safeParse(mergedConfig);
23
- if (result.success) {
24
- const data = result.data;
25
- const isApiTokenAuth = !(data.KINTONE_USERNAME && data.KINTONE_PASSWORD) &&
26
- !!data.KINTONE_API_TOKEN;
27
- return {
28
- config: data,
29
- isApiTokenAuth,
30
- };
31
- }
32
- const errors = result.error.format();
33
- const errorMessages = [];
34
- if (errors.KINTONE_BASE_URL?._errors.length) {
35
- errorMessages.push(`KINTONE_BASE_URL: ${errors.KINTONE_BASE_URL._errors.join(", ")}`);
36
- }
37
- if (errors.KINTONE_USERNAME?._errors.length) {
38
- errorMessages.push(`KINTONE_USERNAME: ${errors.KINTONE_USERNAME._errors.join(", ")}`);
39
- }
40
- if (errors.KINTONE_PASSWORD?._errors.length) {
41
- errorMessages.push(`KINTONE_PASSWORD: ${errors.KINTONE_PASSWORD._errors.join(", ")}`);
42
- }
43
- if (errors.KINTONE_API_TOKEN?._errors.length) {
44
- errorMessages.push(`KINTONE_API_TOKEN: ${errors.KINTONE_API_TOKEN._errors.join(", ")}`);
45
- }
46
- if (errors.HTTPS_PROXY?._errors.length) {
47
- errorMessages.push(`HTTPS_PROXY: ${errors.HTTPS_PROXY._errors.join(", ")}`);
48
- }
49
- if (errors.KINTONE_PFX_FILE_PATH?._errors.length) {
50
- errorMessages.push(`KINTONE_PFX_FILE_PATH: ${errors.KINTONE_PFX_FILE_PATH._errors.join(", ")}`);
51
- }
52
- if (errors.KINTONE_PFX_FILE_PASSWORD?._errors.length) {
53
- errorMessages.push(`KINTONE_PFX_FILE_PASSWORD: ${errors.KINTONE_PFX_FILE_PASSWORD._errors.join(", ")}`);
54
- }
55
- if (errors.KINTONE_BASIC_AUTH_USERNAME?._errors.length) {
56
- errorMessages.push(`KINTONE_BASIC_AUTH_USERNAME: ${errors.KINTONE_BASIC_AUTH_USERNAME._errors.join(", ")}`);
57
- }
58
- if (errors.KINTONE_BASIC_AUTH_PASSWORD?._errors.length) {
59
- errorMessages.push(`KINTONE_BASIC_AUTH_PASSWORD: ${errors.KINTONE_BASIC_AUTH_PASSWORD._errors.join(", ")}`);
60
- }
61
- // Handle cross-field validation errors
62
- if (errors._errors?.length) {
63
- errorMessages.push(...errors._errors);
64
- }
65
- throw new Error(`Environment variables are missing or invalid:\n${errorMessages.join("\n")}`);
11
+ export const getKintoneClientConfig = () => {
12
+ return {
13
+ KINTONE_BASE_URL: config.config.KINTONE_BASE_URL,
14
+ KINTONE_USERNAME: config.config.KINTONE_USERNAME,
15
+ KINTONE_PASSWORD: config.config.KINTONE_PASSWORD,
16
+ KINTONE_API_TOKEN: config.config.KINTONE_API_TOKEN,
17
+ KINTONE_BASIC_AUTH_USERNAME: config.config.KINTONE_BASIC_AUTH_USERNAME,
18
+ KINTONE_BASIC_AUTH_PASSWORD: config.config.KINTONE_BASIC_AUTH_PASSWORD,
19
+ HTTPS_PROXY: config.config.HTTPS_PROXY,
20
+ KINTONE_PFX_FILE_PATH: config.config.KINTONE_PFX_FILE_PATH,
21
+ KINTONE_PFX_FILE_PASSWORD: config.config.KINTONE_PFX_FILE_PASSWORD,
22
+ USER_AGENT: config.userAgent,
23
+ };
24
+ };
25
+ export const getToolConditionConfig = () => {
26
+ return {
27
+ isApiTokenAuth: config.isApiTokenAuth,
28
+ };
29
+ };
30
+ export const getFileConfig = () => {
31
+ return {
32
+ attachmentsDir: config.config.KINTONE_ATTACHMENTS_DIR,
33
+ };
66
34
  };
@@ -0,0 +1,72 @@
1
+ import { parse } from "./command-line.js";
2
+ import { PACKAGE_NAME, configSchema } from "./schema.js";
3
+ import { version } from "../version.js";
4
+ export const parseKintoneMcpServerConfig = () => {
5
+ const cmdArgs = parse(process.argv);
6
+ const mergedConfig = merge(process.env, cmdArgs);
7
+ const result = configSchema.safeParse(mergedConfig);
8
+ if (result.success) {
9
+ const data = result.data;
10
+ const isApiTokenAuth = !(data.KINTONE_USERNAME && data.KINTONE_PASSWORD) &&
11
+ !!data.KINTONE_API_TOKEN;
12
+ return {
13
+ config: data,
14
+ userAgent: `${PACKAGE_NAME}@${version}`,
15
+ isApiTokenAuth,
16
+ };
17
+ }
18
+ const errorMessages = createErrorMessage(result.error.format());
19
+ throw new Error(`Environment variables are missing or invalid:\n${errorMessages.join("\n")}`);
20
+ };
21
+ export const merge = (env, args) => {
22
+ return {
23
+ KINTONE_BASE_URL: args["base-url"] ?? env.KINTONE_BASE_URL,
24
+ KINTONE_USERNAME: args.username ?? env.KINTONE_USERNAME,
25
+ KINTONE_PASSWORD: args.password ?? env.KINTONE_PASSWORD,
26
+ KINTONE_API_TOKEN: args["api-token"] ?? env.KINTONE_API_TOKEN,
27
+ KINTONE_BASIC_AUTH_USERNAME: args["basic-auth-username"] ?? env.KINTONE_BASIC_AUTH_USERNAME,
28
+ KINTONE_BASIC_AUTH_PASSWORD: args["basic-auth-password"] ?? env.KINTONE_BASIC_AUTH_PASSWORD,
29
+ KINTONE_PFX_FILE_PATH: args["pfx-file-path"] ?? env.KINTONE_PFX_FILE_PATH,
30
+ KINTONE_PFX_FILE_PASSWORD: args["pfx-file-password"] ?? env.KINTONE_PFX_FILE_PASSWORD,
31
+ HTTPS_PROXY: args.proxy ?? env.HTTPS_PROXY ?? env.https_proxy,
32
+ KINTONE_ATTACHMENTS_DIR: args["attachments-dir"] ?? env.KINTONE_ATTACHMENTS_DIR,
33
+ };
34
+ };
35
+ const createErrorMessage = (errors) => {
36
+ const errorMessages = [];
37
+ if (errors.KINTONE_BASE_URL?._errors.length) {
38
+ errorMessages.push(`KINTONE_BASE_URL: ${errors.KINTONE_BASE_URL._errors.join(", ")}`);
39
+ }
40
+ if (errors.KINTONE_USERNAME?._errors.length) {
41
+ errorMessages.push(`KINTONE_USERNAME: ${errors.KINTONE_USERNAME._errors.join(", ")}`);
42
+ }
43
+ if (errors.KINTONE_PASSWORD?._errors.length) {
44
+ errorMessages.push(`KINTONE_PASSWORD: ${errors.KINTONE_PASSWORD._errors.join(", ")}`);
45
+ }
46
+ if (errors.KINTONE_API_TOKEN?._errors.length) {
47
+ errorMessages.push(`KINTONE_API_TOKEN: ${errors.KINTONE_API_TOKEN._errors.join(", ")}`);
48
+ }
49
+ if (errors.HTTPS_PROXY?._errors.length) {
50
+ errorMessages.push(`HTTPS_PROXY: ${errors.HTTPS_PROXY._errors.join(", ")}`);
51
+ }
52
+ if (errors.KINTONE_PFX_FILE_PATH?._errors.length) {
53
+ errorMessages.push(`KINTONE_PFX_FILE_PATH: ${errors.KINTONE_PFX_FILE_PATH._errors.join(", ")}`);
54
+ }
55
+ if (errors.KINTONE_PFX_FILE_PASSWORD?._errors.length) {
56
+ errorMessages.push(`KINTONE_PFX_FILE_PASSWORD: ${errors.KINTONE_PFX_FILE_PASSWORD._errors.join(", ")}`);
57
+ }
58
+ if (errors.KINTONE_BASIC_AUTH_USERNAME?._errors.length) {
59
+ errorMessages.push(`KINTONE_BASIC_AUTH_USERNAME: ${errors.KINTONE_BASIC_AUTH_USERNAME._errors.join(", ")}`);
60
+ }
61
+ if (errors.KINTONE_BASIC_AUTH_PASSWORD?._errors.length) {
62
+ errorMessages.push(`KINTONE_BASIC_AUTH_PASSWORD: ${errors.KINTONE_BASIC_AUTH_PASSWORD._errors.join(", ")}`);
63
+ }
64
+ if (errors.KINTONE_ATTACHMENTS_DIR?._errors.length) {
65
+ errorMessages.push(`KINTONE_ATTACHMENTS_DIR: ${errors.KINTONE_ATTACHMENTS_DIR._errors.join(", ")}`);
66
+ }
67
+ // Handle cross-field validation errors
68
+ if (errors._errors?.length) {
69
+ errorMessages.push(...errors._errors.map(String));
70
+ }
71
+ return errorMessages;
72
+ };
@@ -50,6 +50,10 @@ export const configSchema = z
50
50
  .string()
51
51
  .optional()
52
52
  .describe("Password for PFX client certificate file"),
53
+ KINTONE_ATTACHMENTS_DIR: z
54
+ .string()
55
+ .optional()
56
+ .describe("Directory path for downloading files from kintone"),
53
57
  })
54
58
  .refine((data) => {
55
59
  // Either username/password or API token must be provided
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -1,14 +1,24 @@
1
1
  #!/usr/bin/env node
2
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";
3
+ import { createServer } from "./server/index.js";
4
+ import { getFileConfig, getKintoneClientConfig, getMcpServerConfig, getToolConditionConfig, } from "./config/index.js";
6
5
  const main = async () => {
7
6
  const transport = new StdioServerTransport();
8
7
  console.error("Starting server...");
9
- const config = parseKintoneClientConfig();
10
- getKintoneClient(config);
11
- const server = createServer();
8
+ const mcpServerConfig = getMcpServerConfig();
9
+ const clientConfig = getKintoneClientConfig();
10
+ const fileConfig = getFileConfig();
11
+ const toolConditionConfig = getToolConditionConfig();
12
+ const serverConfig = {
13
+ name: mcpServerConfig.name,
14
+ version: mcpServerConfig.version,
15
+ config: {
16
+ clientConfig,
17
+ fileConfig,
18
+ toolConditionConfig,
19
+ },
20
+ };
21
+ const server = createServer(serverConfig);
12
22
  await server.connect(transport);
13
23
  };
14
24
  main().catch(console.error);
@@ -0,0 +1,47 @@
1
+ import { fileTypeFromBuffer } from "file-type";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ export const generateFileName = (fileName, ext) => {
5
+ const extWithDot = ext ? `.${ext}` : "";
6
+ return `${replaceSpecialCharacters(fileName)}${extWithDot}`;
7
+ };
8
+ export const generateFilePath = (downloadDir, filename) => {
9
+ const filePath = path.join(downloadDir, filename);
10
+ return filePath;
11
+ };
12
+ /**
13
+ * Replace special characters in filename for Windows compatibility
14
+ */
15
+ const replaceSpecialCharacters = (filename) => {
16
+ // Windows forbidden characters: < > : " | ? * \ /
17
+ return filename.replace(/[<>:"|?*\\/]/g, "_");
18
+ };
19
+ /**
20
+ * Ensure directory exists, create if it doesn't
21
+ */
22
+ export const ensureDirectoryExists = (dirPath) => {
23
+ if (!fs.existsSync(dirPath)) {
24
+ fs.mkdirSync(dirPath, { recursive: true });
25
+ }
26
+ };
27
+ export const writeFileSyncWithoutOverwrite = (filePath, arrayBuffer) => {
28
+ const buffer = Buffer.from(arrayBuffer);
29
+ const uniqueFilePath = generateUniqueLocalFilePath(filePath);
30
+ fs.writeFileSync(uniqueFilePath, buffer);
31
+ };
32
+ export const getFileTypeFromArrayBuffer = async (arrayBuffer) => {
33
+ return fileTypeFromBuffer(arrayBuffer);
34
+ };
35
+ const generateUniqueLocalFilePath = (filePath) => {
36
+ const internal = (index) => {
37
+ const newFileName = index === 0
38
+ ? path.basename(filePath)
39
+ : `${path.basename(filePath, path.extname(filePath))} (${index})${path.extname(filePath)}`;
40
+ const newFilePath = path.join(path.dirname(filePath), newFileName);
41
+ if (fs.existsSync(newFilePath)) {
42
+ return internal(index + 1);
43
+ }
44
+ return newFilePath;
45
+ };
46
+ return internal(0);
47
+ };