FnKit.Functions.Framework 0.1.0

dotnet add package FnKit.Functions.Framework --version 0.1.0
                    
NuGet\Install-Package FnKit.Functions.Framework -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FnKit.Functions.Framework" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FnKit.Functions.Framework" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="FnKit.Functions.Framework" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FnKit.Functions.Framework --version 0.1.0
                    
#r "nuget: FnKit.Functions.Framework, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FnKit.Functions.Framework@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FnKit.Functions.Framework&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=FnKit.Functions.Framework&version=0.1.0
                    
Install as a Cake Tool

fnkit — MQTT Functions Framework for .NET

An open source FaaS (Function as a Service) framework for writing portable .NET functions invoked via MQTT messages instead of HTTP requests.

Adapted from the Google Cloud Functions Framework for .NET.

How It Works

Instead of standing up an HTTP server, fnkit connects to an MQTT broker and subscribes to a topic based on your function name. When a message arrives, your function is invoked with (request, response) arguments.

MQTT Message → Broker → fnkit subscribes → Your Function(req, res) → Optional MQTT Response

Prerequisites

The fnkit Functions Framework for .NET requires .NET 8.0 or later.

Quick Start

1. Create a .NET project

mkdir MyFunction && cd MyFunction
dotnet new console
dotnet add package FnKit.Functions.Framework
dotnet add package FnKit.Functions.Hosting

2. Create your function

// HelloFunction.cs
using FnKit.Functions.Framework;

public class HelloFunction : IMqttFunction
{
    public Task HandleAsync(MqttRequest request, MqttResponse response, CancellationToken cancellationToken)
    {
        string name = "World";
        if (request.Body.HasValue &&
            request.Body.Value.TryGetProperty("name", out var nameProp))
        {
            name = nameProp.GetString() ?? "World";
        }

        response.Send(new { message = $"Hello, {name}!" });
        return Task.CompletedTask;
    }
}

3. Create the entry point

// Program.cs
using FnKit.Functions.Hosting;

return await EntryPoint.StartAsync(typeof(HelloFunction).Assembly, args);

4. Run it

FUNCTION_TARGET=HelloFunction dotnet run
# Output: [fnkit] Listening on topic: fnkit/HelloFunction

5. Test it

# In another terminal, publish a message
mosquitto_pub -h localhost -t fnkit/HelloFunction -m '{"name": "Max"}'

Function Signature

fnkit uses an interface-based pattern consistent with the .NET Functions Framework:

public class MyFunction : IMqttFunction
{
    public Task HandleAsync(MqttRequest request, MqttResponse response, CancellationToken cancellationToken)
    {
        // request — MQTT request object
        // response — MQTT response object
        // cancellationToken — cancellation token
        return Task.CompletedTask;
    }
}

Request Object (MqttRequest)

Property Type Description
Topic string The full MQTT topic the message was received on
Payload byte[] The raw message payload
Body JsonElement? Parsed payload (JSON if possible, otherwise null)
BodyText string The raw payload as a string
Params Dictionary<string, string> Topic segments beyond the function name (wildcard subscriptions)
Properties Dictionary<string, string> MQTT v5 user properties (analogous to HTTP headers)
Headers Dictionary<string, string> Alias for Properties
CorrelationData byte[]? MQTT v5 correlation data
ResponseTopic string? MQTT v5 response topic
ContentType string? MQTT v5 content type
MessageId ushort MQTT packet identifier
QoS byte QoS level of the received message
Retain bool Whether the message was retained
ExecutionId string Unique execution ID for this invocation

Use request.GetBody<T>() for typed deserialization of the JSON body.

Response Object (MqttResponse)

Method Description
Send(data) Publish response. Accepts string, byte[], or any object (auto JSON-serialized)
Json(obj) Publish JSON response (sets content type)
Status(code) Set a status code in response user properties (chainable)
Set(key, value) Set an MQTT v5 user property on the response (chainable)
End() Signal completion without sending a response

Fire-and-Forget

Functions don't have to send a response. Just process the message and return:

public class LoggerFunction : IMqttFunction
{
    public Task HandleAsync(MqttRequest request, MqttResponse response, CancellationToken cancellationToken)
    {
        Console.WriteLine($"Event received: {request.BodyText}");
        // No response.Send() needed — fire and forget
        return Task.CompletedTask;
    }
}

Response Topics

Responses are published to (in order of precedence):

  1. MQTT v5 Response Topic — If the incoming message has a ResponseTopic property
  2. Defaultfnkit/{functionName}/response

Correlation data from the incoming message is automatically forwarded.

Configuration

Configure via CLI flags or environment variables. CLI flags take precedence.

CLI Flag Environment Variable Description Default
--broker MQTT_BROKER MQTT broker URL (mqtt:// or mqtts://) mqtt://localhost:1883
--target FUNCTION_TARGET Name of the function to invoke auto-detected
--topic-prefix MQTT_TOPIC_PREFIX Topic prefix before function name fnkit
--qos MQTT_QOS Default QoS level (0, 1, 2) 1
--client-id MQTT_CLIENT_ID MQTT client identifier auto-generated
--username MQTT_USERNAME Broker username
--password MQTT_PASSWORD Broker password
--ca MQTT_CA Path to CA certificate (TLS)
--cert MQTT_CERT Path to client certificate (mTLS)
--key MQTT_KEY Path to client private key (mTLS)
--reject-unauthorized MQTT_REJECT_UNAUTHORIZED Reject unauthorized TLS certs true

If FUNCTION_TARGET is not specified and the assembly contains exactly one IMqttFunction implementation, it is used automatically (same pattern as the Google Cloud Functions Framework).

Security

TLS (Port 8883)

FUNCTION_TARGET=HelloFunction dotnet run -- --broker=mqtts://broker:8883 --ca=/path/to/ca.crt

mTLS (Mutual TLS)

FUNCTION_TARGET=HelloFunction dotnet run -- \
  --broker=mqtts://broker:8883 \
  --ca=/path/to/ca.crt \
  --cert=/path/to/client.crt \
  --key=/path/to/client.key

Username/Password

FUNCTION_TARGET=HelloFunction dotnet run -- --broker=mqtt://broker:1883 --username=user --password=pass

MQTT v5 Features

fnkit uses MQTT v5 by default, enabling:

  • Response Topics — Request-reply pattern via ResponseTopic property
  • Correlation Data — Match responses to requests
  • User Properties — Key-value metadata on messages (like HTTP headers)
  • Content Type — Indicate payload format

Comparison with HTTP Functions Framework

Aspect HTTP Framework (.NET) fnkit (.NET)
Transport HTTP server (Kestrel) MQTT client (subscribes to broker)
Routing URL path → function Topic fnkit/{name} → function
Request HttpContext (URL, headers, body) MqttRequest (topic, properties, payload)
Response HttpContext.Response MqttResponse (publish to reply topic)
Invocation Per HTTP request Per MQTT message
Interface IHttpFunction IMqttFunction
Config PORT, FUNCTION_TARGET MQTT_BROKER, FUNCTION_TARGET

Architecture

See the design docs for:

  • Architecture — System overview and components
  • Contract — The MQTT Functions Framework contract (language-agnostic)
  • Decisions — Design decisions and rationale

Based On

This framework is adapted from the Google Cloud Functions Framework for .NET (Apache-2.0 License). The function resolution, assembly scanning, and framework patterns are reused. The HTTP transport layer has been replaced with MQTT using MQTTnet.

License

Apache-2.0 — See LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on FnKit.Functions.Framework:

Package Downloads
FnKit.Functions.Hosting

fnkit Functions Framework for .NET — MQTT hosting, connection management, and function invocation.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 141 2/15/2026