Technology · Language

C#

The Windows side of my Teams integration is C# on .NET 8: a media service on Microsoft's real-time SDK, screen-share publication, and a product MCP server later ported to the official .NET SDK.

Helix · Auth and access planeWindows media bridge.NET 8
Helix in a Teams call · two hosts, one link
C# media bridgeAzure VM · joins calls, moves frames
Linux voice engineconversation, models and state
One authenticated WebSocket per call
the binary audio and video protocol, byte-identical in C# and Rust against golden vectors
20 msthe SDK frame the send loop is paced to
  • 6,400lines of .NET 8 in the media service's six-project solution
  • 100call-to-persona bindings exercised by its unit suite
  • 9,650lines in the weather MCP server, ported to the official C# SDK

A narrow Windows bridge into Teams calls

Helix had to put a self-hosted voice agent into Microsoft Teams calls, and Microsoft's real-time media stack runs only on Windows.

I keep the Windows component narrow so the system's logic stays in one place.

The service is .NET 8, a six-project solution covering host, calls, media, transport, contracts and unit tests, built on Microsoft's real-time media SDK and hosted on an Azure virtual machine with managed identity and vault-held secrets. It handles the calling callbacks and call lifecycle, answers inbound calls and places outbound ones, and binds each call to a persona.

One inbound call, two clients · illustrative
Employee identity
Transport-only
An outbound call
Calling bot identity
The employee answers and hangs up under its own name; the transport-only client owns the single native media platform for the media in between. Outbound calls present as Microsoft's calling bot, never as a spoofed employee.

The identity side is told in Solving the digital-employee identity.

Moving frames without stalling the SDK

Media callbacks copy the frame and return immediately, so SDK threads never wait on the network. The transport has bounded queues on both sides of the socket, and the SDK's unmanaged audio send buffers are tracked and released explicitly, outside the garbage collector's timing.

The sender transmits only while the socket is active. On reconnect it drops microphone audio captured during the break, so the conversation resumes in real time instead of replaying a backlog.

Thirty minutes of media between the Azure VM and the Linux host
Buffers moved
91,643
Receive stalls
0
Reconnects
0

Rate held at 50.001 buffers per second. A forced mid-call reconnect, run separately, recovered after one 250 ms retry.

The bridge kept pace with the SDK's frame clock for the whole soak.

The whole bridge is told in A self-hosted colleague in a Teams call.

Sharing an agent's screen into the meeting

Helix also lets an agent show its screen in a meeting, through H.264 frames the same bridge publishes.

browser
terminal
desktop
stop
clean
Frames from a headless desktop container, H.264 with periodic keyframes (dark ticks), published by the C# bridge as video-based screen sharing. Each kind of share was exercised in a real meeting.

Porting an MCP server onto the official SDK

Auth and access plane includes a weather-intelligence MCP server I first wrote in TypeScript, with a local transport and a trimmed surface for Microsoft Copilot Studio. I ported it to C# on the official MCP C# SDK with the ASP.NET Core HTTP transport, using the .NET HTTP client factory and in-memory caching.

TypeScript · 21 tools

the 8 in tone formed the trimmed Copilot Studio surface

C# on the official SDK · 15 tool classes

over the same nine public data services

Once an official SDK existed, the protocol layer stopped being my code to maintain.

The media SDK, Teams, Graph and Agent 365 are Microsoft's, used as Microsoft ships them.