diff --git a/.gitignore b/.gitignore index 5b2ce30..673aa5a 100644 --- a/.gitignore +++ b/.gitignore @@ -494,3 +494,7 @@ $RECYCLE.BIN/ # Vim temporary swap files *.swp .claude/settings.local.json + +# Nix build outputs +result +result-* diff --git a/deps-cli.json b/deps-cli.json new file mode 100644 index 0000000..46d5135 --- /dev/null +++ b/deps-cli.json @@ -0,0 +1,377 @@ +[ + { + "pname": "Azure.Core", + "version": "1.44.1", + "hash": "sha256-0su/ylZ68+FDZ6mgfp3qsm7qpfPtD5SW75HXbVhs5qk=" + }, + { + "pname": "Google.Apis", + "version": "1.68.0", + "hash": "sha256-KUFT+rWxzeWVMWc34cqrFs1N/FxvG15vWqZruwWXHX4=" + }, + { + "pname": "Google.Apis", + "version": "1.69.0", + "hash": "sha256-/9JN0CZIFZnmGS69ki38RlNzQiwp4yO0MFDeRk1slsg=" + }, + { + "pname": "Google.Apis.Auth", + "version": "1.69.0", + "hash": "sha256-T6n3hc+KpgHNqQQeJLOmgHQWkjBvnhIob5giHabREV8=" + }, + { + "pname": "Google.Apis.Calendar.v3", + "version": "1.68.0.3592", + "hash": "sha256-h/LOC5qTKtA5A4qJmldufRtq2mlJhTm1V4ZkfOzuqX4=" + }, + { + "pname": "Google.Apis.Core", + "version": "1.69.0", + "hash": "sha256-IW1AOY8o6hHkrc/tINsS/VCOUrOSoXb6OCSEF6gamkc=" + }, + { + "pname": "Google.Apis.Gmail.v1", + "version": "1.69.0.3742", + "hash": "sha256-8q5sv9NZDwYMYd1eAda4SCPQHGeYmCdQ2bAQSnjBhJo=" + }, + { + "pname": "Microsoft.Bcl.AsyncInterfaces", + "version": "6.0.0", + "hash": "sha256-49+H/iFwp+AfCICvWcqo9us4CzxApPKC37Q5Eqrw+JU=" + }, + { + "pname": "Microsoft.Bcl.TimeProvider", + "version": "8.0.1", + "hash": "sha256-TQRaWjk1aZu+jn/rR8oOv8BJEG31i6mPkf3BkIR7C+c=" + }, + { + "pname": "Microsoft.Extensions.AI.Abstractions", + "version": "10.0.0", + "hash": "sha256-hEvvw5jQCOvUOCqLC//TGTDVTdSCgAXmqTMmxG5QoWo=" + }, + { + "pname": "Microsoft.Extensions.Configuration", + "version": "10.0.0", + "hash": "sha256-MsLskVPpkCvov5+DWIaALCt1qfRRX4u228eHxvpE0dg=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Abstractions", + "version": "10.0.0", + "hash": "sha256-GcgrnTAieCV7AVT13zyOjfwwL86e99iiO/MiMOxPGG0=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Binder", + "version": "10.0.0", + "hash": "sha256-YSiWoA3VQR22k6+bSEAUqeG7UDzZlJfHWDTubUO5V8U=" + }, + { + "pname": "Microsoft.Extensions.Configuration.FileExtensions", + "version": "10.0.0", + "hash": "sha256-rN+3rqrHiTaBfHgP+E4dA8Qm2cFJPfbEcd93yKLsqlQ=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Json", + "version": "10.0.0", + "hash": "sha256-VCFukgsxiQ2MFGE6RDMFTGopBHbcZL2t0ER7ENaFXRY=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection", + "version": "10.0.0", + "hash": "sha256-LYm9hVlo/R9c2aAKHsDYJ5vY9U0+3Jvclme3ou3BtvQ=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.0", + "hash": "sha256-9iodXP39YqgxomnOPOxd/mzbG0JfOSXzFoNU3omT2Ps=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics.Abstractions", + "version": "10.0.0", + "hash": "sha256-cix7QxQ/g3sj6reXu3jn0cRv2RijzceaLLkchEGTt5E=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Abstractions", + "version": "10.0.0", + "hash": "sha256-CHDs2HCN8QcfuYQpgNVszZ5dfXFe4yS9K2GoQXecc20=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Physical", + "version": "10.0.0", + "hash": "sha256-2Rw/cwBO+/A3QY2IjN/c8Y0LhtC1qTBL7VdJiD1J2UQ=" + }, + { + "pname": "Microsoft.Extensions.FileSystemGlobbing", + "version": "10.0.0", + "hash": "sha256-ETfVTdsdBtp69EggLg/AARTQW4lLQYVdVldXIQrsjZA=" + }, + { + "pname": "Microsoft.Extensions.Hosting.Abstractions", + "version": "10.0.0", + "hash": "sha256-Sub3Thay/+eR84cEODk/nPh1oYIYtawvDX6r0duReqo=" + }, + { + "pname": "Microsoft.Extensions.Logging", + "version": "10.0.0", + "hash": "sha256-P+zPAadLL63k/GqK34/qChqQjY9aIRxZfxlB9lqsSrs=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.0", + "hash": "sha256-BnhgGZc01HwTSxogavq7Ueq4V7iMA3wPnbfRwQ4RhGk=" + }, + { + "pname": "Microsoft.Extensions.Logging.Configuration", + "version": "10.0.0", + "hash": "sha256-7/TWO1aq8hdgbcTEKDBWIjgSC9KpFN3kRnMX+12bOkU=" + }, + { + "pname": "Microsoft.Extensions.Logging.Console", + "version": "10.0.0", + "hash": "sha256-Rsblo7GSMTOr43876KkdvqS6wU9Typ1yoFK3tL50CBk=" + }, + { + "pname": "Microsoft.Extensions.Options", + "version": "10.0.0", + "hash": "sha256-j5MOqZSKeUtxxzmZjzZMGy0vELHdvPraqwTQQQNVsYA=" + }, + { + "pname": "Microsoft.Extensions.Options.ConfigurationExtensions", + "version": "10.0.0", + "hash": "sha256-XGAs5DxMvWnmjX8dqRwKY0vsuS40SHvsfJqB1rO4L7k=" + }, + { + "pname": "Microsoft.Extensions.Primitives", + "version": "10.0.0", + "hash": "sha256-Dup08KcptLjlnpN5t5//+p4n8FUTgRAq4n/w1s6us+I=" + }, + { + "pname": "Microsoft.Graph", + "version": "5.68.0", + "hash": "sha256-N1LWR2yOFw8iQa31r1ZO7pM984AcJR89u8ahzb9GmqE=" + }, + { + "pname": "Microsoft.Graph.Core", + "version": "3.2.1", + "hash": "sha256-LeZmexKC22SFSVg98WtK7tA0xiDJgx6unld6mbRalt0=" + }, + { + "pname": "Microsoft.Identity.Client", + "version": "4.66.2", + "hash": "sha256-xAAaQJX/RsOujoPBtG8Zn4YIaJKODyx7SOzPAelxD5I=" + }, + { + "pname": "Microsoft.Identity.Client.Extensions.Msal", + "version": "4.66.2", + "hash": "sha256-KFN3M4ejGt5nRCMTJ/LMh5DoPCKuo82GN+B5suIxTKo=" + }, + { + "pname": "Microsoft.IdentityModel.Abstractions", + "version": "6.35.0", + "hash": "sha256-bxyYu6/QgaA4TQYBr5d+bzICL+ktlkdy/tb/1fBu00Q=" + }, + { + "pname": "Microsoft.IdentityModel.Abstractions", + "version": "8.2.0", + "hash": "sha256-e+BmN/Et9mTqWt4M38udL47M4wHHs25Ob299gJSBZIM=" + }, + { + "pname": "Microsoft.IdentityModel.JsonWebTokens", + "version": "8.2.0", + "hash": "sha256-tOzI2GmMISuWO/vDtJIeKmYAaFPYjrB5NhpzCWWcIw4=" + }, + { + "pname": "Microsoft.IdentityModel.Logging", + "version": "8.2.0", + "hash": "sha256-JdrIo2Dg9UPu/eK5TIPKLWfRmvPGhKZrBCQL+MIv72I=" + }, + { + "pname": "Microsoft.IdentityModel.Protocols", + "version": "8.2.0", + "hash": "sha256-Tud941SQnR7fJzCC5WllIN8X1sqBTf7RDxU6PXVwN2A=" + }, + { + "pname": "Microsoft.IdentityModel.Protocols.OpenIdConnect", + "version": "8.2.0", + "hash": "sha256-VcS01u6w+fWfdAMF43W2SlV0yX28xAbNOBXwtB0cIS8=" + }, + { + "pname": "Microsoft.IdentityModel.Tokens", + "version": "8.2.0", + "hash": "sha256-QxhnZVUrKKUZEKZgok2+4HjawuXZtVhXCJ2+BDomja8=" + }, + { + "pname": "Microsoft.IdentityModel.Validators", + "version": "8.2.0", + "hash": "sha256-QagwQJWdRN3T2bnRpvyJMUBdWOADkG7k1w9p0VhWKto=" + }, + { + "pname": "Microsoft.Kiota.Abstractions", + "version": "1.14.0", + "hash": "sha256-/3XjWnJ0l9Rlt3x5M3035DnvqHKojV86N1drobJ4vVI=" + }, + { + "pname": "Microsoft.Kiota.Abstractions", + "version": "1.15.2", + "hash": "sha256-DGM9G/VW+xK+ataekRjsuuOT0IFdv7z21SqkUBqRyPc=" + }, + { + "pname": "Microsoft.Kiota.Authentication.Azure", + "version": "1.15.2", + "hash": "sha256-3WEpq2WeOGKQBGtvdrGIuidFESz9hgJSTu6sbabIm/k=" + }, + { + "pname": "Microsoft.Kiota.Http.HttpClientLibrary", + "version": "1.15.2", + "hash": "sha256-8xNwGEq/zX27Om4CpP2fTR8ls6yY8C+ZX88r75tw3Eg=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Form", + "version": "1.14.0", + "hash": "sha256-Uv5TQj01xUxr8ZPmcpunfo0w6o6Ds5Vv1aZyBP6/Uzs=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Json", + "version": "1.15.2", + "hash": "sha256-2eSjIdPbq3bL5HPFfwnlXaquEChgwu0UixmkAmpAdCM=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Multipart", + "version": "1.14.0", + "hash": "sha256-PopI4m/DSee6AQ4gyNQtasKWuuyC9dluXB1T8Gp5wZs=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Text", + "version": "1.14.0", + "hash": "sha256-usNV4TAFlvYTRVC4pzD11XyeXkO5CWzagj9BcBxAUHs=" + }, + { + "pname": "ModelContextProtocol", + "version": "0.4.1-preview.1", + "hash": "sha256-9PbHfpjDoNuzcAqazDfXHgoefJd8Aa8AFzUmjoxD/58=" + }, + { + "pname": "ModelContextProtocol.Core", + "version": "0.4.1-preview.1", + "hash": "sha256-NyHcXRhdLzf0GdaY1SKRcDLaE7B4ZdIO9kIqKfTLAFk=" + }, + { + "pname": "Newtonsoft.Json", + "version": "13.0.3", + "hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc=" + }, + { + "pname": "Spectre.Console", + "version": "0.49.1", + "hash": "sha256-tqSVojyuQjuB34lXo759NOcyLgNIw815mKXJPq5JFDo=" + }, + { + "pname": "Spectre.Console.Cli", + "version": "0.49.1", + "hash": "sha256-sar9rhft1ivDMj1kU683+4KxUPUZL+Fb++ewMA6RD4Q=" + }, + { + "pname": "Std.UriTemplate", + "version": "2.0.1", + "hash": "sha256-SBp+7foUJVRYfNz6xa96oC2DYDXZVjTONbNJr29AuXc=" + }, + { + "pname": "System.ClientModel", + "version": "1.1.0", + "hash": "sha256-FiueWJawZGar++OztDFWxU2nQE5Vih9iYsc3uEx0thM=" + }, + { + "pname": "System.CodeDom", + "version": "7.0.0", + "hash": "sha256-7IPt39cY+0j0ZcRr/J45xPtEjnSXdUJ/5ai3ebaYQiE=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "10.0.0", + "hash": "sha256-t7NakmBNSZbMIU802EpfPwNUHwS7Sd9GlebOHvYty+M=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "6.0.1", + "hash": "sha256-Xi8wrUjVlioz//TPQjFHqcV/QGhTqnTfUcltsNlcCJ4=" + }, + { + "pname": "System.IdentityModel.Tokens.Jwt", + "version": "8.2.0", + "hash": "sha256-Htz1I19N0/IWHF8tbyZC90wCqI5xLh42jMXI3GXkCP4=" + }, + { + "pname": "System.IO.Pipelines", + "version": "10.0.0", + "hash": "sha256-0aeIxLFEBn9BoCa93UVNikdlqgPl3B1nmYCLQ9Yu9Ak=" + }, + { + "pname": "System.Management", + "version": "7.0.2", + "hash": "sha256-bJ21ILQfbHb8mX2wnVh7WP/Ip7gdVPIw+BamQuifTVY=" + }, + { + "pname": "System.Memory.Data", + "version": "1.0.2", + "hash": "sha256-XiVrVQZQIz4NgjiK/wtH8iZhhOZ9MJ+X2hL2/8BrGN0=" + }, + { + "pname": "System.Memory.Data", + "version": "6.0.0", + "hash": "sha256-83/bxn3vyv17dQDDqH1L3yDpluhOxIS5XR27f4OnCEo=" + }, + { + "pname": "System.Net.ServerSentEvents", + "version": "10.0.0", + "hash": "sha256-Ez92vnxlAEH1q0tl7VwOihlU49eCD1eAbYEU4Dyeds8=" + }, + { + "pname": "System.Numerics.Vectors", + "version": "4.5.0", + "hash": "sha256-qdSTIFgf2htPS+YhLGjAGiLN8igCYJnCCo6r78+Q+c8=" + }, + { + "pname": "System.Runtime.CompilerServices.Unsafe", + "version": "6.0.0", + "hash": "sha256-bEG1PnDp7uKYz/OgLOWs3RWwQSVYm+AnPwVmAmcgp2I=" + }, + { + "pname": "System.Security.Cryptography.ProtectedData", + "version": "4.5.0", + "hash": "sha256-Z+X1Z2lErLL7Ynt2jFszku6/IgrngO3V1bSfZTBiFIc=" + }, + { + "pname": "System.Text.Encodings.Web", + "version": "10.0.0", + "hash": "sha256-OrsgqAPfEjjo+CzzrAzkKTXNv3VXw2dm3Wpn+uRHCM8=" + }, + { + "pname": "System.Text.Encodings.Web", + "version": "6.0.0", + "hash": "sha256-UemDHGFoQIG7ObQwRluhVf6AgtQikfHEoPLC6gbFyRo=" + }, + { + "pname": "System.Text.Json", + "version": "10.0.0", + "hash": "sha256-ZyAMIT3yQDJazYAObAlXmScGshGD9MVZgYmLqHyICq0=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.0", + "hash": "sha256-9AE/5ds4DqEfb0l+27fCBTSeYCdRWhxh2Bhg8IKvIuo=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.10", + "hash": "sha256-UijYh0dxFjFinMPSTJob96oaRkNm+Wsa+7Ffg6mRnsc=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.9", + "hash": "sha256-5jjvxV8ubGYjkydDhLsGZXB6ml3O/7CGauQcu1ikeLs=" + }, + { + "pname": "System.Threading.Tasks.Extensions", + "version": "4.5.4", + "hash": "sha256-owSpY8wHlsUXn5xrfYAiu847L6fAKethlvYx97Ri1ng=" + } +] diff --git a/deps-server.json b/deps-server.json new file mode 100644 index 0000000..2c26b2f --- /dev/null +++ b/deps-server.json @@ -0,0 +1,562 @@ +[ + { + "pname": "Azure.Core", + "version": "1.44.1", + "hash": "sha256-0su/ylZ68+FDZ6mgfp3qsm7qpfPtD5SW75HXbVhs5qk=" + }, + { + "pname": "Google.Apis", + "version": "1.68.0", + "hash": "sha256-KUFT+rWxzeWVMWc34cqrFs1N/FxvG15vWqZruwWXHX4=" + }, + { + "pname": "Google.Apis", + "version": "1.69.0", + "hash": "sha256-/9JN0CZIFZnmGS69ki38RlNzQiwp4yO0MFDeRk1slsg=" + }, + { + "pname": "Google.Apis.Auth", + "version": "1.68.0", + "hash": "sha256-pptb3sxuFZMREdgGDJzdOSfn84XF5PMzzXwe+w7N+kQ=" + }, + { + "pname": "Google.Apis.Auth", + "version": "1.69.0", + "hash": "sha256-T6n3hc+KpgHNqQQeJLOmgHQWkjBvnhIob5giHabREV8=" + }, + { + "pname": "Google.Apis.Calendar.v3", + "version": "1.68.0.3592", + "hash": "sha256-h/LOC5qTKtA5A4qJmldufRtq2mlJhTm1V4ZkfOzuqX4=" + }, + { + "pname": "Google.Apis.Core", + "version": "1.69.0", + "hash": "sha256-IW1AOY8o6hHkrc/tINsS/VCOUrOSoXb6OCSEF6gamkc=" + }, + { + "pname": "Google.Apis.Gmail.v1", + "version": "1.69.0.3742", + "hash": "sha256-8q5sv9NZDwYMYd1eAda4SCPQHGeYmCdQ2bAQSnjBhJo=" + }, + { + "pname": "Google.Protobuf", + "version": "3.22.5", + "hash": "sha256-KuPCqobX6vE9RYElAN9vw+FPonFipms7kE/cRDCLmSQ=" + }, + { + "pname": "Grpc.Core.Api", + "version": "2.52.0", + "hash": "sha256-ISgN3zWwvV8qD7JFkaYveLbke09+UtUBy3Tux+ZHLNc=" + }, + { + "pname": "Grpc.Net.Client", + "version": "2.52.0", + "hash": "sha256-4Rhb8PIoV2BiohfRwzx1GYDPbcfqxGAmL2uB0atFFTk=" + }, + { + "pname": "Grpc.Net.Common", + "version": "2.52.0", + "hash": "sha256-XoY+jt+JIt6SzvCjUSXKKa9Q8Bu5UrNJv2z1hCBKDrY=" + }, + { + "pname": "Microsoft.Bcl.AsyncInterfaces", + "version": "6.0.0", + "hash": "sha256-49+H/iFwp+AfCICvWcqo9us4CzxApPKC37Q5Eqrw+JU=" + }, + { + "pname": "Microsoft.Bcl.TimeProvider", + "version": "8.0.1", + "hash": "sha256-TQRaWjk1aZu+jn/rR8oOv8BJEG31i6mPkf3BkIR7C+c=" + }, + { + "pname": "Microsoft.Extensions.AI.Abstractions", + "version": "10.0.0", + "hash": "sha256-hEvvw5jQCOvUOCqLC//TGTDVTdSCgAXmqTMmxG5QoWo=" + }, + { + "pname": "Microsoft.Extensions.Configuration", + "version": "9.0.0", + "hash": "sha256-uBLeb4z60y8z7NelHs9uT3cLD6wODkdwyfJm6/YZLDM=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Abstractions", + "version": "10.0.0", + "hash": "sha256-GcgrnTAieCV7AVT13zyOjfwwL86e99iiO/MiMOxPGG0=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Abstractions", + "version": "9.0.0", + "hash": "sha256-xtG2USC9Qm0f2Nn6jkcklpyEDT3hcEZOxOwTc0ep7uc=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Binder", + "version": "9.0.0", + "hash": "sha256-6ajYWcNOQX2WqftgnoUmVtyvC1kkPOtTCif4AiKEffU=" + }, + { + "pname": "Microsoft.Extensions.Configuration.CommandLine", + "version": "9.0.0", + "hash": "sha256-RE6DotU1FM1sy5p3hukT+WOFsDYJRsKX6jx5vhlPceM=" + }, + { + "pname": "Microsoft.Extensions.Configuration.EnvironmentVariables", + "version": "9.0.0", + "hash": "sha256-tDJx2prYZpr0RKSwmJfsK9FlUGwaDmyuSz2kqQxsWoI=" + }, + { + "pname": "Microsoft.Extensions.Configuration.FileExtensions", + "version": "9.0.0", + "hash": "sha256-PsLo6mrLGYfbi96rfCG8YS1APXkUXBG4hLstpT60I4s=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Json", + "version": "9.0.0", + "hash": "sha256-qQn7Ol0CvPYuyecYWYBkPpTMdocO7I6n+jXQI2udzLI=" + }, + { + "pname": "Microsoft.Extensions.Configuration.UserSecrets", + "version": "9.0.0", + "hash": "sha256-GoEk+Qq7lbiwWurHYx1LkDaUzIpOzaoTiVGDPfViGak=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection", + "version": "9.0.0", + "hash": "sha256-dAH52PPlTLn7X+1aI/7npdrDzMEFPMXRv4isV1a+14k=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.0", + "hash": "sha256-9iodXP39YqgxomnOPOxd/mzbG0JfOSXzFoNU3omT2Ps=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "8.0.0", + "hash": "sha256-75KzEGWjbRELczJpCiJub+ltNUMMbz5A/1KQU+5dgP8=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "9.0.0", + "hash": "sha256-CncVwkKZ5CsIG2O0+OM9qXuYXh3p6UGyueTHSLDVL+c=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics", + "version": "9.0.0", + "hash": "sha256-JMbhtjdcWRlrcrbgPlowfj26+pM+MYhnPIaYKnv9byU=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics.Abstractions", + "version": "10.0.0", + "hash": "sha256-cix7QxQ/g3sj6reXu3jn0cRv2RijzceaLLkchEGTt5E=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics.Abstractions", + "version": "9.0.0", + "hash": "sha256-wG1LcET+MPRjUdz3HIOTHVEnbG/INFJUqzPErCM79eY=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Abstractions", + "version": "10.0.0", + "hash": "sha256-CHDs2HCN8QcfuYQpgNVszZ5dfXFe4yS9K2GoQXecc20=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Abstractions", + "version": "9.0.0", + "hash": "sha256-mVfLjZ8VrnOQR/uQjv74P2uEG+rgW72jfiGdSZhIfDc=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Physical", + "version": "9.0.0", + "hash": "sha256-IzFpjKHmF1L3eVbFLUZa2N5aH3oJkJ7KE1duGIS7DP8=" + }, + { + "pname": "Microsoft.Extensions.FileSystemGlobbing", + "version": "9.0.0", + "hash": "sha256-eBLa8pW/y/hRj+JbEr340zbHRABIeFlcdqE0jf5/Uhc=" + }, + { + "pname": "Microsoft.Extensions.Hosting", + "version": "9.0.0", + "hash": "sha256-apIN4Cz86ujsMp/ibxcvguA9uCFaFqOsZ4kAUPX5ASI=" + }, + { + "pname": "Microsoft.Extensions.Hosting.Abstractions", + "version": "10.0.0", + "hash": "sha256-Sub3Thay/+eR84cEODk/nPh1oYIYtawvDX6r0duReqo=" + }, + { + "pname": "Microsoft.Extensions.Hosting.Abstractions", + "version": "8.0.0", + "hash": "sha256-0JBx+wwt5p1SPfO4m49KxNOXPAzAU0A+8tEc/itvpQE=" + }, + { + "pname": "Microsoft.Extensions.Hosting.Abstractions", + "version": "9.0.0", + "hash": "sha256-NhEDqZGnwCDFyK/NKn1dwLQExYE82j1YVFcrhXVczqY=" + }, + { + "pname": "Microsoft.Extensions.Logging", + "version": "8.0.0", + "hash": "sha256-Meh0Z0X7KyOEG4l0RWBcuHHihcABcvCyfUXgasmQ91o=" + }, + { + "pname": "Microsoft.Extensions.Logging", + "version": "9.0.0", + "hash": "sha256-kR16c+N8nQrWeYLajqnXPg7RiXjZMSFLnKLEs4VfjcM=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.0", + "hash": "sha256-BnhgGZc01HwTSxogavq7Ueq4V7iMA3wPnbfRwQ4RhGk=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "3.0.3", + "hash": "sha256-UFawgCAhbN5HCtJy39XO4sz5N/P/Zyrs0uqrQHc4SPI=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "8.0.0", + "hash": "sha256-Jmddjeg8U5S+iBTwRlVAVLeIHxc4yrrNgqVMOB7EjM4=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "9.0.0", + "hash": "sha256-iBTs9twjWXFeERt4CErkIIcoJZU1jrd1RWCI8V5j7KU=" + }, + { + "pname": "Microsoft.Extensions.Logging.Configuration", + "version": "9.0.0", + "hash": "sha256-ysPjBq64p6JM4EmeVndryXnhLWHYYszzlVpPxRWkUkw=" + }, + { + "pname": "Microsoft.Extensions.Logging.Console", + "version": "9.0.0", + "hash": "sha256-N2t9EUdlS6ippD4Z04qUUyBuQ4tKSR/8TpmKScb5zRw=" + }, + { + "pname": "Microsoft.Extensions.Logging.Debug", + "version": "9.0.0", + "hash": "sha256-5W6fP9Eb98U3MTWKeLzSNl2cRFpE694OOPjpWp/qTAk=" + }, + { + "pname": "Microsoft.Extensions.Logging.EventLog", + "version": "9.0.0", + "hash": "sha256-mIL1I85Ef5+/mXl24odoUpcXet+jCZTRtKCd5z6YUwI=" + }, + { + "pname": "Microsoft.Extensions.Logging.EventSource", + "version": "9.0.0", + "hash": "sha256-pplZskMsR3gGbs3I0wycGsvIMPIpfWFJpOsR9GkiYRw=" + }, + { + "pname": "Microsoft.Extensions.Options", + "version": "10.0.0", + "hash": "sha256-j5MOqZSKeUtxxzmZjzZMGy0vELHdvPraqwTQQQNVsYA=" + }, + { + "pname": "Microsoft.Extensions.Options", + "version": "9.0.0", + "hash": "sha256-DT5euAQY/ItB5LPI8WIp6Dnd0lSvBRP35vFkOXC68ck=" + }, + { + "pname": "Microsoft.Extensions.Options.ConfigurationExtensions", + "version": "9.0.0", + "hash": "sha256-r1Z3sEVSIjeH2UKj+KMj86har68g/zybSqoSjESBcoA=" + }, + { + "pname": "Microsoft.Extensions.Primitives", + "version": "10.0.0", + "hash": "sha256-Dup08KcptLjlnpN5t5//+p4n8FUTgRAq4n/w1s6us+I=" + }, + { + "pname": "Microsoft.Extensions.Primitives", + "version": "9.0.0", + "hash": "sha256-ZNLusK1CRuq5BZYZMDqaz04PIKScE2Z7sS2tehU7EJs=" + }, + { + "pname": "Microsoft.Graph", + "version": "5.68.0", + "hash": "sha256-N1LWR2yOFw8iQa31r1ZO7pM984AcJR89u8ahzb9GmqE=" + }, + { + "pname": "Microsoft.Graph.Core", + "version": "3.2.1", + "hash": "sha256-LeZmexKC22SFSVg98WtK7tA0xiDJgx6unld6mbRalt0=" + }, + { + "pname": "Microsoft.Identity.Client", + "version": "4.66.2", + "hash": "sha256-xAAaQJX/RsOujoPBtG8Zn4YIaJKODyx7SOzPAelxD5I=" + }, + { + "pname": "Microsoft.Identity.Client.Extensions.Msal", + "version": "4.66.2", + "hash": "sha256-KFN3M4ejGt5nRCMTJ/LMh5DoPCKuo82GN+B5suIxTKo=" + }, + { + "pname": "Microsoft.IdentityModel.Abstractions", + "version": "6.35.0", + "hash": "sha256-bxyYu6/QgaA4TQYBr5d+bzICL+ktlkdy/tb/1fBu00Q=" + }, + { + "pname": "Microsoft.IdentityModel.Abstractions", + "version": "8.2.0", + "hash": "sha256-e+BmN/Et9mTqWt4M38udL47M4wHHs25Ob299gJSBZIM=" + }, + { + "pname": "Microsoft.IdentityModel.JsonWebTokens", + "version": "8.2.0", + "hash": "sha256-tOzI2GmMISuWO/vDtJIeKmYAaFPYjrB5NhpzCWWcIw4=" + }, + { + "pname": "Microsoft.IdentityModel.Logging", + "version": "8.2.0", + "hash": "sha256-JdrIo2Dg9UPu/eK5TIPKLWfRmvPGhKZrBCQL+MIv72I=" + }, + { + "pname": "Microsoft.IdentityModel.Protocols", + "version": "8.2.0", + "hash": "sha256-Tud941SQnR7fJzCC5WllIN8X1sqBTf7RDxU6PXVwN2A=" + }, + { + "pname": "Microsoft.IdentityModel.Protocols.OpenIdConnect", + "version": "8.2.0", + "hash": "sha256-VcS01u6w+fWfdAMF43W2SlV0yX28xAbNOBXwtB0cIS8=" + }, + { + "pname": "Microsoft.IdentityModel.Tokens", + "version": "8.2.0", + "hash": "sha256-QxhnZVUrKKUZEKZgok2+4HjawuXZtVhXCJ2+BDomja8=" + }, + { + "pname": "Microsoft.IdentityModel.Validators", + "version": "8.2.0", + "hash": "sha256-QagwQJWdRN3T2bnRpvyJMUBdWOADkG7k1w9p0VhWKto=" + }, + { + "pname": "Microsoft.Kiota.Abstractions", + "version": "1.14.0", + "hash": "sha256-/3XjWnJ0l9Rlt3x5M3035DnvqHKojV86N1drobJ4vVI=" + }, + { + "pname": "Microsoft.Kiota.Abstractions", + "version": "1.15.2", + "hash": "sha256-DGM9G/VW+xK+ataekRjsuuOT0IFdv7z21SqkUBqRyPc=" + }, + { + "pname": "Microsoft.Kiota.Authentication.Azure", + "version": "1.15.2", + "hash": "sha256-3WEpq2WeOGKQBGtvdrGIuidFESz9hgJSTu6sbabIm/k=" + }, + { + "pname": "Microsoft.Kiota.Http.HttpClientLibrary", + "version": "1.15.2", + "hash": "sha256-8xNwGEq/zX27Om4CpP2fTR8ls6yY8C+ZX88r75tw3Eg=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Form", + "version": "1.14.0", + "hash": "sha256-Uv5TQj01xUxr8ZPmcpunfo0w6o6Ds5Vv1aZyBP6/Uzs=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Json", + "version": "1.15.2", + "hash": "sha256-2eSjIdPbq3bL5HPFfwnlXaquEChgwu0UixmkAmpAdCM=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Multipart", + "version": "1.14.0", + "hash": "sha256-PopI4m/DSee6AQ4gyNQtasKWuuyC9dluXB1T8Gp5wZs=" + }, + { + "pname": "Microsoft.Kiota.Serialization.Text", + "version": "1.14.0", + "hash": "sha256-usNV4TAFlvYTRVC4pzD11XyeXkO5CWzagj9BcBxAUHs=" + }, + { + "pname": "ModelContextProtocol", + "version": "0.4.1-preview.1", + "hash": "sha256-9PbHfpjDoNuzcAqazDfXHgoefJd8Aa8AFzUmjoxD/58=" + }, + { + "pname": "ModelContextProtocol.Core", + "version": "0.4.1-preview.1", + "hash": "sha256-NyHcXRhdLzf0GdaY1SKRcDLaE7B4ZdIO9kIqKfTLAFk=" + }, + { + "pname": "Newtonsoft.Json", + "version": "13.0.3", + "hash": "sha256-hy/BieY4qxBWVVsDqqOPaLy1QobiIapkbrESm6v2PHc=" + }, + { + "pname": "OpenTelemetry", + "version": "1.10.0", + "hash": "sha256-ucUy3vIabYb0TGDhraqMEzT+LLPmXrO1NgAjEeyVCO8=" + }, + { + "pname": "OpenTelemetry.Api", + "version": "1.10.0", + "hash": "sha256-ZSpQFnNgkk3dO8Q7yokJ/VSl4wp5PuIv9nduxgC6UxU=" + }, + { + "pname": "OpenTelemetry.Api.ProviderBuilderExtensions", + "version": "1.10.0", + "hash": "sha256-hLw3Sf1fviAlVJYhaMudVJEdG5pjX5JvVrqv9DgYAk8=" + }, + { + "pname": "OpenTelemetry.Exporter.OpenTelemetryProtocol", + "version": "1.10.0", + "hash": "sha256-1sKqD/DsEo1nfD4BuuIde/In7W0wAbIEWD3jvvbO8JA=" + }, + { + "pname": "OpenTelemetry.Extensions.Hosting", + "version": "1.10.0", + "hash": "sha256-+O9oaAUYaKUItLAaT7yQUs2nrHVDNkj8YcFuUxiTy6M=" + }, + { + "pname": "OpenTelemetry.Instrumentation.Runtime", + "version": "1.10.0", + "hash": "sha256-cCTYKxHh1Qzu8X51B8gGsrxwKhVSqJfiql/+o4TWrwg=" + }, + { + "pname": "Serilog", + "version": "3.1.1", + "hash": "sha256-L263y8jkn7dNFD2jAUK6mgvyRTqFe39i1tRhVZsNZTI=" + }, + { + "pname": "Serilog", + "version": "4.0.0", + "hash": "sha256-j8hQ5TdL1TjfdGiBO9PyHJFMMPvATHWN1dtrrUZZlNw=" + }, + { + "pname": "Serilog.Extensions.Hosting", + "version": "8.0.0", + "hash": "sha256-OEVkEQoONawJF+SXeyqqgU0OGp9ubtt9aXT+rC25j4E=" + }, + { + "pname": "Serilog.Extensions.Logging", + "version": "8.0.0", + "hash": "sha256-GoWxCpkdahMvYd7ZrhwBxxTyjHGcs9ENNHJCp0la6iA=" + }, + { + "pname": "Serilog.Sinks.File", + "version": "6.0.0", + "hash": "sha256-KQmlUpG9ovRpNqKhKe6rz3XMLUjkBqjyQhEm2hV5Sow=" + }, + { + "pname": "Std.UriTemplate", + "version": "2.0.1", + "hash": "sha256-SBp+7foUJVRYfNz6xa96oC2DYDXZVjTONbNJr29AuXc=" + }, + { + "pname": "System.ClientModel", + "version": "1.1.0", + "hash": "sha256-FiueWJawZGar++OztDFWxU2nQE5Vih9iYsc3uEx0thM=" + }, + { + "pname": "System.CodeDom", + "version": "7.0.0", + "hash": "sha256-7IPt39cY+0j0ZcRr/J45xPtEjnSXdUJ/5ai3ebaYQiE=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "10.0.0", + "hash": "sha256-t7NakmBNSZbMIU802EpfPwNUHwS7Sd9GlebOHvYty+M=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "6.0.1", + "hash": "sha256-Xi8wrUjVlioz//TPQjFHqcV/QGhTqnTfUcltsNlcCJ4=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "9.0.0", + "hash": "sha256-1VzO9i8Uq2KlTw1wnCCrEdABPZuB2JBD5gBsMTFTSvE=" + }, + { + "pname": "System.Diagnostics.EventLog", + "version": "9.0.0", + "hash": "sha256-tPvt6yoAp56sK/fe+/ei8M65eavY2UUhRnbrREj/Ems=" + }, + { + "pname": "System.IdentityModel.Tokens.Jwt", + "version": "8.2.0", + "hash": "sha256-Htz1I19N0/IWHF8tbyZC90wCqI5xLh42jMXI3GXkCP4=" + }, + { + "pname": "System.IO.Pipelines", + "version": "10.0.0", + "hash": "sha256-0aeIxLFEBn9BoCa93UVNikdlqgPl3B1nmYCLQ9Yu9Ak=" + }, + { + "pname": "System.Management", + "version": "7.0.2", + "hash": "sha256-bJ21ILQfbHb8mX2wnVh7WP/Ip7gdVPIw+BamQuifTVY=" + }, + { + "pname": "System.Memory", + "version": "4.5.3", + "hash": "sha256-Cvl7RbRbRu9qKzeRBWjavUkseT2jhZBUWV1SPipUWFk=" + }, + { + "pname": "System.Memory.Data", + "version": "1.0.2", + "hash": "sha256-XiVrVQZQIz4NgjiK/wtH8iZhhOZ9MJ+X2hL2/8BrGN0=" + }, + { + "pname": "System.Memory.Data", + "version": "6.0.0", + "hash": "sha256-83/bxn3vyv17dQDDqH1L3yDpluhOxIS5XR27f4OnCEo=" + }, + { + "pname": "System.Net.ServerSentEvents", + "version": "10.0.0", + "hash": "sha256-Ez92vnxlAEH1q0tl7VwOihlU49eCD1eAbYEU4Dyeds8=" + }, + { + "pname": "System.Numerics.Vectors", + "version": "4.5.0", + "hash": "sha256-qdSTIFgf2htPS+YhLGjAGiLN8igCYJnCCo6r78+Q+c8=" + }, + { + "pname": "System.Security.Cryptography.ProtectedData", + "version": "4.5.0", + "hash": "sha256-Z+X1Z2lErLL7Ynt2jFszku6/IgrngO3V1bSfZTBiFIc=" + }, + { + "pname": "System.Text.Encodings.Web", + "version": "10.0.0", + "hash": "sha256-OrsgqAPfEjjo+CzzrAzkKTXNv3VXw2dm3Wpn+uRHCM8=" + }, + { + "pname": "System.Text.Encodings.Web", + "version": "6.0.0", + "hash": "sha256-UemDHGFoQIG7ObQwRluhVf6AgtQikfHEoPLC6gbFyRo=" + }, + { + "pname": "System.Text.Json", + "version": "10.0.0", + "hash": "sha256-ZyAMIT3yQDJazYAObAlXmScGshGD9MVZgYmLqHyICq0=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.0", + "hash": "sha256-9AE/5ds4DqEfb0l+27fCBTSeYCdRWhxh2Bhg8IKvIuo=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.10", + "hash": "sha256-UijYh0dxFjFinMPSTJob96oaRkNm+Wsa+7Ffg6mRnsc=" + }, + { + "pname": "System.Text.Json", + "version": "6.0.9", + "hash": "sha256-5jjvxV8ubGYjkydDhLsGZXB6ml3O/7CGauQcu1ikeLs=" + }, + { + "pname": "System.Threading.Tasks.Extensions", + "version": "4.5.4", + "hash": "sha256-owSpY8wHlsUXn5xrfYAiu847L6fAKethlvYx97Ri1ng=" + } +] diff --git a/docs/nix-packaging.md b/docs/nix-packaging.md new file mode 100644 index 0000000..fb97b7a --- /dev/null +++ b/docs/nix-packaging.md @@ -0,0 +1,190 @@ +# Nix Packaging Guide + +This guide covers building and packaging Calendar MCP using Nix flakes, including dependency management and common issues. + +## Table of Contents + +- [Prerequisites](#prerequisites) +- [Quick Start](#quick-start) +- [Building Packages](#building-packages) +- [Updating Dependencies](#updating-dependencies) +- [NixOS Module](#nixos-module) +- [Common Issues](#common-issues) +- [References](#references) + +## Prerequisites + +- Nix with flakes enabled +- Git (the repository must be a git repo with files tracked) + +No .NET SDK required - Nix handles all build dependencies. + +## Quick Start + +**Step 1: Build the packages** + +```bash +# Build the MCP server (default package) +nix build .#default + +# Build the CLI tool +nix build .#cli +``` + +**Step 2: Run** + +```bash +# Test the server responds to MCP initialize +echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{}},"id":1}' | \ + timeout 5 result/bin/CalendarMcp.StdioServer + +# Run the CLI +result/bin/CalendarMcp.Cli --help +``` + +## Building Packages + +The flake provides two packages to avoid assembly version conflicts: + +| Package | Description | Output | +|---------|-------------|--------| +| `default` | MCP stdio server | `CalendarMcp.StdioServer` | +| `cli` | Account management CLI | `CalendarMcp.Cli` | + +```bash +# Build server only +nix build .#default + +# Build CLI only +nix build .#cli + +# Build both +nix build .#default .#cli +``` + +### Why Separate Packages? + +The server and CLI depend on different versions of `Microsoft.Extensions.Logging` (v9 vs v10). Combining them in a single `buildDotnetModule` causes runtime assembly loading errors. Separate packages with separate dependency lockfiles resolve this. + +## Updating Dependencies + +When NuGet packages change upstream, regenerate the dependency lockfiles. + +### Using the Script (Recommended) + +```bash +./update-nix-deps.sh +git add deps-server.json deps-cli.json +nix build .#default .#cli +``` + +### Manual Process + +The `buildDotnetModule` builder creates a `fetch-deps` script: + +```bash +# Generate server deps +$(nix build .#default.fetch-deps --no-link --print-out-paths) deps-server.json + +# Generate CLI deps +$(nix build .#cli.fetch-deps --no-link --print-out-paths) deps-cli.json + +# Stage and rebuild +git add deps-server.json deps-cli.json +nix build .#default .#cli +``` + +**Important:** The fetch-deps script writes to the nix store by default. You MUST pass the output filename as an argument. + +### Initial Setup for New Projects + +If starting fresh or after major changes: + +```bash +# Create empty deps files so nix can evaluate the flake +echo '[]' > deps-server.json +echo '[]' > deps-cli.json +git add deps-server.json deps-cli.json flake.nix + +# Now generate real deps +./update-nix-deps.sh +git add deps-server.json deps-cli.json +``` + +## NixOS Module + +The flake includes a NixOS module for running the server as a systemd service: + +```nix +{ + inputs.calendar-mcp.url = "github:your-fork/calendar-mcp"; + + outputs = { self, nixpkgs, calendar-mcp }: { + nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { + modules = [ + calendar-mcp.nixosModules.default + { + services.calendar-mcp = { + enable = true; + dataDir = "/var/lib/calendar-mcp"; + }; + } + ]; + }; + }; +} +``` + +### Module Options + +| Option | Default | Description | +|--------|---------|-------------| +| `enable` | `false` | Enable the service | +| `package` | `calendar-mcp.packages.${system}.default` | Package to use | +| `dataDir` | `/var/lib/calendar-mcp` | Data directory | +| `user` | `calendar-mcp` | Service user | +| `group` | `calendar-mcp` | Service group | + +## Common Issues + +### "nuget-to-nix has been removed" + +Use the `fetch-deps` approach instead. See [Updating Dependencies](#updating-dependencies). + +### "Option '--configuration' expects a single argument but 2 were provided" + +Don't pass build flags like `[ "-c" "Release" ]` in `dotnetBuildFlags`. The default configuration is already Release. + +### Assembly version mismatches at runtime + +``` +Could not load file or assembly 'Microsoft.Extensions.Logging, Version=10.0.0.0' +``` + +This happens when projects require different versions of the same package. Solution: split into separate packages with separate `nugetDeps` files (already done in this flake). + +### fetch-deps writes to read-only path + +Always pass the output filename as an argument: + +```bash +# Wrong - tries to write to /nix/store +/nix/store/xxx-fetch-deps + +# Correct +/nix/store/xxx-fetch-deps deps.json +``` + +### "path does not exist" or "file not tracked by git" + +Nix flakes only see files tracked by git: + +```bash +git add deps-server.json deps-cli.json flake.nix +``` + +## References + +- [NixOS Wiki - DotNET](https://wiki.nixos.org/wiki/DotNET) +- [nixpkgs .NET documentation](https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/dotnet.section.md) +- [buildDotnetModule source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/dotnet/build-dotnet-module/default.nix) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5a9df81 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1768564909, + "narHash": "sha256-Kell/SpJYVkHWMvnhqJz/8DqQg2b6PguxVWOuadbHCc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e4bae1bd10c9c57b2cf517953ab70060a828ee6f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..128446a --- /dev/null +++ b/flake.nix @@ -0,0 +1,158 @@ +{ + description = "Calendar MCP - Unified email and calendar access for AI assistants"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + + dotnetSdk = pkgs.dotnet-sdk_9; + dotnetRuntime = pkgs.dotnet-runtime_9; + + projectName = "CalendarMcp"; + version = "0.1.0"; + + in { + packages = { + # MCP Server - the main package + default = pkgs.buildDotnetModule { + pname = "calendar-mcp-server"; + inherit version; + + src = ./src; + + projectFile = "CalendarMcp.StdioServer/CalendarMcp.StdioServer.csproj"; + executables = [ "CalendarMcp.StdioServer" ]; + + dotnet-sdk = dotnetSdk; + dotnet-runtime = dotnetRuntime; + + nugetDeps = ./deps-server.json; + runtimeDeps = [ pkgs.icu ]; + + meta = with pkgs.lib; { + description = "MCP server for unified email and calendar access"; + homepage = "https://github.com/Veraticus/calendar-mcp"; + license = licenses.mit; + platforms = platforms.all; + }; + }; + + # CLI for account management - separate to avoid version conflicts + cli = pkgs.buildDotnetModule { + pname = "calendar-mcp-cli"; + inherit version; + + src = ./src; + + projectFile = "CalendarMcp.Cli/CalendarMcp.Cli.csproj"; + executables = [ "CalendarMcp.Cli" ]; + + dotnet-sdk = dotnetSdk; + dotnet-runtime = dotnetRuntime; + + nugetDeps = ./deps-cli.json; + runtimeDeps = [ pkgs.icu ]; + + meta = with pkgs.lib; { + description = "CLI for managing Calendar MCP accounts"; + homepage = "https://github.com/Veraticus/calendar-mcp"; + license = licenses.mit; + platforms = platforms.all; + }; + }; + }; + + devShells.default = pkgs.mkShell { + buildInputs = [ + dotnetSdk + pkgs.nuget-to-json + ]; + + shellHook = '' + echo "Calendar MCP development shell" + echo " dotnet version: $(dotnet --version)" + echo "" + echo "To regenerate deps.json:" + echo " cd src && dotnet restore && nuget-to-json . > ../deps.json" + ''; + }; + } + ) // { + nixosModules.default = { config, lib, pkgs, ... }: + let + cfg = config.services.calendar-mcp; + in { + options.services.calendar-mcp = { + enable = lib.mkEnableOption "Calendar MCP server"; + + package = lib.mkOption { + type = lib.types.package; + default = self.packages.${pkgs.system}.default; + description = "The calendar-mcp package to use"; + }; + + dataDir = lib.mkOption { + type = lib.types.path; + default = "/var/lib/calendar-mcp"; + description = "Directory for calendar-mcp data"; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "calendar-mcp"; + description = "User to run calendar-mcp as"; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "calendar-mcp"; + description = "Group to run calendar-mcp as"; + }; + }; + + config = lib.mkIf cfg.enable { + users.users.${cfg.user} = { + isSystemUser = true; + group = cfg.group; + home = cfg.dataDir; + createHome = true; + }; + + users.groups.${cfg.group} = {}; + + systemd.services.calendar-mcp = { + description = "Calendar MCP Server"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + Type = "simple"; + User = cfg.user; + Group = cfg.group; + ExecStart = "${cfg.package}/bin/CalendarMcp.StdioServer"; + Restart = "on-failure"; + RestartSec = 5; + + # Hardening + NoNewPrivileges = true; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + ReadWritePaths = [ cfg.dataDir ]; + }; + + environment = { + HOME = cfg.dataDir; + XDG_DATA_HOME = "${cfg.dataDir}/.local/share"; + }; + }; + }; + }; + }; +} diff --git a/update-nix-deps.sh b/update-nix-deps.sh new file mode 100755 index 0000000..d272a55 --- /dev/null +++ b/update-nix-deps.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Update Nix dependency lockfiles for .NET packages +# Run this after NuGet dependencies change upstream + +set -euo pipefail + +cd "$(dirname "$0")" + +echo "Updating server deps..." +server_script=$(nix build .#default.fetch-deps --no-link --print-out-paths) +"$server_script" deps-server.json + +echo "Updating CLI deps..." +cli_script=$(nix build .#cli.fetch-deps --no-link --print-out-paths) +"$cli_script" deps-cli.json + +echo "" +echo "Done. Remember to stage the updated files:" +echo " git add deps-server.json deps-cli.json"