<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>.NET on</title><link>https://eunus.dev/categories/.net/</link><description>Recent content in .NET on</description><generator>Hugo -- gohugo.io</generator><lastBuildDate>Thu, 02 Jul 2026 00:00:00 +0600</lastBuildDate><atom:link href="https://eunus.dev/categories/.net/index.xml" rel="self" type="application/rss+xml"/><item><title>Model Context Protocol Series 2A — OAuth 2.1 for MCP: Connecting Claude to Your Real Users with OpenIddict</title><link>https://eunus.dev/blog/model-context-protocol-series-2a-oauth-2.1-for-mcp-connecting-claude-to-your-real-users-with-openiddict/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0600</pubDate><guid>https://eunus.dev/blog/model-context-protocol-series-2a-oauth-2.1-for-mcp-connecting-claude-to-your-real-users-with-openiddict/</guid><description>Series 1 ended with a working MCP server — but every tool call it made to the backend used a service account with admin access and no tenant context. Which means Claude could, in theory, pull data from any tenant in the system. No audit trail. No permission boundaries. Just a skeleton key with your API&amp;rsquo;s address on it.
That&amp;rsquo;s not a security model. That&amp;rsquo;s a liability.
This post replaces the service account with OAuth 2.</description></item><item><title>Model Context Protocol Series 2B — The Bridge Middleware That Lets Claude Debug and Fix Its Own Tools</title><link>https://eunus.dev/blog/model-context-protocol-series-2b-the-bridge-middleware-that-lets-claude-debug-and-fix-its-own-tools/</link><pubDate>Thu, 02 Jul 2026 00:00:00 +0600</pubDate><guid>https://eunus.dev/blog/model-context-protocol-series-2b-the-bridge-middleware-that-lets-claude-debug-and-fix-its-own-tools/</guid><description>Series 2A wired up the full OAuth 2.1 stack: discovery endpoints, mock Dynamic Client Registration, JWT validation, bearer token forwarding. Every piece of it works — right up until Claude Code opens the browser to log in, and OpenIddict slams the door:
error: invalid_request error_description: The specified 'redirect_uri' is not valid for this client application. This post is about the one component that fixes it — a single bridge middleware — and why it earns its own post: it is the piece nobody else builds, because almost everyone tests their MCP OAuth against a client that never triggers the problem.</description></item><item><title>Version-Based Cache Validation in ABP — Keeping the Application Layer Clean Without Redis</title><link>https://eunus.dev/blog/version-based-cache-validation-in-abp-keeping-the-application-layer-clean-without-redis/</link><pubDate>Sun, 28 Jun 2026 00:00:00 +0600</pubDate><guid>https://eunus.dev/blog/version-based-cache-validation-in-abp-keeping-the-application-layer-clean-without-redis/</guid><description>Every caching tutorial I found did the same thing: reach into the application service, wrap the method body in GetOrCreateAsync, and call it clean architecture. The service now knows it&amp;rsquo;s being cached. It has a cache key. It has an invalidation call in the delete method. It has become a caching service with a thin layer of business logic underneath.
That bothered me. The application layer is supposed to contain orchestration and business use cases — not decide whether a response came from memory or a database.</description></item><item><title>Model Context Protocol Series 1 — Building a Production MCP Server in .NET with HTTP Transport</title><link>https://eunus.dev/blog/model-context-protocol-series-1-building-a-production-mcp-server-in-.net-with-http-transport/</link><pubDate>Thu, 18 Jun 2026 00:00:00 +0600</pubDate><guid>https://eunus.dev/blog/model-context-protocol-series-1-building-a-production-mcp-server-in-.net-with-http-transport/</guid><description>I was building a multi-tenant SaaS platform on ABP Framework and kept hitting the same wall: I wanted Claude to create tenants, query bookings, and manage configuration — not by generating code for me to run, but by calling the actual API directly. Like giving an AI assistant a real key to the backend, not a stack of printed instructions.
That&amp;rsquo;s exactly what MCP enables. But once I started digging, every tutorial I found showed stdio — a local process Claude spawns and kills.</description></item></channel></rss>