Compare commits

..

198 Commits

Author SHA1 Message Date
cbcoutinho bd09a1f361 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-16 17:38:22 +00:00
cbcoutinho 08820782be Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-14 15:58:04 +00:00
cbcoutinho 936480ed9c Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-03 11:33:37 +00:00
cbcoutinho f4a01f37e1 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-03 08:42:27 +00:00
cbcoutinho 76f3878b2a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-03 08:34:08 +00:00
cbcoutinho a7b4cfe672 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-03 06:13:18 +00:00
cbcoutinho bcdf3898b8 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-02 11:36:01 +00:00
cbcoutinho b341fca408 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-02 11:34:04 +00:00
cbcoutinho ac48e43a60 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-01 16:26:14 +00:00
cbcoutinho 85c71802d2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-01 16:24:58 +00:00
cbcoutinho 7e2e8b2c8c Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-01 16:23:53 +00:00
cbcoutinho 183269bf8f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-03-01 16:05:30 +00:00
cbcoutinho 47b6db5dc1 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-26 15:42:55 +00:00
cbcoutinho 99ee32e691 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-25 12:44:02 +00:00
cbcoutinho ffc64b855e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-25 11:35:51 +00:00
cbcoutinho 2c51b1188b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-25 09:15:13 +00:00
cbcoutinho 4392ae2a11 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-25 08:42:38 +00:00
cbcoutinho fa9fec7269 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-25 07:27:13 +00:00
cbcoutinho 9ac6e741d0 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-24 12:44:31 +00:00
cbcoutinho 174278a9c3 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-24 09:35:06 +00:00
cbcoutinho 419c80f80f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-24 08:22:13 +00:00
cbcoutinho bf916f24aa Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-24 08:20:16 +00:00
cbcoutinho f01f64e8a4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-24 07:52:06 +00:00
cbcoutinho 8064aebb0f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-23 06:09:10 +00:00
cbcoutinho dc1510a485 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-21 08:53:18 +00:00
cbcoutinho 33db76696a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-21 08:38:24 +00:00
cbcoutinho 4f5e4be5ec Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-20 18:23:44 +00:00
cbcoutinho 1c3781fa95 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-20 13:33:16 +00:00
cbcoutinho 222fc1618c Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-20 07:15:51 +00:00
cbcoutinho 4013c25c68 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-20 06:12:13 +00:00
cbcoutinho 0b475d5acb Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-19 21:03:12 +00:00
cbcoutinho 758586d666 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-19 06:28:50 +00:00
cbcoutinho bdaec6a0c5 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 15:14:13 +00:00
cbcoutinho 599b665963 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 14:50:33 +00:00
cbcoutinho 9f86f86ec7 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 14:48:02 +00:00
cbcoutinho c4cfb027f0 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 14:31:52 +00:00
cbcoutinho 51c689c6a5 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 11:38:48 +00:00
cbcoutinho e3e1cfc9f7 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 10:27:42 +00:00
cbcoutinho e01b053f22 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 09:11:08 +00:00
cbcoutinho c460f24e0d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 08:09:51 +00:00
cbcoutinho 3380aa2f56 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 07:55:42 +00:00
cbcoutinho aef852f73e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 07:50:07 +00:00
cbcoutinho acc1b9c9e2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-18 06:28:00 +00:00
cbcoutinho 7d932b153d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-17 13:45:45 +00:00
cbcoutinho 93a23846c4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-17 04:38:31 +00:00
cbcoutinho 0690088db2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-17 04:38:03 +00:00
cbcoutinho 08270d9455 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-17 04:37:32 +00:00
cbcoutinho a8ce648566 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-16 14:49:39 +00:00
cbcoutinho e3c7a138ed Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-16 11:38:52 +00:00
cbcoutinho 9ed9d570bd Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-16 07:20:20 +00:00
cbcoutinho fdc6d1232e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-15 19:37:59 +00:00
cbcoutinho f86fd927e3 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-15 19:17:30 +00:00
cbcoutinho 379bd12e1d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-12 22:02:02 +00:00
cbcoutinho 00c0b15c2d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-12 22:01:21 +00:00
cbcoutinho 17cb4cb25d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-11 07:00:33 +00:00
cbcoutinho e1ffc2809c Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-11 06:21:56 +00:00
cbcoutinho 377b1e2332 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-08 22:52:38 +00:00
cbcoutinho 05e196dedc Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-08 12:57:53 +00:00
cbcoutinho 389c98cc74 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-07 16:38:41 +00:00
cbcoutinho 32c09c338d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-07 14:49:51 +00:00
cbcoutinho 9f574432be Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-07 14:47:51 +00:00
cbcoutinho b29563630e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 20:08:20 +00:00
cbcoutinho dd2627edda Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 17:45:04 +00:00
cbcoutinho 5a74cdca14 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 15:18:39 +00:00
cbcoutinho 6151d92158 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 14:49:50 +00:00
cbcoutinho ce4536cb2d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 14:23:27 +00:00
cbcoutinho 65cf635e71 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 14:05:18 +00:00
cbcoutinho ada1f57e59 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 07:23:25 +00:00
cbcoutinho f9949c920c Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-06 07:09:40 +00:00
cbcoutinho 6d99728d9b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-04 06:25:23 +00:00
cbcoutinho 6bb5e77c7a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-03 19:58:02 +00:00
cbcoutinho 3890bf430f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-02-03 06:50:42 +00:00
cbcoutinho 53aada6669 Update README and index from chart release 2026-02-03 06:50:40 +00:00
cbcoutinho da6268002e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-31 16:57:07 +00:00
cbcoutinho bace73a6fe Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-31 16:48:55 +00:00
cbcoutinho 9ffa11cd62 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-31 16:10:52 +00:00
cbcoutinho e2ba31985a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-30 19:27:11 +00:00
cbcoutinho b534812cad Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-30 19:15:00 +00:00
cbcoutinho 450ebb2c8d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-30 14:38:41 +00:00
cbcoutinho c2c80d732f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-29 21:55:40 +00:00
cbcoutinho 3340b854c2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-28 20:15:57 +00:00
cbcoutinho cf73238caa Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-28 12:46:53 +00:00
cbcoutinho 12ced4a255 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-28 12:45:45 +00:00
cbcoutinho 964740bb71 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-28 07:39:23 +00:00
cbcoutinho 434c36ea57 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-26 21:02:40 +00:00
cbcoutinho 831627b78e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-26 19:29:55 +00:00
cbcoutinho 9662e77d87 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-24 11:45:14 +00:00
cbcoutinho 2efe761e37 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-20 14:26:59 +00:00
cbcoutinho 5b673d4715 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-20 13:27:18 +00:00
cbcoutinho 27042f40d4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-19 12:43:04 +00:00
cbcoutinho 724d68694e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-19 12:41:41 +00:00
cbcoutinho ee0505bcc1 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-18 10:57:50 +00:00
cbcoutinho 3951260e91 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-17 20:38:13 +00:00
cbcoutinho b682da9c8b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-16 17:15:11 +00:00
cbcoutinho eb2b227b8a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-16 10:28:13 +00:00
cbcoutinho 8916080262 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-16 09:54:16 +00:00
cbcoutinho 52b3e857e4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-15 13:34:25 +00:00
cbcoutinho bc979b0e7d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-15 11:23:55 +00:00
cbcoutinho b5bb1639d2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-15 09:00:59 +00:00
cbcoutinho 507fa69af8 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2026-01-15 06:33:30 +00:00
cbcoutinho 9919b4eaf4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-29 18:18:56 +00:00
cbcoutinho 9523cbc9ef Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-26 16:34:01 +00:00
cbcoutinho 12ece90a87 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-26 15:17:48 +00:00
cbcoutinho 58f5367b36 Update README and index from chart release 2025-12-26 15:17:47 +00:00
cbcoutinho f45250ad59 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-22 21:21:56 +00:00
cbcoutinho 752221a869 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-22 20:53:22 +00:00
cbcoutinho ec1e70f0ff Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-19 20:45:05 +00:00
cbcoutinho 8146fdfa91 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-19 13:23:28 +00:00
cbcoutinho 246e90ec8a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-13 23:25:09 +00:00
cbcoutinho d061418d44 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-13 22:56:15 +00:00
cbcoutinho 3131ffb106 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-13 21:24:34 +00:00
cbcoutinho d2f31b7b26 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-13 14:53:56 +00:00
cbcoutinho 738302baa3 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-12 17:00:49 +00:00
cbcoutinho f5c84bcded Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-11 12:58:25 +00:00
cbcoutinho b08e44f41d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-09 17:43:43 +00:00
cbcoutinho 832698f668 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-09 14:47:01 +00:00
cbcoutinho 03e9e9ba10 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-08 06:23:30 +00:00
cbcoutinho 5d7f6fd59e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-12-03 12:09:14 +00:00
cbcoutinho 2285960ec3 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-28 23:03:23 +00:00
cbcoutinho 60bbeb36a8 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 16:40:21 +00:00
cbcoutinho 3d4c538cc9 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 04:44:32 +00:00
cbcoutinho a304ae3bdf Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 03:25:35 +00:00
cbcoutinho 5a0fd0f10f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 03:04:10 +00:00
cbcoutinho 0e7286a535 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 00:53:40 +00:00
cbcoutinho feccc92d01 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-23 00:24:03 +00:00
cbcoutinho 2ea8f1d873 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-22 21:03:06 +00:00
cbcoutinho deb1839be7 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-22 18:54:27 +00:00
cbcoutinho 6831e4e414 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-22 18:40:42 +00:00
cbcoutinho ae2029eca2 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-22 16:14:51 +00:00
cbcoutinho bdbc22b30b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-21 00:39:39 +00:00
cbcoutinho 808ca6218a Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-19 22:43:17 +00:00
cbcoutinho 48f69fc046 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-18 12:56:28 +00:00
cbcoutinho 6b9547a240 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-17 07:25:46 +00:00
cbcoutinho 3d4e29c9c9 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-17 05:57:25 +00:00
cbcoutinho 812ff5bede Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-16 11:09:57 +00:00
cbcoutinho 189490c274 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-16 11:03:01 +00:00
cbcoutinho 48966bcfe9 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-16 10:18:49 +00:00
cbcoutinho 05d2496d99 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-16 10:18:14 +00:00
cbcoutinho 0be2eacd99 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-15 23:33:10 +00:00
cbcoutinho db137ebfbf Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-15 00:46:26 +00:00
cbcoutinho 082e31c86e Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-13 21:11:49 +00:00
cbcoutinho a0825aff4b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-13 21:10:32 +00:00
cbcoutinho 0d0733e202 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-13 16:15:43 +00:00
cbcoutinho beb8668260 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-13 12:10:57 +00:00
cbcoutinho 0d6dd79e70 Update README and index from chart release 2025-11-13 10:58:18 +00:00
cbcoutinho d3ebcd2423 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-13 10:58:18 +00:00
cbcoutinho ab644cdfde Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-12 02:17:13 +00:00
cbcoutinho a823bb95a6 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-11 23:54:55 +00:00
cbcoutinho db1437e927 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-10 22:22:04 +00:00
cbcoutinho 57b66155c7 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-10 07:03:03 +00:00
cbcoutinho c3ce208c4c Update README and index from chart release 2025-11-10 02:50:28 +00:00
cbcoutinho 6d5a20d5c6 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-10 02:50:26 +00:00
cbcoutinho 75f6e5e7a0 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 18:28:48 +00:00
cbcoutinho b0fdda4a51 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 08:54:37 +00:00
cbcoutinho e38814cb3b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 08:30:09 +00:00
cbcoutinho 90fbaeeb30 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 08:04:23 +00:00
cbcoutinho a0f1349fb4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 06:52:43 +00:00
cbcoutinho c29c6bde1d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 06:46:00 +00:00
cbcoutinho 88c2b2350d Update README and index from chart release 2025-11-09 06:22:17 +00:00
cbcoutinho 939445166b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-09 06:22:16 +00:00
cbcoutinho b69986aafa Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-08 03:59:39 +00:00
cbcoutinho c697d73c9b Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-08 03:48:59 +00:00
cbcoutinho eea197fd2d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-05 23:02:36 +00:00
cbcoutinho b793c7a1c4 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-04 12:28:26 +00:00
cbcoutinho f09dd94f2d Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-04 10:27:51 +00:00
cbcoutinho dddb7f69ef Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-11-03 01:48:48 +00:00
cbcoutinho b080171f17 Update README and index from chart release 2025-10-29 11:18:55 +00:00
cbcoutinho 1431e946cc Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 11:18:54 +00:00
cbcoutinho 8218db8ee2 Update README and index from chart release 2025-10-29 10:57:55 +00:00
cbcoutinho c550e622b0 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 10:57:54 +00:00
cbcoutinho e13ee362b5 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 10:55:07 +00:00
cbcoutinho 4fab77350f Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 10:44:22 +00:00
cbcoutinho cd3497a935 Update README and index from chart release 2025-10-29 10:30:52 +00:00
cbcoutinho b7e3244b79 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 10:30:51 +00:00
cbcoutinho d7aca04dd6 Update index.yaml
Signed-off-by: cbcoutinho <cbcoutinho@users.noreply.github.com>
2025-10-29 09:35:17 +00:00
github-actions[bot] 0e7e74867f bump: version 0.21.0 → 0.22.0 2025-10-29 09:32:27 +00:00
Chris Coutinho a29045cca4 Merge pull request #246 from cbcoutinho/feature/helm-chart
Feature/helm chart
2025-10-29 10:32:02 +01:00
Chris Coutinho b11c3ddfb6 build: Rename /helm -> /charts 2025-10-29 10:30:48 +01:00
Chris Coutinho 562c102711 feat(server): Add /live & /health endpoints 2025-10-29 10:29:30 +01:00
Chris Coutinho 3c3646bec2 Merge pull request #247 from cbcoutinho/renovate/docker.io-library-nginx-alpine
chore(deps): update docker.io/library/nginx:alpine docker digest to 9dacca6
2025-10-29 09:37:07 +01:00
renovate-bot-cbcoutinho[bot] dd636e6a08 chore(deps): update docker.io/library/nginx:alpine docker digest to 9dacca6 2025-10-29 05:07:08 +00:00
Chris Coutinho d7a8719d0e build: Remove duplicate --host 2025-10-29 01:40:36 +01:00
Chris Coutinho 97fa9ef8a7 build: Update helm chart README and instructions 2025-10-29 01:37:08 +01:00
Chris Coutinho 77dd17b3e1 build: fix templating/linting errors 2025-10-29 01:37:07 +01:00
Chris Coutinho d56ec33b77 build: update helm chart 2025-10-29 01:37:07 +01:00
Chris Coutinho a1c5acc1c2 feat: Initialize helm chart 2025-10-29 01:37:03 +01:00
Chris Coutinho e0de2e17e9 Merge pull request #245 from cbcoutinho/renovate/docker.io-library-nextcloud-32.0.1
chore(deps): update docker.io/library/nextcloud:32.0.1 docker digest to 1e4eae5
2025-10-28 09:19:39 +01:00
renovate-bot-cbcoutinho[bot] 4fc0cb5a41 chore(deps): update docker.io/library/nextcloud:32.0.1 docker digest to 1e4eae5 2025-10-27 23:10:34 +00:00
Chris Coutinho ff9cca716b Merge pull request #243 from cbcoutinho/renovate/astral-sh-setup-uv-digest
chore(deps): update astral-sh/setup-uv digest to 8585678
2025-10-26 22:00:45 +01:00
Chris Coutinho ef4a82e589 Update .github/workflows/release.yml 2025-10-26 22:00:36 +01:00
Chris Coutinho 301c502e57 Merge pull request #244 from cbcoutinho/renovate/astral-sh-setup-uv-7.x
chore(deps): update astral-sh/setup-uv action to v7.1.2
2025-10-26 21:59:19 +01:00
renovate-bot-cbcoutinho[bot] d4d291d6d2 chore(deps): update astral-sh/setup-uv action to v7.1.2 2025-10-26 17:07:33 +00:00
renovate-bot-cbcoutinho[bot] e4b0ea5093 chore(deps): update astral-sh/setup-uv digest to 8585678 2025-10-26 17:07:29 +00:00
Chris Coutinho 6833f7f117 Merge pull request #242 from cbcoutinho/renovate/pin-dependencies
chore(deps): pin downloads.unstructured.io/unstructured-io/unstructured-api docker tag to a43ab55
2025-10-26 02:43:56 +02:00
renovate-bot-cbcoutinho[bot] 7db2a5c586 chore(deps): pin downloads.unstructured.io/unstructured-io/unstructured-api docker tag to a43ab55 2025-10-25 22:05:59 +00:00
Chris Coutinho b76c10f18c Merge branch 'docs/oauth-arch' 2025-10-25 22:08:02 +02:00
Chris Coutinho ab7411d9fd test: Fix tests 2025-10-25 22:07:46 +02:00
Chris Coutinho d02fe3c3b6 Merge pull request #241 from cbcoutinho/docs/oauth-arch
docs: Update OAuth architecture
2025-10-25 21:58:45 +02:00
25 changed files with 9037 additions and 299 deletions
+29
View File
@@ -0,0 +1,29 @@
name: Release Charts
on:
push:
tags:
- v*
jobs:
release:
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.7.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Install uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: Install Python 3.11
run: uv python install 3.11
- name: Build
+2 -2
View File
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install the latest version of uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: Check format
run: |
uv run --frozen ruff format --diff
@@ -52,7 +52,7 @@ jobs:
up-flags: "--build"
- name: Install the latest version of uv
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: Install Playwright dependencies
run: |
+7
View File
@@ -1,3 +1,10 @@
## v0.22.0 (2025-10-29)
### Feat
- **server**: Add /live & /health endpoints
- Initialize helm chart
## v0.21.0 (2025-10-25)
### Feat
+673 -288
View File
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
+23
View File
@@ -0,0 +1,23 @@
apiVersion: v2
name: nextcloud-mcp-server
description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud
type: application
version: 0.1.0
appVersion: "0.21.0"
keywords:
- nextcloud
- mcp
- model-context-protocol
- llm
- ai
- claude
- webdav
- caldav
- carddav
maintainers:
- name: Chris Coutinho
email: chris@coutinho.io
home: https://github.com/cbcoutinho/nextcloud-mcp-server
sources:
- https://github.com/cbcoutinho/nextcloud-mcp-server
icon: https://raw.githubusercontent.com/nextcloud/server/master/core/img/logo/logo.svg
+742
View File
@@ -0,0 +1,742 @@
# Nextcloud MCP Server Helm Chart
This Helm chart deploys the Nextcloud MCP (Model Context Protocol) Server on a Kubernetes cluster, enabling AI assistants to interact with your Nextcloud instance.
## Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
- A running Nextcloud instance (accessible from the Kubernetes cluster)
- Nextcloud credentials (username/password for basic auth OR OAuth client for OAuth mode)
## Installation
### Quick Start with Basic Authentication
```bash
# Add the Helm repository
helm repo add nextcloud-mcp https://cbcoutinho.github.io/nextcloud-mcp-server
helm repo update
# Install with basic auth (recommended for most users)
helm install nextcloud-mcp nextcloud-mcp/nextcloud-mcp-server \
--set nextcloud.host=https://cloud.example.com \
--set auth.basic.username=myuser \
--set auth.basic.password=mypassword
```
### Using a values file
Create a `custom-values.yaml` file:
```yaml
nextcloud:
host: https://cloud.example.com
auth:
mode: basic
basic:
username: myuser
password: mypassword
resources:
limits:
cpu: 1000m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
```
Install with your custom values:
```bash
helm install nextcloud-mcp nextcloud-mcp/nextcloud-mcp-server -f custom-values.yaml
```
### OAuth Authentication Mode (Experimental)
**Warning:** OAuth mode is experimental and requires patches to the Nextcloud `user_oidc` app. See the [Authentication Guide](https://github.com/cbcoutinho/nextcloud-mcp-server#authentication) for details.
```yaml
nextcloud:
host: https://cloud.example.com
mcpServerUrl: https://mcp.example.com
publicIssuerUrl: https://cloud.example.com
auth:
mode: oauth
oauth:
# Optional: provide pre-registered client credentials
# If not provided, will use Dynamic Client Registration
clientId: "your-client-id"
clientSecret: "your-client-secret"
persistence:
enabled: true
size: 100Mi
ingress:
enabled: true
className: nginx
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: nextcloud-mcp-tls
hosts:
- mcp.example.com
```
## Configuration
### Key Configuration Parameters
#### Nextcloud Connection
| Parameter | Description | Default |
|-----------|-------------|---------|
| `nextcloud.host` | URL of your Nextcloud instance (required) | `""` |
| `nextcloud.mcpServerUrl` | MCP server URL for OAuth callbacks (OAuth only, optional) | Smart default* |
| `nextcloud.publicIssuerUrl` | Public URL for browser-accessible OAuth authorization endpoint (OAuth only, optional) | Smart default** |
**Smart Defaults:**
- `*mcpServerUrl`: If not set, automatically uses ingress host (if enabled) or `http://localhost:8000` (for port-forward setups)
- `**publicIssuerUrl`: If not set, defaults to `nextcloud.host`. **Only used for authorization endpoints** that browsers must access. All server-to-server endpoints (token, JWKS, introspection, userinfo) use URLs from OIDC discovery without rewriting
#### Authentication
| Parameter | Description | Default |
|-----------|-------------|---------|
| `auth.mode` | Authentication mode: `basic` or `oauth` | `basic` |
| `auth.basic.username` | Nextcloud username (basic auth) | `""` |
| `auth.basic.password` | Nextcloud password (basic auth) | `""` |
| `auth.basic.existingSecret` | Use existing secret for credentials | `""` |
| `auth.oauth.clientId` | OAuth client ID (OAuth mode, optional) | `""` |
| `auth.oauth.clientSecret` | OAuth client secret (OAuth mode, optional) | `""` |
| `auth.oauth.persistence.enabled` | Enable persistent storage for OAuth | `true` |
| `auth.oauth.persistence.size` | Size of OAuth storage PVC | `100Mi` |
#### Data Storage
The `/app/data` directory is used for application data (token databases, Qdrant persistent storage, etc.). It is always mounted as writable to support the read-only root filesystem security context.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `dataStorage.enabled` | Enable persistent storage for `/app/data` | `false` |
| `dataStorage.size` | Size of data storage PVC | `1Gi` |
| `dataStorage.storageClass` | Storage class (leave empty for default) | `""` |
| `dataStorage.accessMode` | Access mode | `ReadWriteOnce` |
| `dataStorage.existingClaim` | Use existing PVC | `""` |
**When to enable persistence:**
- Multi-user basic auth with offline access (stores `tokens.db`)
- Qdrant persistent mode (stores vector database)
- Any feature requiring persistent app data
**When persistence is disabled:** Uses `emptyDir` (non-persistent, data lost on pod restart, but directory remains writable).
#### MCP Server Configuration
| Parameter | Description | Default |
|-----------|-------------|---------|
| `mcp.transport` | Transport mode | `streamable-http` |
| `mcp.port` | Server port (used by both auth modes) | `8000` |
| `mcp.extraArgs` | Additional command-line arguments | `[]` |
The `extraArgs` parameter allows you to pass additional command-line arguments to the MCP server. This is useful for enabling debug logging, enabling specific apps, or other runtime configuration.
**Example:**
```yaml
mcp:
extraArgs:
- "--log-level"
- "debug"
- "--enable-app"
- "notes"
```
#### Image Configuration
| Parameter | Description | Default |
|-----------|-------------|---------|
| `image.repository` | Container image repository | `ghcr.io/cbcoutinho/nextcloud-mcp-server` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
**Note:** Image tag is automatically set to the chart's `appVersion` and cannot be overridden.
#### Resources
| Parameter | Description | Default |
|-----------|-------------|---------|
| `resources.limits.cpu` | CPU limit | `1000m` |
| `resources.limits.memory` | Memory limit | `512Mi` |
| `resources.requests.cpu` | CPU request | `100m` |
| `resources.requests.memory` | Memory request | `128Mi` |
#### Service
| Parameter | Description | Default |
|-----------|-------------|---------|
| `service.type` | Service type | `ClusterIP` |
| `service.port` | Service port | `8000` |
#### Ingress
| Parameter | Description | Default |
|-----------|-------------|---------|
| `ingress.enabled` | Enable ingress | `false` |
| `ingress.className` | Ingress class name | `""` |
| `ingress.hosts` | Ingress host configuration | See values.yaml |
| `ingress.tls` | Ingress TLS configuration | `[]` |
#### Autoscaling
| Parameter | Description | Default |
|-----------|-------------|---------|
| `autoscaling.enabled` | Enable HPA | `false` |
| `autoscaling.minReplicas` | Minimum replicas | `1` |
| `autoscaling.maxReplicas` | Maximum replicas | `10` |
| `autoscaling.targetCPUUtilizationPercentage` | Target CPU % | `80` |
#### Health Probes
| Parameter | Description | Default |
|-----------|-------------|---------|
| `livenessProbe.httpGet.path` | Liveness probe endpoint | `/health/live` |
| `livenessProbe.initialDelaySeconds` | Initial delay for liveness | `30` |
| `livenessProbe.periodSeconds` | Check interval for liveness | `10` |
| `readinessProbe.httpGet.path` | Readiness probe endpoint | `/health/ready` |
| `readinessProbe.initialDelaySeconds` | Initial delay for readiness | `10` |
| `readinessProbe.periodSeconds` | Check interval for readiness | `5` |
The application exposes HTTP health check endpoints:
- `/health/live` - Liveness probe (checks if application is running)
- `/health/ready` - Readiness probe (checks if application is ready to serve traffic)
#### Document Processing (Optional)
| Parameter | Description | Default |
|-----------|-------------|---------|
| `documentProcessing.enabled` | Enable document processing | `false` |
| `documentProcessing.defaultProcessor` | Default processor | `unstructured` |
| `documentProcessing.unstructured.enabled` | Enable Unstructured.io processor | `false` |
| `documentProcessing.unstructured.apiUrl` | Unstructured API URL | `http://unstructured:8000` |
| `documentProcessing.tesseract.enabled` | Enable Tesseract OCR | `false` |
#### Vector Search & Semantic Capabilities (Optional)
Enable semantic search capabilities with BM25 hybrid search by deploying a vector database (Qdrant) and embedding service (Ollama or OpenAI).
**Semantic Search Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `semanticSearch.enabled` | Enable semantic search and background vector synchronization | `false` |
| `semanticSearch.scanInterval` | Scan interval in seconds | `3600` |
| `semanticSearch.processorWorkers` | Number of concurrent processor workers | `3` |
| `semanticSearch.queueMaxSize` | Maximum queue size for pending documents | `10000` |
**Document Chunking Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `documentChunking.chunkSize` | Number of words per chunk for embedding | `512` |
| `documentChunking.chunkOverlap` | Number of overlapping words between chunks | `50` |
**Chunking Strategy:**
- **Small chunks (256-384)**: Better precision for searches, more storage overhead
- **Medium chunks (512-768)**: Balanced approach (recommended for most use cases)
- **Large chunks (1024+)**: Better context preservation, less precise matching
- **Overlap**: Should be 10-20% of chunk size to preserve context across boundaries
**Qdrant Vector Database:**
Qdrant is deployed as a subchart when `qdrant.enabled` is `true`. All configuration values are passed through to the [qdrant/qdrant](https://github.com/qdrant/qdrant-helm) chart.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `qdrant.enabled` | Deploy Qdrant as a subchart | `false` |
| `qdrant.replicaCount` | Number of Qdrant replicas | `1` |
| `qdrant.image.tag` | Qdrant version | `v1.12.5` |
| `qdrant.apiKey` | Optional API key for authentication | `""` |
| `qdrant.persistence.size` | Storage size for vector data | `10Gi` |
| `qdrant.persistence.storageClass` | Storage class | `""` |
| `qdrant.resources.requests.cpu` | CPU request | `200m` |
| `qdrant.resources.requests.memory` | Memory request | `512Mi` |
| `qdrant.resources.limits.cpu` | CPU limit | `1000m` |
| `qdrant.resources.limits.memory` | Memory limit | `2Gi` |
**Ollama Embedding Service:**
Ollama is deployed as a subchart when `ollama.enabled` is `true`. All configuration values are passed through to the [ollama/ollama](https://github.com/otwld/ollama-helm) chart. Alternatively, set `ollama.url` to use an external Ollama instance.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `ollama.enabled` | Deploy Ollama as a subchart | `false` |
| `ollama.url` | External Ollama URL (use with `enabled: false`) | `""` |
| `ollama.embeddingModel` | Embedding model to use | `nomic-embed-text` |
| `ollama.verifySsl` | Verify SSL certificates | `true` |
| `ollama.replicaCount` | Number of Ollama replicas | `1` |
| `ollama.ollama.models.pull` | Models to pull on startup | `["nomic-embed-text"]` |
| `ollama.persistentVolume.enabled` | Enable persistent storage | `true` |
| `ollama.persistentVolume.size` | Storage size for models | `20Gi` |
| `ollama.resources.requests.cpu` | CPU request | `500m` |
| `ollama.resources.requests.memory` | Memory request | `1Gi` |
| `ollama.resources.limits.cpu` | CPU limit | `2000m` |
| `ollama.resources.limits.memory` | Memory limit | `4Gi` |
**OpenAI Embedding Provider (Alternative):**
Use OpenAI or any OpenAI-compatible API instead of Ollama.
| Parameter | Description | Default |
|-----------|-------------|---------|
| `openai.enabled` | Enable OpenAI embedding provider | `false` |
| `openai.apiKey` | OpenAI API key | `""` |
| `openai.existingSecret` | Use existing secret for API key | `""` |
| `openai.secretKey` | Key in secret containing API key | `api-key` |
| `openai.baseUrl` | Custom API endpoint (optional) | `""` |
#### Observability & Monitoring
The chart includes comprehensive observability features including Prometheus metrics, OpenTelemetry tracing, and Grafana dashboards.
**Metrics Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `observability.metrics.enabled` | Enable Prometheus metrics | `true` |
| `observability.metrics.port` | Metrics port | `9090` |
| `observability.metrics.path` | Metrics endpoint path | `/metrics` |
**Tracing Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `observability.tracing.enabled` | Enable OpenTelemetry tracing | `false` |
| `observability.tracing.endpoint` | OTLP collector endpoint | `""` |
| `observability.tracing.serviceName` | Service name in traces | `nextcloud-mcp-server` |
| `observability.tracing.samplingRate` | Trace sampling rate (0.0-1.0) | `1.0` |
**Logging Configuration:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `observability.logging.format` | Log format (json or text) | `json` |
| `observability.logging.level` | Log level | `INFO` |
| `observability.logging.includeTraceContext` | Include trace IDs in logs | `true` |
**ServiceMonitor (Prometheus Operator):**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `serviceMonitor.enabled` | Create ServiceMonitor resource | `false` |
| `serviceMonitor.interval` | Scrape interval | `30s` |
| `serviceMonitor.scrapeTimeout` | Scrape timeout | `10s` |
| `serviceMonitor.labels` | Additional labels for ServiceMonitor | `{}` |
**PrometheusRule (Prometheus Operator):**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `prometheusRule.enabled` | Create PrometheusRule with alert rules | `false` |
| `prometheusRule.labels` | Additional labels for PrometheusRule | `{}` |
**Grafana Dashboards:**
| Parameter | Description | Default |
|-----------|-------------|---------|
| `dashboards.enabled` | Enable automatic dashboard provisioning | `false` |
| `dashboards.grafanaFolder` | Grafana folder name for dashboards | `Nextcloud MCP` |
| `dashboards.labels` | Additional labels for dashboard ConfigMap | `{}` |
| `dashboards.annotations` | Additional annotations for dashboard ConfigMap | `{}` |
When `dashboards.enabled` is `true`, a ConfigMap with the Grafana dashboard is created with the `grafana_dashboard: "1"` label. This enables automatic discovery by Grafana sidecar containers (commonly used with kube-prometheus-stack).
The dashboard provides comprehensive monitoring including:
- HTTP request metrics (RED pattern: Rate, Errors, Duration)
- MCP tool performance and errors
- Nextcloud API performance by app (notes, calendar, contacts, etc.)
- OAuth token operations and cache hit rates
- External dependency health (Nextcloud, Qdrant, Keycloak, Unstructured API)
- Vector sync processing pipeline (when enabled)
For manual import or more details, see `charts/nextcloud-mcp-server/dashboards/README.md`.
## Examples
### Example 1: Basic Auth with Ingress
```yaml
nextcloud:
host: https://cloud.example.com
auth:
mode: basic
basic:
username: admin
password: secure-password
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: mcp-tls
hosts:
- mcp.example.com
resources:
limits:
cpu: 2000m
memory: 1Gi
requests:
cpu: 200m
memory: 256Mi
```
### Example 2: Using Existing Secrets
#### Basic Auth with Existing Secret
Create a secret manually:
```bash
kubectl create secret generic nextcloud-credentials \
--from-literal=username=myuser \
--from-literal=password=mypassword
```
Then reference it in your values:
```yaml
nextcloud:
host: https://cloud.example.com
auth:
mode: basic
basic:
existingSecret: nextcloud-credentials
usernameKey: username
passwordKey: password
```
#### OAuth with Existing Secret (Pre-registered Client)
If you have a pre-registered OAuth client:
```bash
kubectl create secret generic nextcloud-oauth-creds \
--from-literal=clientId=my-oauth-client-id \
--from-literal=clientSecret=my-oauth-client-secret
```
Then reference it in your values:
```yaml
nextcloud:
host: https://cloud.example.com
# mcpServerUrl and publicIssuerUrl are optional!
# If not set, mcpServerUrl defaults to ingress host or localhost
# publicIssuerUrl defaults to nextcloud.host (only used for browser-accessible auth endpoint)
auth:
mode: oauth
oauth:
existingSecret: nextcloud-oauth-creds
clientIdKey: clientId
clientSecretKey: clientSecret
persistence:
enabled: true
ingress:
enabled: true
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: mcp-tls
hosts:
- mcp.example.com
```
### Example 3: OAuth with Document Processing and Dynamic Client Registration
This example shows OAuth without pre-registered credentials (using DCR) and optional URL values:
```yaml
nextcloud:
host: https://cloud.example.com
# mcpServerUrl will automatically use ingress host (https://mcp.example.com)
# publicIssuerUrl will automatically default to nextcloud.host (only used for browser-accessible auth endpoint)
auth:
mode: oauth
oauth:
# No clientId/clientSecret - will use Dynamic Client Registration!
persistence:
enabled: true
storageClass: fast-ssd
size: 200Mi
documentProcessing:
enabled: true
defaultProcessor: unstructured
unstructured:
enabled: true
apiUrl: http://unstructured-api:8000
strategy: hi_res
languages: eng,deu,fra
ingress:
enabled: true
className: nginx
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
```
### Example 4: High Availability with Autoscaling
```yaml
replicaCount: 2
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 20
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
resources:
limits:
cpu: 2000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- nextcloud-mcp-server
topologyKey: kubernetes.io/hostname
```
### Example 5: Semantic Search with Qdrant and Ollama
Deploy with vector search capabilities using embedded Qdrant and Ollama:
```yaml
nextcloud:
host: https://cloud.example.com
auth:
mode: basic
basic:
username: admin
password: secure-password
# Enable semantic search
semanticSearch:
enabled: true
scanInterval: 1800 # Scan every 30 minutes
processorWorkers: 5
# Deploy Qdrant as a subchart
qdrant:
enabled: true
persistence:
size: 20Gi
storageClass: fast-ssd
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
# Deploy Ollama as a subchart
ollama:
enabled: true
embeddingModel: nomic-embed-text
persistentVolume:
size: 30Gi
storageClass: standard
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 4000m
memory: 8Gi
```
Or use an external Ollama instance:
```yaml
semanticSearch:
enabled: true
qdrant:
enabled: true
# Use external Ollama instead of deploying subchart
ollama:
enabled: false
url: "http://ollama.ai-services.svc.cluster.local:11434"
embeddingModel: nomic-embed-text
```
Or use OpenAI for embeddings:
```yaml
semanticSearch:
enabled: true
qdrant:
enabled: true
# Use OpenAI instead of Ollama
openai:
enabled: true
apiKey: "sk-..."
# Or use existing secret:
# existingSecret: openai-api-key
# secretKey: api-key
```
## Upgrading
### To upgrade an existing deployment:
```bash
# Update the repository
helm repo update
# Upgrade with your custom values
helm upgrade nextcloud-mcp nextcloud-mcp/nextcloud-mcp-server -f custom-values.yaml
```
### To upgrade with new values:
```bash
helm upgrade nextcloud-mcp nextcloud-mcp/nextcloud-mcp-server \
--set resources.limits.memory=1Gi
```
## Uninstalling
```bash
helm uninstall nextcloud-mcp
```
**Note:** This will delete all resources including PVCs. If you want to preserve OAuth client data, backup the PVC before uninstalling.
## Troubleshooting
### Check pod status
```bash
kubectl get pods -l app.kubernetes.io/name=nextcloud-mcp-server
```
### View logs
```bash
kubectl logs -l app.kubernetes.io/name=nextcloud-mcp-server --tail=100 -f
```
### Check health endpoints
The application exposes health check endpoints for monitoring:
```bash
# Port forward to the service
kubectl port-forward svc/nextcloud-mcp 8000:8000
# Check liveness (if app is running)
curl http://localhost:8000/health/live
# Check readiness (if app is ready to serve traffic)
curl http://localhost:8000/health/ready
```
**Example responses:**
Liveness (always returns 200 if running):
```json
{
"status": "alive",
"mode": "basic"
}
```
Readiness (returns 200 if ready, 503 if not ready):
```json
{
"status": "ready",
"checks": {
"nextcloud_configured": "ok",
"auth_mode": "basic",
"auth_configured": "ok"
}
}
```
### Common Issues
1. **Connection refused to Nextcloud**
- Verify `nextcloud.host` is accessible from the Kubernetes cluster
- For OAuth mode: Ensure MCP server can reach OIDC discovery endpoints (token, JWKS, introspection, userinfo URLs)
- Check network policies and firewall rules
- Note: Do not use internal Docker hostnames (like `http://app:80`) for `nextcloud.host` - use externally resolvable URLs
2. **Authentication failures**
- For basic auth: verify username/password are correct
- For OAuth: check that OIDC app is properly configured
3. **OAuth persistence issues**
- Verify PVC is bound: `kubectl get pvc`
- Check storage class exists: `kubectl get storageclass`
4. **Resource constraints**
- Increase memory limits if seeing OOM errors
- Adjust CPU requests based on load
## Security Considerations
1. **Secrets Management**: Consider using external secret management (e.g., Sealed Secrets, External Secrets Operator)
2. **TLS**: Always use TLS/HTTPS for production deployments
3. **Network Policies**: Restrict network access to necessary services only
4. **RBAC**: Review and customize ServiceAccount permissions as needed
5. **App Passwords**: For basic auth, use Nextcloud app passwords instead of main account passwords
## Support
- GitHub Issues: https://github.com/cbcoutinho/nextcloud-mcp-server/issues
- Documentation: https://github.com/cbcoutinho/nextcloud-mcp-server#readme
## License
This chart is licensed under AGPL-3.0, consistent with the Nextcloud MCP Server project.
@@ -0,0 +1,80 @@
Thank you for installing {{ .Chart.Name }}!
Your Nextcloud MCP Server has been deployed in {{ .Values.auth.mode }} authentication mode.
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nextcloud-mcp-server.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nextcloud-mcp-server.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nextcloud-mcp-server.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nextcloud-mcp-server.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your MCP server"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
2. Check the deployment status:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "nextcloud-mcp-server.name" . }},app.kubernetes.io/instance={{ .Release.Name }}"
{{- if eq .Values.auth.mode "basic" }}
3. Basic Authentication Mode:
{{- if .Values.auth.basic.existingSecret }}
- Credentials: (using existing secret {{ .Values.auth.basic.existingSecret }})
{{- else }}
- Username: {{ .Values.auth.basic.username }}
- Password: (stored in secret {{ include "nextcloud-mcp-server.basicAuthSecretName" . }})
{{- end }}
- Connected to: {{ .Values.nextcloud.host }}
{{- else if eq .Values.auth.mode "oauth" }}
3. OAuth Authentication Mode:
- Server URL: {{ include "nextcloud-mcp-server.mcpServerUrl" . }}
- Issuer URL: {{ include "nextcloud-mcp-server.publicIssuerUrl" . }}
- Connected to: {{ .Values.nextcloud.host }}
{{- if .Values.auth.oauth.existingSecret }}
- Using existing OAuth client secret: {{ .Values.auth.oauth.existingSecret }}
{{- else if and .Values.auth.oauth.clientId .Values.auth.oauth.clientSecret }}
- Using pre-registered OAuth client
{{- else }}
- Using Dynamic Client Registration (DCR)
{{- end }}
{{- if .Values.auth.oauth.persistence.enabled }}
- OAuth client credentials are persisted in PVC: {{ include "nextcloud-mcp-server.oauthPvcName" . }}
{{- end }}
IMPORTANT: OAuth mode is experimental and requires patches to the user_oidc app.
See: https://github.com/cbcoutinho/nextcloud-mcp-server#authentication
{{- end }}
{{- if .Values.documentProcessing.enabled }}
4. Document Processing:
- Enabled: {{ .Values.documentProcessing.enabled }}
- Default processor: {{ .Values.documentProcessing.defaultProcessor }}
{{- if .Values.documentProcessing.unstructured.enabled }}
- Unstructured API: {{ .Values.documentProcessing.unstructured.apiUrl }}
{{- end }}
{{- end }}
For more information and documentation:
- GitHub: https://github.com/cbcoutinho/nextcloud-mcp-server
- Documentation: https://github.com/cbcoutinho/nextcloud-mcp-server#readme
To upgrade this deployment:
helm upgrade {{ .Release.Name }} nextcloud-mcp-server
To uninstall:
helm uninstall {{ .Release.Name }}
@@ -0,0 +1,146 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "nextcloud-mcp-server.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "nextcloud-mcp-server.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "nextcloud-mcp-server.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "nextcloud-mcp-server.labels" -}}
helm.sh/chart: {{ include "nextcloud-mcp-server.chart" . }}
{{ include "nextcloud-mcp-server.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "nextcloud-mcp-server.selectorLabels" -}}
app.kubernetes.io/name: {{ include "nextcloud-mcp-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "nextcloud-mcp-server.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "nextcloud-mcp-server.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the secret to use for basic auth
*/}}
{{- define "nextcloud-mcp-server.basicAuthSecretName" -}}
{{- if .Values.auth.basic.existingSecret }}
{{- .Values.auth.basic.existingSecret }}
{{- else }}
{{- include "nextcloud-mcp-server.fullname" . }}-basic-auth
{{- end }}
{{- end }}
{{/*
Create the name of the secret to use for OAuth
*/}}
{{- define "nextcloud-mcp-server.oauthSecretName" -}}
{{- if .Values.auth.oauth.existingSecret }}
{{- .Values.auth.oauth.existingSecret }}
{{- else }}
{{- include "nextcloud-mcp-server.fullname" . }}-oauth
{{- end }}
{{- end }}
{{/*
Create the name of the PVC to use for OAuth storage
*/}}
{{- define "nextcloud-mcp-server.oauthPvcName" -}}
{{- if .Values.auth.oauth.persistence.existingClaim }}
{{- .Values.auth.oauth.persistence.existingClaim }}
{{- else }}
{{- include "nextcloud-mcp-server.fullname" . }}-oauth-storage
{{- end }}
{{- end }}
{{/*
Return the appropriate MCP server port based on auth mode
*/}}
{{- define "nextcloud-mcp-server.port" -}}
{{- if eq .Values.auth.mode "oauth" }}
{{- .Values.auth.oauth.port }}
{{- else }}
{{- .Values.mcp.port }}
{{- end }}
{{- end }}
{{/*
Return the image tag
*/}}
{{- define "nextcloud-mcp-server.imageTag" -}}
{{- .Values.image.tag | default .Chart.AppVersion }}
{{- end }}
{{/*
Return the public issuer URL for OAuth
Defaults to nextcloud.host if not specified
*/}}
{{- define "nextcloud-mcp-server.publicIssuerUrl" -}}
{{- if .Values.nextcloud.publicIssuerUrl }}
{{- .Values.nextcloud.publicIssuerUrl }}
{{- else }}
{{- .Values.nextcloud.host }}
{{- end }}
{{- end }}
{{/*
Return the MCP server URL for OAuth callbacks
If not specified:
- Uses ingress host if ingress is enabled
- Otherwise defaults to http://localhost:8000 (for port-forward setups)
*/}}
{{- define "nextcloud-mcp-server.mcpServerUrl" -}}
{{- if .Values.nextcloud.mcpServerUrl }}
{{- .Values.nextcloud.mcpServerUrl }}
{{- else if .Values.ingress.enabled }}
{{- $host := index .Values.ingress.hosts 0 }}
{{- if .Values.ingress.tls }}
{{- printf "https://%s" $host.host }}
{{- else }}
{{- printf "http://%s" $host.host }}
{{- end }}
{{- else }}
{{- printf "http://localhost:%d" (int .Values.mcp.port) }}
{{- end }}
{{- end }}
@@ -0,0 +1,189 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "nextcloud-mcp-server.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "nextcloud-mcp-server.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- with .Values.initContainers }}
initContainers:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ include "nextcloud-mcp-server.imageTag" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- "--transport"
- "{{ .Values.mcp.transport }}"
{{- if eq .Values.auth.mode "oauth" }}
- "--oauth"
- "--port"
- "{{ .Values.auth.oauth.port }}"
- "--oauth-token-type"
- "{{ .Values.auth.oauth.tokenType }}"
{{- end }}
ports:
- name: http
containerPort: {{ include "nextcloud-mcp-server.port" . }}
protocol: TCP
env:
# Nextcloud connection
- name: NEXTCLOUD_HOST
value: {{ .Values.nextcloud.host | quote }}
{{- if eq .Values.auth.mode "basic" }}
# Basic auth mode
- name: NEXTCLOUD_USERNAME
valueFrom:
secretKeyRef:
name: {{ include "nextcloud-mcp-server.basicAuthSecretName" . }}
key: {{ .Values.auth.basic.usernameKey }}
- name: NEXTCLOUD_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "nextcloud-mcp-server.basicAuthSecretName" . }}
key: {{ .Values.auth.basic.passwordKey }}
{{- else if eq .Values.auth.mode "oauth" }}
# OAuth mode
- name: NEXTCLOUD_MCP_SERVER_URL
value: {{ include "nextcloud-mcp-server.mcpServerUrl" . | quote }}
- name: NEXTCLOUD_PUBLIC_ISSUER_URL
value: {{ include "nextcloud-mcp-server.publicIssuerUrl" . | quote }}
- name: NEXTCLOUD_OIDC_CLIENT_STORAGE
value: "/app/.oauth/nextcloud_oauth_client.json"
- name: NEXTCLOUD_OIDC_SCOPES
value: {{ .Values.auth.oauth.scopes | quote }}
{{- if .Values.auth.oauth.clientId }}
- name: NEXTCLOUD_OIDC_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ include "nextcloud-mcp-server.oauthSecretName" . }}
key: {{ .Values.auth.oauth.clientIdKey }}
- name: NEXTCLOUD_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ include "nextcloud-mcp-server.oauthSecretName" . }}
key: {{ .Values.auth.oauth.clientSecretKey }}
{{- end }}
{{- end }}
{{- if .Values.documentProcessing.enabled }}
# Document processing
- name: ENABLE_DOCUMENT_PROCESSING
value: {{ .Values.documentProcessing.enabled | quote }}
- name: DOCUMENT_PROCESSOR
value: {{ .Values.documentProcessing.defaultProcessor | quote }}
- name: PROGRESS_INTERVAL
value: {{ .Values.documentProcessing.progressInterval | quote }}
{{- if .Values.documentProcessing.unstructured.enabled }}
- name: ENABLE_UNSTRUCTURED
value: "true"
- name: UNSTRUCTURED_API_URL
value: {{ .Values.documentProcessing.unstructured.apiUrl | quote }}
- name: UNSTRUCTURED_TIMEOUT
value: {{ .Values.documentProcessing.unstructured.timeout | quote }}
- name: UNSTRUCTURED_STRATEGY
value: {{ .Values.documentProcessing.unstructured.strategy | quote }}
- name: UNSTRUCTURED_LANGUAGES
value: {{ .Values.documentProcessing.unstructured.languages | quote }}
{{- end }}
{{- if .Values.documentProcessing.tesseract.enabled }}
- name: ENABLE_TESSERACT
value: "true"
{{- if .Values.documentProcessing.tesseract.cmd }}
- name: TESSERACT_CMD
value: {{ .Values.documentProcessing.tesseract.cmd | quote }}
{{- end }}
- name: TESSERACT_LANG
value: {{ .Values.documentProcessing.tesseract.lang | quote }}
{{- end }}
{{- if .Values.documentProcessing.custom.enabled }}
- name: ENABLE_CUSTOM_PROCESSOR
value: "true"
- name: CUSTOM_PROCESSOR_NAME
value: {{ .Values.documentProcessing.custom.name | quote }}
- name: CUSTOM_PROCESSOR_URL
value: {{ .Values.documentProcessing.custom.url | quote }}
{{- if .Values.documentProcessing.custom.apiKey }}
- name: CUSTOM_PROCESSOR_API_KEY
value: {{ .Values.documentProcessing.custom.apiKey | quote }}
{{- end }}
- name: CUSTOM_PROCESSOR_TIMEOUT
value: {{ .Values.documentProcessing.custom.timeout | quote }}
- name: CUSTOM_PROCESSOR_TYPES
value: {{ .Values.documentProcessing.custom.types | quote }}
{{- end }}
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.extraEnvFrom }}
envFrom:
{{- toYaml . | nindent 12 }}
{{- end }}
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: tmp
mountPath: /tmp
{{- if and (eq .Values.auth.mode "oauth") .Values.auth.oauth.persistence.enabled }}
- name: oauth-storage
mountPath: /app/.oauth
{{- end }}
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: tmp
emptyDir: {}
{{- if and (eq .Values.auth.mode "oauth") .Values.auth.oauth.persistence.enabled }}
- name: oauth-storage
persistentVolumeClaim:
claimName: {{ include "nextcloud-mcp-server.oauthPvcName" . }}
{{- end }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -0,0 +1,32 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "nextcloud-mcp-server.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
@@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "nextcloud-mcp-server.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,17 @@
{{- if and (eq .Values.auth.mode "oauth") .Values.auth.oauth.persistence.enabled (not .Values.auth.oauth.persistence.existingClaim) }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}-oauth-storage
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.auth.oauth.persistence.accessMode }}
{{- if .Values.auth.oauth.persistence.storageClass }}
storageClassName: {{ .Values.auth.oauth.persistence.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.auth.oauth.persistence.size }}
{{- end }}
@@ -0,0 +1,29 @@
{{- if eq .Values.auth.mode "basic" }}
{{- if not .Values.auth.basic.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}-basic-auth
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
type: Opaque
data:
{{ .Values.auth.basic.usernameKey }}: {{ .Values.auth.basic.username | b64enc | quote }}
{{ .Values.auth.basic.passwordKey }}: {{ .Values.auth.basic.password | b64enc | quote }}
{{- end }}
{{- end }}
---
{{- if eq .Values.auth.mode "oauth" }}
{{- if and .Values.auth.oauth.clientId (not .Values.auth.oauth.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}-oauth
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
type: Opaque
data:
{{ .Values.auth.oauth.clientIdKey }}: {{ .Values.auth.oauth.clientId | b64enc | quote }}
{{ .Values.auth.oauth.clientSecretKey }}: {{ .Values.auth.oauth.clientSecret | b64enc | quote }}
{{- end }}
{{- end }}
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "nextcloud-mcp-server.fullname" . }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "nextcloud-mcp-server.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "nextcloud-mcp-server.serviceAccountName" . }}
labels:
{{- include "nextcloud-mcp-server.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}
+268
View File
@@ -0,0 +1,268 @@
# Default values for nextcloud-mcp-server
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# Number of replicas
replicaCount: 1
image:
repository: ghcr.io/cbcoutinho/nextcloud-mcp-server
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
# Nextcloud connection settings
nextcloud:
# URL of your Nextcloud instance (required)
# Example: https://cloud.example.com
host: ""
# MCP server URL for OAuth callbacks (OAuth mode only)
# If not specified, will be constructed from ingress.hosts[0] if ingress is enabled,
# or defaults to http://localhost:8000 (suitable for port-forward setups)
# Example: https://mcp.example.com
mcpServerUrl: ""
# Public issuer URL for OAuth (OAuth mode only)
# If not specified, defaults to nextcloud.host
# Only set this if your Nextcloud is accessible at a different URL for OAuth
# Example: https://cloud.example.com
publicIssuerUrl: ""
# Authentication configuration
# Choose either basic auth OR oauth (not both)
auth:
# Authentication mode: "basic" or "oauth"
# basic: Uses username/password (recommended for most users)
# oauth: Uses OAuth2/OIDC (experimental, requires patches)
mode: basic
# Basic authentication settings
basic:
# Nextcloud username (ignored if existingSecret is set)
username: ""
# Nextcloud password or app password (recommended) (ignored if existingSecret is set)
password: ""
# Use existing secret instead of creating one
# If set, username and password above are ignored
# Secret must contain keys specified in usernameKey and passwordKey
# Example:
# kubectl create secret generic my-nextcloud-creds \
# --from-literal=username=myuser \
# --from-literal=password=mypassword
existingSecret: ""
# Keys in the existing secret
usernameKey: "username"
passwordKey: "password"
# OAuth2/OIDC settings (experimental)
oauth:
# Port for OAuth MCP server (default: 8001)
port: 8001
# OAuth token type: "jwt" or "opaque"
tokenType: "jwt"
# Pre-registered OAuth client ID (optional, ignored if existingSecret is set)
# If not provided and no existingSecret, will use Dynamic Client Registration (DCR)
clientId: ""
# Pre-registered OAuth client secret (optional, ignored if existingSecret is set)
clientSecret: ""
# OAuth scopes to request (space-separated)
scopes: "openid profile email notes:read notes:write calendar:read calendar:write contacts:read contacts:write cookbook:read cookbook:write deck:read deck:write tables:read tables:write files:read files:write sharing:read sharing:write todo:read todo:write"
# Use existing secret for OAuth client credentials
# If set, clientId and clientSecret above are ignored
# Secret must contain keys specified in clientIdKey and clientSecretKey
# Example:
# kubectl create secret generic my-oauth-creds \
# --from-literal=clientId=my-client-id \
# --from-literal=clientSecret=my-client-secret
existingSecret: ""
# Keys in the existing secret
clientIdKey: "clientId"
clientSecretKey: "clientSecret"
# Persistent storage for OAuth client credentials
persistence:
enabled: true
# Storage class (leave empty for default)
storageClass: ""
accessMode: ReadWriteOnce
size: 100Mi
# Use existing PVC
existingClaim: ""
# MCP server configuration
mcp:
# Transport mode (default: streamable-http for SSE)
transport: "streamable-http"
# Port for basic auth mode
port: 8000
# Document processing configuration (optional)
documentProcessing:
# Enable document processing (PDF, DOCX, images, etc.)
enabled: false
# Default processor: unstructured, tesseract, or custom
defaultProcessor: "unstructured"
# Progress reporting interval in seconds
progressInterval: 10
# Unstructured.io processor
unstructured:
enabled: false
# Unstructured API endpoint
apiUrl: "http://unstructured:8000"
# Request timeout in seconds
timeout: 120
# Parsing strategy: auto, fast, or hi_res
strategy: "auto"
# OCR languages (comma-separated ISO 639-3 codes)
languages: "eng,deu"
# Tesseract processor (local OCR)
tesseract:
enabled: false
# Path to tesseract executable (optional, auto-detected if in PATH)
cmd: ""
# OCR language (e.g., eng, deu, eng+deu for multiple)
lang: "eng"
# Custom processor
custom:
enabled: false
# Unique name for your processor
name: "my_ocr"
# Custom processor API endpoint
url: ""
# Optional API key for authentication
apiKey: ""
# Request timeout in seconds
timeout: 60
# Comma-separated MIME types your processor supports
types: "application/pdf,image/jpeg,image/png"
serviceAccount:
# Specifies whether a service account should be created
create: true
# Automatically mount a ServiceAccount's API credentials?
automount: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podLabels: {}
podSecurityContext:
fsGroup: 2000
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
service:
type: ClusterIP
port: 8000
# For OAuth mode, you may want to expose both ports
oauthPort: 8001
annotations: {}
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: nextcloud-mcp-tls
# hosts:
# - mcp.example.com
resources:
# We recommend setting resource requests and limits
limits:
cpu: 1000m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# Liveness probe configuration
# Checks if the application process is running
livenessProbe:
httpGet:
path: /health/live
port: http
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
# Readiness probe configuration
# Checks if the application is ready to serve traffic
readinessProbe:
httpGet:
path: /health/ready
port: http
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
# Autoscaling configuration
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# Additional volumes on the output Deployment definition.
volumes: []
# - name: foo
# secret:
# secretName: mysecret
# optional: false
# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
# - name: foo
# mountPath: "/etc/foo"
# readOnly: true
nodeSelector: {}
tolerations: []
affinity: {}
# Init containers
initContainers: []
# Additional environment variables
extraEnv: []
# - name: CUSTOM_VAR
# value: "custom_value"
# Additional environment variables from ConfigMaps or Secrets
extraEnvFrom: []
# - configMapRef:
# name: my-configmap
# - secretRef:
# name: my-secret
+3 -3
View File
@@ -21,7 +21,7 @@ services:
restart: always
app:
image: docker.io/library/nextcloud:32.0.1@sha256:42a36b4711191273a9cf8cebfd35602909eb1bee461b7076d4d5a57f7ec2b81e
image: docker.io/library/nextcloud:32.0.1@sha256:1e4eae55eebe094cae6f9e7b6e0b4bccf4a4fe7b7e6f6f8f57010994b3b2ee42
restart: always
ports:
- 0.0.0.0:8080:80
@@ -45,14 +45,14 @@ services:
- REDIS_HOST=redis
recipes:
image: docker.io/library/nginx:alpine@sha256:61e01287e546aac28a3f56839c136b31f590273f3b41187a36f46f6a03bbfe22
image: docker.io/library/nginx:alpine@sha256:9dacca6749f2215cc3094f641c5b6662f7791e66a57ed034e806a7c48d51c18f
restart: always
volumes:
- ./tests/fixtures/test_recipe.html:/usr/share/nginx/html/test_recipe.html:ro
- ./tests/fixtures/nginx.conf:/etc/nginx/nginx.conf:ro
unstructured:
image: downloads.unstructured.io/unstructured-io/unstructured-api:latest
image: downloads.unstructured.io/unstructured-io/unstructured-api:latest@sha256:a43ab55898599157fb0e0e097dabb8ecdd1d8e3df1ae5b67c6e15a136b171a6c
restart: always
ports:
- 127.0.0.1:8002:8000
+64
View File
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nextcloud MCP Server Helm Chart</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
line-height: 1.6;
}
code {
background: #f4f4f4;
padding: 2px 6px;
border-radius: 3px;
font-family: "Monaco", "Courier New", monospace;
}
pre {
background: #f4f4f4;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
}
h1, h2 { color: #0082c9; }
a { color: #0082c9; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>Nextcloud MCP Server Helm Chart</h1>
<p>A Helm chart for deploying the Nextcloud MCP (Model Context Protocol) Server on Kubernetes, enabling AI assistants to interact with your Nextcloud instance.</p>
<h2>Installation</h2>
<p>Add the Helm repository:</p>
<pre><code>helm repo add nextcloud-mcp https://cbcoutinho.github.io/nextcloud-mcp-server/
helm repo update</code></pre>
<p>Install the chart:</p>
<pre><code>helm install nextcloud-mcp nextcloud-mcp/nextcloud-mcp-server \
--set nextcloud.host=https://cloud.example.com \
--set auth.basic.username=myuser \
--set auth.basic.password=mypassword</code></pre>
<h2>Documentation</h2>
<ul>
<li><a href="README.md">Chart README</a> - Full documentation for the Helm chart</li>
<li><a href="https://github.com/cbcoutinho/nextcloud-mcp-server">GitHub Repository</a> - Source code and issues</li>
<li><a href="index.yaml">Helm Repository Index</a> - Chart metadata</li>
</ul>
<h2>Quick Start</h2>
<p>See the <a href="README.md">full documentation</a> for detailed configuration options, examples, and troubleshooting guides.</p>
<hr>
<p><small>Generated by <a href="https://github.com/helm/chart-releaser">chart-releaser</a></small></p>
</body>
</html>
+6540
View File
File diff suppressed because it is too large Load Diff
+63
View File
@@ -648,8 +648,71 @@ def get_app(transport: str = "sse", enabled_apps: list[str] | None = None):
await stack.enter_async_context(mcp.session_manager.run())
yield
# Health check endpoints for Kubernetes probes
def health_live(request):
"""Liveness probe endpoint.
Returns 200 OK if the application process is running.
This is a simple check that doesn't verify external dependencies.
"""
return JSONResponse(
{
"status": "alive",
"mode": "oauth" if oauth_enabled else "basic",
}
)
async def health_ready(request):
"""Readiness probe endpoint.
Returns 200 OK if the application is ready to serve traffic.
Checks that required configuration is present.
"""
checks = {}
is_ready = True
# Check Nextcloud host configuration
nextcloud_host = os.getenv("NEXTCLOUD_HOST")
if nextcloud_host:
checks["nextcloud_configured"] = "ok"
else:
checks["nextcloud_configured"] = "error: NEXTCLOUD_HOST not set"
is_ready = False
# Check authentication configuration
if oauth_enabled:
# OAuth mode - just verify we got this far (token_verifier initialized in lifespan)
checks["auth_mode"] = "oauth"
checks["auth_configured"] = "ok"
else:
# BasicAuth mode - verify credentials are set
username = os.getenv("NEXTCLOUD_USERNAME")
password = os.getenv("NEXTCLOUD_PASSWORD")
if username and password:
checks["auth_mode"] = "basic"
checks["auth_configured"] = "ok"
else:
checks["auth_mode"] = "basic"
checks["auth_configured"] = "error: credentials not set"
is_ready = False
status_code = 200 if is_ready else 503
return JSONResponse(
{
"status": "ready" if is_ready else "not_ready",
"checks": checks,
},
status_code=status_code,
)
# Add Protected Resource Metadata (PRM) endpoint for OAuth mode
routes = []
# Add health check routes (available in both OAuth and BasicAuth modes)
routes.append(Route("/health/live", health_live, methods=["GET"]))
routes.append(Route("/health/ready", health_ready, methods=["GET"]))
logger.info("Health check endpoints enabled: /health/live, /health/ready")
if oauth_enabled:
def oauth_protected_resource_metadata(request):
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "nextcloud-mcp-server"
version = "0.21.0"
version = "0.22.0"
description = "Model Context Protocol (MCP) server for Nextcloud integration - enables AI assistants to interact with Nextcloud data"
authors = [
{name = "Chris Coutinho", email = "chris@coutinho.io"}
+11 -3
View File
@@ -253,9 +253,17 @@ def test_default_values(runner, clean_env, monkeypatch):
_ = runner.invoke(run, [])
# Verify default values
assert (
captured_env["NEXTCLOUD_OIDC_SCOPES"]
== "openid profile email notes:read notes:write calendar:read calendar:write contacts:read contacts:write cookbook:read cookbook:write deck:read deck:write tables:read tables:write files:read files:write sharing:read sharing:write"
assert captured_env["NEXTCLOUD_OIDC_SCOPES"] == (
"openid profile email "
"notes:read notes:write "
"calendar:read calendar:write "
"todo:read todo:write "
"contacts:read contacts:write "
"cookbook:read cookbook:write "
"deck:read deck:write "
"tables:read tables:write "
"files:read files:write "
"sharing:read sharing:write"
)
assert captured_env["NEXTCLOUD_OIDC_TOKEN_TYPE"] == "bearer"
assert captured_env["NEXTCLOUD_MCP_SERVER_URL"] == "http://localhost:8000"
Generated
+1 -1
View File
@@ -941,7 +941,7 @@ wheels = [
[[package]]
name = "nextcloud-mcp-server"
version = "0.21.0"
version = "0.22.0"
source = { editable = "." }
dependencies = [
{ name = "caldav" },