diff --git a/src/GeneralUpdate.Tools.csproj b/src/GeneralUpdate.Tools.csproj
index 37a6f8d..b284fb4 100644
--- a/src/GeneralUpdate.Tools.csproj
+++ b/src/GeneralUpdate.Tools.csproj
@@ -31,4 +31,8 @@
+
+
+
+
diff --git a/src/Services/LocalUpdateServer.cs b/src/Services/LocalUpdateServer.cs
new file mode 100644
index 0000000..8f0d598
--- /dev/null
+++ b/src/Services/LocalUpdateServer.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace GeneralUpdate.Tools.Services;
+
+public class LocalUpdateServer : IAsyncDisposable
+{
+ private WebApplication? _app;
+ private int _port;
+ private Task? _runTask;
+
+ public int Port => _port;
+ public string BaseUrl => $"http://127.0.0.1:{_port}";
+
+ public List<(string CurrentVersion, string TargetVersion, string Hash, string ZipPath, int AppType)> Updates { get; } = new();
+
+ public async Task StartAsync(int port = 5000)
+ {
+ var builder = WebApplication.CreateBuilder();
+ builder.WebHost.UseUrls($"http://127.0.0.1:{port}");
+
+ _app = builder.Build();
+
+ // GET /Upgrade/Verification
+ _app.MapGet("/Upgrade/Verification", async (HttpContext context) =>
+ {
+ var q = context.Request.Query;
+ var currentVer = q["currentVersion"].ToString();
+ _ = int.TryParse(q["appType"].ToString(), out var appType);
+
+ var match = Updates.Find(u => u.CurrentVersion == currentVer);
+ if (match == default)
+ {
+ await context.Response.WriteAsJsonAsync(new { code = 204, body = Array.Empty