CloudflaredKit 0.1.1
dotnet add package CloudflaredKit --version 0.1.1
NuGet\Install-Package CloudflaredKit -Version 0.1.1
<PackageReference Include="CloudflaredKit" Version="0.1.1" />
<PackageVersion Include="CloudflaredKit" Version="0.1.1" />
<PackageReference Include="CloudflaredKit" />
paket add CloudflaredKit --version 0.1.1
#r "nuget: CloudflaredKit, 0.1.1"
#:package CloudflaredKit@0.1.1
#addin nuget:?package=CloudflaredKit&version=0.1.1
#tool nuget:?package=CloudflaredKit&version=0.1.1
CloudflaredKit
A .NET library that manages the cloudflared binary and Cloudflare Tunnel lifecycle programmatically.
Inspired by FluffySpoon.Ngrok.
Features
- TryCloudflare mode — No account or pre-configuration needed. Issues a random
https://xxxxx.trycloudflare.comURL at startup. - Permanent tunnel mode — Specify a Cloudflare Zero Trust tunnel token to run with a fixed URL.
- Automatic binary management — Downloads and caches the
cloudflaredbinary from GitHub Releases. - DI support — Works with
Microsoft.Extensions.DependencyInjection(console apps, generic host, etc.). - Lifetime hooks —
ICloudflaredLifetimeHookcallbacks fired on tunnel creation and destruction.
Supported Platforms
| OS | Architecture |
|---|---|
| Linux | x64 |
| Linux | x86 (32-bit) |
| Linux | arm64 |
| Linux | arm (32-bit, armhf / armel) |
| macOS | x64 |
| macOS | arm64 (Apple Silicon) |
| Windows | x64 |
| Windows | x86 (32-bit) |
Installation
dotnet add package CloudflaredKit
Usage
Console application (TryCloudflare mode)
No account or pre-configuration required. Just specify the local port and a temporary public URL is issued automatically.
using CloudflaredKit;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddTryCloudflare(options =>
{
options.LocalPort = 5000;
});
var provider = services.BuildServiceProvider();
var service = provider.GetRequiredService<ICloudflaredService>();
// Downloads cloudflared on first run, then starts the tunnel.
var tunnel = await service.StartAsync();
Console.WriteLine($"Public URL: {tunnel.PublicUrl}");
// => Public URL: https://abc-def-123.trycloudflare.com
// ... application logic ...
await service.StopAsync();
Permanent tunnel mode (tunnel token)
Create a tunnel in the Cloudflare Zero Trust dashboard and pass the generated token.
services.AddTryCloudflare(options =>
{
options.TunnelToken = "your-cloudflare-tunnel-token";
});
In permanent tunnel mode, the public URL is managed in the Cloudflare dashboard,
so TunnelInfo.PublicUrl is null.
Configuration via appsettings.json
{
"Cloudflare": {
"LocalPort": 5000
}
}
builder.Services.AddTryCloudflare(builder.Configuration.GetSection("Cloudflare"));
Lifetime hooks
Implement ICloudflaredLifetimeHook to run custom logic whenever a tunnel is created or destroyed.
This is useful when something outside the tunnel startup flow needs to react to the public URL —
for example, registering it with a remote service.
public class MyHook : ICloudflaredLifetimeHook
{
public async Task OnCreatedAsync(TunnelInfo tunnel, CancellationToken cancellationToken)
{
// Called after the tunnel is up. tunnel.PublicUrl contains the public URL.
await RegisterSomewhereAsync(tunnel.PublicUrl, cancellationToken);
}
public async Task OnDestroyedAsync(TunnelInfo tunnel, CancellationToken cancellationToken)
{
// Called after the tunnel is stopped.
await UnregisterSomewhereAsync(tunnel.PublicUrl, cancellationToken);
}
}
services.AddTryCloudflare(options => options.LocalPort = 5000);
services.AddCloudflaredLifetimeHook<MyHook>();
Hooks are optional. If you only need the URL at the call site, use the return value of StartAsync instead.
Waiting for the tunnel to be ready
StartAsync already blocks until the tunnel is up and returns TunnelInfo directly,
so in most cases you do not need WaitUntilReadyAsync.
// Normal usage — URL is available immediately after await.
var tunnel = await service.StartAsync();
Console.WriteLine(tunnel.PublicUrl);
WaitUntilReadyAsync is only needed when StartAsync is called without being awaited
(fire-and-forget), and a separate part of the code needs to wait for readiness.
// Fire-and-forget start (unusual).
_ = service.StartAsync();
// Somewhere else, wait until the tunnel is ready.
await service.WaitUntilReadyAsync();
Console.WriteLine(service.ActiveTunnel?.PublicUrl);
Using a pre-installed cloudflared binary
Skip the automatic download and point to an existing binary.
services.AddTryCloudflare(options =>
{
options.LocalPort = 5000;
options.CloudflaredPath = "/usr/local/bin/cloudflared";
});
Selecting the local host name
By default, TryCloudflare forwards to http://localhost:{LocalPort}.
If your local server is bound to IPv4 loopback only, or localhost resolves to an address your server is not listening on, specify 127.0.0.1 explicitly.
services.AddTryCloudflare(options =>
{
options.LocalPort = 5000;
options.LocalHostName = "127.0.0.1";
});
Options
| Property | Type | Default | Description |
|---|---|---|---|
LocalPort |
int |
80 |
Local port to expose (TryCloudflare mode only) |
LocalHostName |
string |
localhost |
Local host name or IP address to expose (TryCloudflare mode only) |
TunnelToken |
string? |
null |
Cloudflare tunnel token. When null, TryCloudflare mode is used |
CloudflaredPath |
string? |
null |
Path to an existing cloudflared binary. When null, auto-downloaded |
CacheDirectory |
string? |
null |
Directory used to cache the downloaded cloudflared binary. When null, the platform default cache location below is used |
Binary Cache Location
| OS | Path |
|---|---|
| Windows | %LOCALAPPDATA%\TryCloudflare\cloudflared.exe |
| Linux | ~/.local/share/TryCloudflare/cloudflared |
| macOS | ~/Library/Caches/TryCloudflare/cloudflared |
Running E2E Tests Locally
TryCloudflare E2E tests can be run locally without a Cloudflare account. They download cloudflared, open a temporary public tunnel, and verify that traffic reaches a local test server.
$env:CLOUDFLARED_E2E = "1"
dotnet test .\src\CloudflaredKit.Tests\CloudflaredKit.Tests.csproj -c Release --filter "FullyQualifiedName~CloudflaredE2ETests"
Permanent tunnel E2E tests are skipped unless CLOUDFLARED_PERMANENT_E2E=1 and CLOUDFLARE_TUNNEL_TOKEN are also set.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Http (>= 10.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.