1. Conduid
  2. Science
  3. Tharga.Communication.Mcp
MCP server · Science

Tharga.Communication.Mcp

Exposes Tharga.Communication runtime data (connected clients, active subscriptions, registered handlers) via MCP (Model Context Protocol). Plugs into Tharga.Mcp.

Unclaimed science
34Low

Scored 5 months ago · breakdown

About Tharga.Communication.Mcp

Tharga.Communication.Mcp is an MCP server in the Science category: exposes Tharga.Communication runtime data (connected clients, active subscriptions, registered handlers) via MCP (Model Context Protocol). Plugs into Tharga.Mcp.

Install

From source
git clone https://github.com/Tharga/Communication

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Tharga.Communication.Mcp

Powered by Claude · Grounded in docs

I know everything about Tharga.Communication.Mcp. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

  • ✓README presentThe repository ships documentation.

5 checks have not been run yet.

README

Tharga Communication

GitHub repo Issues NuGet Nuget License

A SignalR-based communication framework for .NET with built-in message handler patterns for request-response and fire-and-forget messaging between clients and servers.

Features

  • Fire-and-forget messaging - Send one-way messages from client to server or server to client(s)
  • Request-response messaging - Send a request and await a typed response with configurable timeout
  • Automatic handler discovery - Message handlers are discovered and registered via dependency injection
  • Client connection tracking - Track connected clients with metadata (machine name, app type, version)
  • Automatic reconnection - Configurable reconnect delays for client connections
  • Extensible storage - Abstract repository pattern for client state with an in-memory default

Installation

dotnet add package Tharga.Communication

Quick start

Server setup

var builder = WebApplication.CreateBuilder(args);

builder.AddThargaCommunicationServer(options =>
{
    options.RegisterClientStateService<MyClientStateService>();
    options.RegisterClientRepository<MemoryClientRepository<ClientConnectionInfo>, ClientConnectionInfo>();
});

var app = builder.Build();
app.UseThargaCommunicationServer();
app.Run();

Client setup

Add the configuration section to appsettings.json:

{
  "Tharga": {
    "Communication": {
      "ServerAddress": "https://localhost:5001"
    }
  }
}

Register the client services:

var builder = Host.CreateApplicationBuilder(args);
builder.AddThargaCommunicationClient();

Creating a message handler (fire-and-forget)

public record MyNotification(string Text);

public class MyNotificationHandler : PostMessageHandlerBase<MyNotification>
{
    public override Task Handle(MyNotification message)
    {
        Console.WriteLine(message.Text);
        return Task.CompletedTask;
    }
}

Register the handler in DI:

builder.Services.AddTransient<PostMessageHandlerBase<MyNotification>, MyNotificationHandler>();

Creating a message handler (request-response)

public record PingRequest(string Message);
public record PingResponse(string Reply);

public class PingHandler : SendMessageHandlerBase<PingRequest, PingResponse>
{
    public override Task<PingResponse> Handle(PingRequest message)
    {
        return Task.FromResult(new PingResponse($"Pong: {message.Message}"));
    }
}

Sending messages

From the client:

public class MyService(IClientCommunication client)
{
    public async Task NotifyServer()
    {
        await client.PostAsync(new MyNotification("Hello from client"));
    }

    public async Task<PingResponse> PingServer()
    {
        return await client.SendMessage<PingRequest, PingResponse>(new PingRequest("Ping"));
    }
}

From the server:

public class MyServerService(IServerCommunication server)
{
    public async Task NotifyClient(string connectionId)
    {
        await server.PostAsync(connectionId, new MyNotification("Hello from server"));
    }

    public async Task NotifyAll()
    {
        await server.PostToAllAsync(new MyNotification("Broadcast message"));
    }

    public async Task<PingResponse> PingClient(string connectionId)
    {
        var response = await server.SendMessageAsync<PingRequest, PingResponse>(
            connectionId, new PingRequest("Ping"));
        return response.Value;
    }
}

Implementing a client state service

public class MyClientStateService : ClientStateServiceBase<ClientConnectionInfo>
{
    public MyClientStateService(IServiceProvider sp, IOptions<CommunicationOptions> options)
        : base(sp, options) { }

    protected override ClientConnectionInfo Build(IClientConnectionInfo info) =>
        new()
        {
            Instance = info.Instance,
            ConnectionId = info.ConnectionId,
            Machine = info.Machine,
            Type = info.Type,
            Version = info.Version,
            IsConnected = info.IsConnected,
            ConnectTime = info.ConnectTime
        };

    protected override ClientConnectionInfo BuildDisconnect(ClientConnectionInfo info, DateTime disconnectTime) =>
        info with { IsConnected = false, DisconnectTime = disconnectTime };
}

Configuration

Client options

Property Description Default
ServerAddress The server URL to connect to (required)
Pattern The hub endpoint pattern "hub"
ReconnectDelays Delays between reconnection attempts [0s, 2s, 10s, 30s]
ApiKey API key sent to the server for authentication (none)
AdditionalAssemblies Extra assemblies to scan for message handlers (none)
SendMessageTimeout Default timeout for request-response messages 60s

Server options

The server requires registering a ClientStateServiceBase implementation and a ClientRepositoryBase implementation via the options callback. Use MemoryClientRepository<T> for an in-memory default.

Property Description Default
PrimaryApiKey Primary API key for client authentication (none)
SecondaryApiKey Secondary API key for zero-downtime key rotation (none)
AdditionalAssemblies Extra assemblies to scan for message handlers (none)

When no API keys are configured on the server, all connections are accepted (backwards compatible). When one or both keys are set, clients must provide a matching key via the X-Api-Key header.

Authentication

To secure the SignalR connection with API key authentication:

Server — configure one or both keys:

builder.AddThargaCommunicationServer(options =>
{
    options.PrimaryApiKey = builder.Configuration["Communication:PrimaryApiKey"];
    options.SecondaryApiKey = builder.Configuration["Communication:SecondaryApiKey"];
    options.RegisterClientStateService<MyClientStateService>();
    options.RegisterClientRepository<MemoryClientRepository<ClientConnectionInfo>, ClientConnectionInfo>();
});

Client — provide the matching key:

{
  "Tharga": {
    "Communication": {
      "ServerAddress": "https://localhost:5001",
      "ApiKey": "your-secret-key"
    }
  }
}

Or via the options callback:

builder.AddThargaCommunicationClient(o =>
{
    o.ApiKey = builder.Configuration["Communication:ApiKey"];
});

API keys can also be configured via User Secrets or environment variables. To rotate keys without downtime, set both PrimaryApiKey and SecondaryApiKey on the server — either key is accepted.

Handler discovery

By default, message handlers are discovered by scanning assemblies that match the entry assembly name prefix. If your handlers are in an external package (e.g. a separate NuGet), they won't be found automatically. Use AdditionalAssemblies to include them:

builder.AddThargaCommunicationClient(o =>
{
    o.ServerAddress = "https://localhost:5001";
    o.AdditionalAssemblies = [typeof(MyExternalHandler).Assembly];
});

The same option is available on the server side:

builder.AddThargaCommunicationServer(options =>
{
    options.AdditionalAssemblies = [typeof(MyExternalHandler).Assembly];
    options.RegisterClientStateService<MyClientStateService>();
    options.RegisterClientRepository<MemoryClientRepository<ClientConnectionInfo>, ClientConnectionInfo>();
});

If a client receives a SendMessage for a type with no registered handler, it immediately returns an error response to the server instead of silently timing out.

License

MIT

README copy captured when this server was indexed; it may lag the repository. The original is authoritative.

Questions

About Tharga.Communication.Mcp

How do I install Tharga.Communication.Mcp?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Tharga.Communication.Mcp safe to use with an AI agent?

Its trust score is 34 out of 100 (low). It passes 1 of the 1 static security checks run so far. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Tharga.Communication.Mcp still maintained?

Conduid hasn't recorded a commit date for this repository yet. Check the repository directly for recent activity.