Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
157030 stories
·
33 followers

Secret Claude Tracker Shocks Users After Anthropic's Anti-Surveillance Stance

1 Share
An anonymous reader quotes a report from Ars Technica: Anthropic quickly removed a tracker secretly monitoring Claude Code users in China after a security researcher exposed the hidden code and condemned the spyware-like tracking as a "serious breach of user trust." Last week, a web developer known as "Thereallo" was researching privacy issues in Claude Code and was shocked to find that the AI firm was using "prompt steganography" to hide code that tracks Chinese users "in plain sight." This code wasn't malicious, but it was sending information to Anthropic that most users wouldn't detect, relying on shorthand markers to quietly flag users' timezone, proxy, and potential connection to Chinese AI labs that Anthropic has accused of distillation attacks. On X, Anthropic engineer Thariq Shihipar confirmed that the tracker was added to Claude Code as an "experiment" in March. According to Shihipar, the code "was meant to prevent account abuse from unauthorized resellers and protect against distillation." Regarding the former, The Washington Post found unauthorized retailers have sold access to free models for $1 a month, and pro subscriptions that can cost $100 monthly sell for "as little as $12." Supposedly, Anthropic has "actually been meaning to take this down for a while," Shihipar said of the hidden code, because engineers have "landed stronger mitigations since then." Privacy advocates were not happy with the explanation, though, warning that the code is evidence that Anthropic is willing to cross lines to surveil users. That's perhaps especially surprising, considering that Anthropic riled the Trump administration by refusing to allow the US government to use Claude to surveil US users. The AI firm has since sued the White House over the clash. The Post suggested that the tracker incident is a sign that US firms like Anthropic are taking "increasingly aggressive measures" to block Chinese AI firms from copying their models. A more defensive stance has apparently become critical. In the past year, Chinese firms have "consistently matched" US firms' model capabilities "within months," the Post reported. Most recently, "a new, free AI model from Chinese company Zhipu AI was better at finding computer vulnerabilities than Anthropic's Claude Opus 4.8 model, which was released in May," the Post reported.

Read more of this story at Slashdot.

Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Who Wins The AI Superapp Battle?, Apple’s Consumer AI Victory, World Cup Automation Mistake

1 Share

M.G. Siegler is the author of Spyglass.org. Siegler joins Big Technology to discuss the race to build the AI super app and which companies are best positioned to win. Tune in to hear why OpenAI, Anthropic, Google, Microsoft, Meta, and Apple are all converging on the same idea: an AI interface that can handle more and more of your computing life. We also cover Apple’s new Siri, whether consumer AI will be won by default on the iPhone, and what World Cup automation says about our growing reliance on machines. Hit play for a sharp, wide-ranging conversation about where AI products are headed next.

---

Enjoying Big Technology Podcast? Please rate us five stars ⭐⭐⭐⭐⭐ in your podcast app of choice.

Want a discount for Big Technology on Substack + Discord? Here’s 25% off for the first year: https://www.bigtechnology.com/subscribe?coupon=0843016b


Learn more about your ad choices. Visit megaphone.fm/adchoices





Download audio: https://pdst.fm/e/tracking.swap.fm/track/t7yC0rGPUqahTF4et8YD/pscrb.fm/rss/p/traffic.megaphone.fm/AMPP3037143188.mp3
Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

EP285 Scaling Lessons from Leading the NSA to Defending the World with Morgan Adamski

1 Share




Download audio: https://traffic.libsyn.com/secure/cloudsecuritypodcast/2026-04-27-GSP-Ep277-1.0_AUDIO.mp3?dest-id=2641814
Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Understanding Copilot Risk: Mapping Exposure Across Zero Trust Pillars

1 Share

AI represents a major shift in how users interact with organizational data. Instead of finding information one file, email, or chat at a time, users can ask natural language questions and get synthesized answers drawn from content they already have permission to access. That can improve productivity, but it can also amplify the impact of broad access, oversharing, and weak governance.  

Microsoft 365 Copilot brings this shift into focus. It doesn’t grant new permissions, but it acts as a force multiplier for existing access, making it faster and easier for users to discover, aggregate, and act on data across Microsoft 365. That makes it critical to understand both who can access Copilot and what data it can surface on a user’s behalf. A second layer of risk follows from how organizational data is structured, shared, and governed. In environments with overshared content, excessive permissions, or inconsistent governance, this acceleration can lead to faster and broader access to sensitive information than organizations may expect. 

This shift carries important security implications, especially as organizations move from pilots to scaled deployment. While customers with Microsoft 365 E5 licensing may already have access to tools that help identify and reduce risk, licensing alone does not reduce exposure.  

What’s often missing during early Copilot deployments is a clear view of the risk surface itself: what data is exposed, who can access it, and through which vectors. Organizations building their Microsoft 365 Zero Trust posture can use the Zero Trust Workshop to assess their current postureidentify gaps, and better understand how existing permissions and governance impact Copilot readiness 

In this post, we map Copilot-related risk to the key Zero Trust control areas most relevant to deployment: identity, endpoints, apps, and data. Our goal is to help organizations understand where exposure exists and which control areas they should focus on before scaling deployment. 

Use Zero Trust to assess Microsoft 365 Copilot risk 

Microsoft defines Zero Trust as a security model built on three core principles:  

  1. Verify explicitly
  2. Use least privileged access
  3. Assume breach  

Instead of trusting users or devices based solely on network location, Zero Trust requires continuous validation of every user, endpoint, and request, regardless of where the request originates. Microsoft’s Zero Trust adoption model groups security controls across technology pillars such as identities, endpoints, apps, data, network, infrastructure, and security operations.  

For this analysis, we’ll focus on the four pillars most directly involved in Microsoft 365 Copilot deployments: identity,endpoints, apps, and data.  

Figure 1. Four control areas that shape Copilot exposure 

 

 

 

 

 

Together, these pillars help answer three key questions:  

  1. Who can access Copilot
  2. From which endpoints and applications
  3. What data can Copilot surface once access is granted 

For more information and details about Microsoft’s Zero Trust framework, visit Zero Trust Overview at Microsoft Learn. 

Why Microsoft 365 Copilot changes the risk conversation 

Before assessing specific risks, it helps to understand why Copilot changes the risk conversation compared to traditional Microsoft 365 applications. Most enterprise apps operate within a bounded context. The time and effort required to manually locate, connect, and synthesize information across systems creates friction and a practical limit on how quickly users can surface and act on data across systems. Copilot removes much of that friction. At the speed of a prompt, Copilot lets users retrieve and bring together information from across a user’s existing access—spanning emails, files, meetings, chats, and other Microsoft 365 services—in a single response.

This exposure is not a result of new permissions. It comes from how quickly and easily existing access can be discovered, aggregated, and used. To understand where exposure appears, it helps to break Copilot risk into two interconnected layers: access and data. 

Figure: Two-layer model for Microsoft 365 Copilot risk.

 

 

 

 

 

 

 

 

 

 

The two-layer Microsoft 365 Copilot risk model 

The foundation of this analysis is simple: Copilot acts as a force multiplier for whatever access a user already has. If that access is governed well, Copilot can improve productivity. If not, it can amplify exposure.  

 With that framing in mind, we’ll examine Copilot risk in two distinct layers: 

  1. Access to the Copilot service itself
  2. Access to the data that Copilot can ground on and surface 

The first layer focuses on who can access Copilot and under what conditions. The second focuses on what Copilot can see and surface once access is granted. 

Risk layer 1: Who can access Microsoft 365 Copilot? 

The first layer of risk begins at the point of entry: the conditions that determine whether a user can access Copilot. Organizations don’t need to address every potential exposure point at once. Start by using the table below as a map of where exposure can exist across identity and endpoint controls. We’ll explore how to mitigate these risks in the second post of this series.

The risks below are primarily governed by Microsoft’s Zero Trust identity and endpoint pillars. Together, these pillars help determine whether the right user can access Copilot from a trusted endpoint under the right access conditions. 

Table 1. Identity and endpoint risks that affect Copilot access

 

Risk 

Pillar 

Description 

R1

Unmanaged identity access 

Identity 

A compromised, shared, or former employee account can authenticate Microsoft 365 and access Copilot. Because Copilot operates across the full scope of a user’s permissions, compromised accounts can expose a much larger risk surface than before Copilot existed. Strong account hygiene and identity lifecycle management can reduce that exposure. 

R2

Weak or absent multi-factor authentication (MFA) 

Identity 

If MFA isn’t enforced, or if legacy authentication bypasses modern sign-in controls, users can start Copilot sessions with only a password. In environments with inconsistent MFA coverage, stolen credentials may be enough to gain access. Because Copilot can synthesize data across services, compromised accounts create more risk than access to a single application. 

R3

Unmanaged or non-compliant devices 

Endpoints 

Users can access Copilot through browsers and native apps from any device where they can authenticate. Unmanaged or noncompliant endpoints without endpoint protection, encryption, or compliance evaluation can expose Copilot sessions and allow outputs to be stored or exfiltrated locally. 

R4

Broad Copilot licensing without role-based scoping 

Identity and apps 

Broad Copilot licensing without role-based scoping. Copilot pilots often begin with broad license assignments across departments or business units instead of smaller, security-reviewed user groups. When organizations assign licenses without reviewing access rights, permission posture, and role sensitivity, they can expand exposure across both well-governed and minimally governed users.  

R5

Missing real-time risk evaluation at sign-in 

Identity and endpoints 

If Conditional Access doesn’t evaluate sign-in and user risk signals, such as anomalous activity, or identity protection alerts, high-risk sessions may still reach Copilot. Without real-time risk evaluation, controls may respond only after access is granted. 

R6

App protection gap on mobile devices 

Endpoints and apps 

Users can access Copilot from personal mobile devices that are not enrolled in device or app management. Without app protection policies, organizations may not be able to control how Copilot outputs move into unmanaged apps or remove organizational data from lost devices. 

Key observations from Layer 1: 

Identity appears most frequently across Layer 1, reflecting how tightly Copilot access depends on authenticated user permissions and sign-in conditions. Endpoint-related risks also play a major role because unmanaged or noncompliant endpoints can expose Copilot sessions and outputs beyond the organization’s trusted environment. 

Together, these risks show that securing Copilot access is shaped by two factors: who can sign in, and whether the endpoint and session meet the organization’s access requirements. 

Risk layer 2What data can Microsoft 365 Copilot reach? 

The second layer of risk assumes that the user is already authenticated and actively using Copilot. At this stage, the focus shifts from who can access Copilot to what data Copilot can surface on the user’s behalf. These risks reflect the exposure created by existing permissions, overshared content, connected systems, and governance gaps.  

Layer 2 risks are governed primarily by the apps and data pillars, with identity playing a secondary role in defining the scope of data each user can access. Much of Copilot’s value and risk comes from how it surfaces information based on user intent. 

Figure:How user intent changes data discovery

 

 

 

 

 

 

 

 

 

Data and application risks that shape Copilot exposure 

These risks highlight how permissions, sharing, labeling, and governance directly shape what Copilot can retrieve, synthesize, and surface across organizational data. 

 

Risk 

Zero Trust pillar(s) 

Description 

R7

Overshared SharePoint and OneDrive content 

Apps and identity 

Content shared with "Everyone," "Everyone except external users," or broad groups can become part of Copilot’s queryable surface for licensed users who already have access to that content. Years of oversharing, combined with Copilot’s ability to retrieve and synthesize content in a single prompt, can turn long-standing governance gaps into immediate exposure. Copilot can make data that was once hidden by volume, discoverable by intent. 

R8

Sensitivity label gaps 

Apps and data 

Microsoft Purview sensitivity labels and related protections tell Copilot how to handle content, including whether it can summarize, cite, or include that content in responses. Across containers such as SharePoint sites and Teams, unlabeled, incorrect, or inconsistently labeled content may be treated as unclassified and surfaced freely. Large volumes of legacy content can make that gap harder to manage at scale. 

R9

Excessive user permissions 

Identity and apps 

Copilot follows each user’s existing Microsoft 365 permissions and does not surface content users cannot access. However, users often accumulate access beyond their current role through leftover project permissions, temporary group memberships, and inherited access. Copilot doesn’t create this overprovisioning, but it can make the full scope of it easier to discover and use. 

R10

No DLP coverage on Copilot-generated outputs 

Apps and data 

Copilot outputs, such as summaries and drafts can combine sensitive details from multiple sources.  

Organizations should review how their DLP labeling and data protection policies apply to generated content, especially when users move Copilot outputs into email, chat, or external documents. 

R11

Plugin and connector data surface expansion 

Apps and identity 

Organizations can extend Copilot through agent and connectors that pull external data from CRM systems, ITSM platforms, and other line-of-business tools. Each connected source expands the set of data users can access through Copilot. Each connected source expands the set of data users can access through Copilot and may introduce governance and access model differences that need to be reviewed. 

R12

Audit and visibility gap 

Apps and data 

Organizations need enough visibility to understand how users interact with Copilot and which resources Copilot accesses in response to prompts.  Audit logs and monitoring help security teams investigate suspicious activity, understand usage patterns, and reduce risk over time. 

R13

Privileged user data amplification 

Identity, apps and data 

Privileged users often hold access across sensitive systems and data. A compromised privileged account with Copilot access can expose a much larger slice of organizational data than a standard user account. Privileged identities therefore need tighter access to governance and review. 

Key observations from Layer 2: 

Apps-related risks appear throughout Layer 2 because Microsoft 365 Copilot depends on connected systems, accessible data sources, and governance over generated outputs. The data pillar reinforces the need to protect both sensitive source content and the AI-generated responses that bring content together. The table above maps each risk to its primary and secondary Zero Trust pillars to show where to act. Primary pillars represent control areas that most directly govern a given risk, while secondary pillars represent contributing factors. 

Governing Microsoft 365 Copilot riskNext steps 

Copilot typically doesn’t grant broader access than a user already has. Instead, it makes existing access easier to discover, connect, and use across Microsoft 365. Organizations that successfully scale Copilot are the ones that understand and govern that access first. Understanding where exposure exists is the first step. Your next step depends on where your organization is in their Zero Trust journey. 

Need to assess your current status? Visit the Zero Trust Workshop. 

Ready to learn more about reducing risk by strengthening access controls at the point of entry? Check out post 2 of this series: Mitigating Microsoft 365 Copilot access risk: Identity and device controls for Zero Trust.

Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Give Your MAUI Agent Hands — Contacts, Reminders & Location AI Tools

1 Share

When we shipped Shiny.Health.Extensions.AI, it proved a simple point: a chat model becomes far more useful when it can do things instead of just talk about them. Give it a tool to read step counts and “how did I sleep last week?” stops being a guess and starts being an answer pulled from the device.

So we did the same for three more device services. Three new packages expose Shiny modules as Microsoft.Extensions.AI tool functions:

  • Shiny.Contacts.Extensions.AI — search and manage the device address book
  • Shiny.Notifications.Extensions.AI — schedule and cancel reminders
  • Shiny.Locations.Extensions.AI — read-only GPS: where you are, and how far/long to somewhere else

They all follow the same shape as Health: you opt-in to exactly which operations the model can see (a read/write allow-list you control on behalf of the agent — not an OS permission prompt), it’s read-only by default, and the whole thing is IsAotCompatible — schemas are hand-built and results come back as JsonNode, so there’s no reflection in the tool path.

Contacts

NuGet package Shiny.Contacts.Extensions.AI
dotnet add package Shiny.Contacts.Extensions.AI
builder.Services.AddContactStore();
builder.Services.AddContactsAITools(tools => tools
.AddContacts(ContactAICapabilities.ReadWrite) // Read is the default; ReadWrite adds create/update/delete
);

This generates search_contacts, get_contact, and — when you opt-in to Writecreate_contact, update_contact, and delete_contact.

What you’d use it for: a personal-assistant or CRM-lite app where the user talks to the address book instead of tapping through it — “grab that number so I can text them,” “add the person on this business card,” “which of my contacts work at Acme?” The agent looks up an id with search_contacts, then acts on it.

Example questions:

  • “What’s Jane Doe’s mobile number?”
  • “Add a contact for my new dentist — Dr. Patel at Bright Smiles Dental, 555-0142.”
  • “Change my brother Mike’s email to mike@newjob.com.”
  • “Do I have anyone saved from Acme Corp?”
  • “Delete the contact for my old landlord.” (destructive — tell the model to confirm first)

Reminders

NuGet package Shiny.Notifications.Extensions.AI
dotnet add package Shiny.Notifications.Extensions.AI
builder.Services.AddNotifications();
builder.Services.AddNotificationAITools(tools => tools
.AddReminders(ReminderAICapabilities.ReadWrite, channel: "reminders") // channel is optional
);

Local notifications, framed as reminders. You get list_reminders, and — with Writecreate_reminder (fire now, at a specific date/time, or daily at a set time) and cancel_reminder.

What you’d use it for: any “remind me…” flow in a chat assistant — todo apps, habit and medication trackers, follow-up nudges. The user speaks a reminder in natural language and the model schedules a real local notification; scheduleFor and repeatDailyAt cover one-shot and recurring.

Example questions:

  • “Remind me to call the plumber at 3pm today.”
  • “Set a daily reminder to take my meds at 8:30am.”
  • “What reminders do I have set?”
  • “Cancel the one about the dentist.”
  • “Nudge me to water the plants every evening at 6.”

Location

NuGet package Shiny.Locations.Extensions.AI
dotnet add package Shiny.Locations.Extensions.AI
builder.Services.AddGps();
builder.Services.AddLocationAITool(); // read-only — there's no write capability for GPS

GPS is read-only, so there’s no builder to configure — a single AddLocationAITool() registers get_current_location, get_distance_to, and estimate_travel_time. The agent can learn where the user is and reason about distance and rough travel time to a destination.

What you’d use it for: travel and field-service apps, delivery/ETA estimates, “am I near…” checks, or any assistant that should be location-aware. One honest caveat baked into the tools: distances are great-circle (straight-line) and travel times use an assumed average speed — the results say so in a note field, so the model caveats its answer rather than pretending to be a routing engine.

Example questions:

  • “Where am I right now?”
  • “How far is it from here to 51.4700, -0.4543?”
  • “Roughly how long to cycle to the park at 51.51, -0.12?”
  • “Am I within 2 km of the office?”
  • “What’s my current speed and heading?”

Compose them into one agent

Each package hands you a small bundle you resolve from DI. Concatenate their .Tools and pass the lot to any IChatClient:

var tools = new List<AITool>();
tools.AddRange(sp.GetRequiredService<ContactAITools>().Tools);
tools.AddRange(sp.GetRequiredService<NotificationAITools>().Tools);
tools.AddRange(sp.GetRequiredService<LocationAITools>().Tools);
var response = await chatClient.GetResponseAsync(
messages,
new ChatOptions { Tools = tools }
);

Now a single message can fan out across all three:

“I’m meeting Sarah at the office at 5 — how far am I, and remind me to leave in an hour.”

The model calls search_contacts for Sarah if it needs her details, get_distance_to for the office, and create_reminder for the nudge — one turn, three device services.

Permissions still belong to your app

The capability builders (AddContacts(...), AddReminders(...)) are an allow-list for the agent — they decide which operations the model can see. They are not an OS permission prompt. The underlying platform permission must already be granted: call IContactStore.RequestAccess, INotificationManager.RequestAccess, or start a GPS listener from your app before you invoke the agent. The tools assume access is in place and return a clean error object if it isn’t.

Get started

dotnet add package Shiny.Contacts.Extensions.AI
dotnet add package Shiny.Notifications.Extensions.AI
dotnet add package Shiny.Locations.Extensions.AI

Full details on each: Contacts AI Tools, Reminder AI Tools, and Location AI Tools. Same pattern as Health AI Tools — opt-in, read-only by default, AOT-safe, and now your agent has hands.

Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Foundry Local Monitor — See every local AI model your machine is running with Foundry Local

1 Share

⚠ This blog post was created with the help of AI tools. Yes, I used a bit of magic from language models to organize my thoughts and automate the boring parts, but the geeky fun and the 🤖 in C# are 100% mine.

Foundry Local Monitor hero image

Hi!

If you have been playing with Foundry Local to run AI models on your own machine, you probably ran into the same thing I did: you never really know what is running.

You load a model from the CLI. Your C# app loads another one through the SDK. A Python script spins up its own. A .NET Aspire sample launches a proxy. And five minutes later you have several models loaded across several ports, eating memory, and you have no idea which one belongs to what.

Foundry Local does not run on a single fixed port, and the foundry CLI only sees what the CLI itself started. Everything an app loads directly through the SDK is, basically, invisible.

So I built a small tool to fix that: Foundry Local Monitor.

It is a tiny Windows tray app that watches your machine and tells you, in real time, which Foundry Local instances are running, which models are loaded, and on which device (CPU, GPU, CUDA, DirectML…). When a model loads or unloads — from any app — you get a notification.

What it does

  • Lives in your system tray, out of the way.
  • Discovers all Foundry Local instances on your machine, no matter which language or SDK started them.
  • Shows the models loaded by each instance, grouped by process.
  • Tells you the device backend for each model (CPU / GPU / CUDA / TensorRT / DirectML / WinML) with a colored badge.
  • Fires a toast notification when a model is loaded or unloaded.
  • Has a handy 📂 button to open the process location on disk.
Loaded Models tab

Install it

It is published as a .NET global tool, so one line and you are done:

dotnet tool install -g ElBruno.FoundryLocalMonitor

Then run it:

foundrylocalmon

That’s it. Look for the 🤖 icon in your system tray. Right-click for options, double-click to open the main window with the Status, Loaded Models, and Available Models tabs.

To update later:

dotnet tool update -g ElBruno.FoundryLocalMonitor

A quick example: the scenario it detects

Here is the kind of code the monitor is designed to see. This is a plain .NET console app using the Microsoft.AI.Foundry.Local SDK — no CLI involved. The SDK spins up its own OpenAI-compatible REST server, and that is exactly what the monitor finds and shows in real time.

using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;
// The SDK hosts an internal OpenAI-compatible server on this address.
// The C# SDK default is 55588 (Python uses 55589).
var config = new Configuration
{
AppName = "MyFoundryApp",
Web = new Configuration.WebService { Urls = "http://127.0.0.1:55588" }
};
await FoundryLocalManager.CreateAsync(config, NullLogger.Instance);
var manager = FoundryLocalManager.Instance;
// Start the web service — this is the endpoint the monitor discovers.
await manager.StartWebServiceAsync();
var endpoint = manager.Urls?.FirstOrDefault();
Console.WriteLine($"Foundry Local is serving at {endpoint}");

From this point on, the app is completely invisible to the foundry CLI — but the monitor sees it, because it answers on an HTTP port. The moment a model loads, you get a toast.

Talking to that endpoint is just OpenAI-compatible HTTP, so any .NET HttpClient works:

using System.Net.Http.Json;
using var http = new HttpClient { BaseAddress = new Uri(endpoint!) };
var response = await http.PostAsJsonAsync("/v1/chat/completions", new
{
model = "qwen2.5-coder-0.5b",
messages = new[]
{
new { role = "system", content = "You are a helpful assistant." },
new { role = "user", content = "What is Foundry Local in one sentence?" }
},
max_tokens = 200
});
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);

You can find a full end-to-end sample (init → start → load → chat → unload → stop) in the samples/FoundryLocalChat folder of the repo.

How instances are discovered

This is the part I like the most, so let me explain the trick.

Foundry Local does not use a well-known port. The daemon picks a random one at startup, the C# SDK defaults to 55588, the Python SDK to 55589, and an Aspire proxy gets whatever Aspire assigns. There is no central registry to ask.

So the monitor does something simple and effective: it scans your local ports.

  1. It asks the OS for every TCP port currently listening on 127.0.0.1. This is a fast kernel call, no guessing.
  2. For each of those ports — in parallel — it sends a GET /v1/models request.
  3. Any port that answers with {"object":"list"} is a Foundry Local (OpenAI-compatible) endpoint. Everything else is ignored.
  4. Each discovered endpoint is enriched with process info: name, PID, full path, and whether it is an SDK proxy or the daemon.
  5. Endpoints are grouped by PID, so one process = one card in the UI.

Why parallel? A typical machine has 15–30 listening ports. Probing them one by one, with a timeout each, could take 20+ seconds. Fanning out all the probes at once brings the whole scan down to roughly the time of a single probe — about 800ms. The scan re-runs every 30 seconds, so newly launched apps show up on their own.

In .NET, the port enumeration and the parallel probe boil down to something like this:

using System.Net.NetworkInformation;
// 1. Ask the OS for every port listening on localhost (fast kernel call).
var listeners = IPGlobalProperties.GetIPGlobalProperties()
.GetActiveTcpListeners()
.Where(ep => IPAddress.IsLoopback(ep.Address))
.Select(ep => ep.Port)
.Distinct();
// 2. Probe them all in parallel — a Foundry endpoint answers /v1/models
// with {"object":"list"}.
var probes = listeners.Select(async port =>
{
using var http = new HttpClient { Timeout = TimeSpan.FromMilliseconds(800) };
try
{
var json = await http.GetStringAsync($"http://127.0.0.1:{port}/v1/models");
return json.Contains("\"object\":\"list\"") ? port : (int?)null;
}
catch { return null; }
});
var foundryPorts = (await Task.WhenAll(probes))
.Where(p => p is not null)
.Select(p => p!.Value);

The nice side effect: because the monitor talks HTTP and not the CLI, it sees everything — CLI, C# SDK, Python SDK, Aspire, or any OpenAI-compatible local server. If it listens and it answers, it shows up.

How models are discovered

Once the monitor knows where the endpoints are, it asks each one what it is serving:

  • For an SDK proxy, it calls GET /v1/models.
  • For the daemon, it calls GET /openai/loadedmodels (the models actually in memory).

The interesting bit is the device. Foundry Local encodes the backend right in the model id as a suffix, for example:

Phi-4-mini-instruct-cuda-gpu:5

The monitor strips the version (:5), reads the suffix, and turns it into a friendly badge:

SuffixDeviceBadge
-cuda-gpuCUDA🟢 green
-trtrtx-gpuTensorRT🟩 emerald
-gpuGPU🟢 green
-cpuCPU🔵 blue
-directml-gpuDirectML🟣 purple
-winml-cpuWinML🟠 orange

The parsing itself is a nice little C# pattern-match — strip the version, match the longest device suffix, map it to a label:

static (string Alias, string Device) ParseModelId(string modelId)
{
// "Phi-4-mini-instruct-cuda-gpu:5" -> drop the ":5" version.
var noVersion = modelId.Split(':')[0];
// Longest suffixes first so "-cuda-gpu" wins over "-gpu".
string[] suffixes =
[
"-trtrtx-gpu", "-cuda-gpu", "-generic-gpu", "-generic-cpu",
"-winml-directml", "-winml-cpu", "-directml-gpu", "-cpu", "-gpu"
];
foreach (var suffix in suffixes)
{
if (!noVersion.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
continue;
var alias = noVersion[..^suffix.Length];
var device = suffix switch
{
"-trtrtx-gpu" => "TensorRT",
"-cuda-gpu" => "CUDA",
"-generic-gpu" or "-gpu" => "GPU",
"-generic-cpu" or "-cpu" => "CPU",
"-winml-directml" or "-directml-gpu"=> "DirectML",
"-winml-cpu" => "WinML",
_ => "?"
};
return (alias, device);
}
return (noVersion, "?"); // utility models have no device suffix
}

So at a glance you can tell whether that model is actually running on your GPU or quietly sitting on the CPU. Very useful when you are wondering why something is slow.

And about those notifications: to avoid noise, models discovered on the SDK’s own internal ports are marked silent by default. Only load/unload events from real apps or the daemon pop a toast. You can tune this in Settings.

Wrap up

Foundry Local is a fantastic way to run models locally, and this little monitor gives you the missing piece of visibility: what is actually running, right now, and where. Install it, forget about it, and let it tell you when things change.

If you find a bug or want a feature, the repo is open — issues and PRs welcome.

Resources

Happy coding!

Greetings

El Bruno

More posts in my blog ElBruno.com.

More info in https://beacons.ai/elbruno






Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories