Writing

Thoughts on Cloud Computing, DevOps, and Software Engineering.
Sharing lessons learned from building scalable systems.

Delegating to Subagents with the Claude Agent SDK

A code review agent that hands work to security and test subagents: routing via AgentDefinition, hooks that prove delegation happened, parallel and background runs, and a cost cap you can verify.

Build a Private RAG Pipeline with Ollama and pgvector

A fully local retrieval-augmented generation stack: PostgreSQL with pgvector stores embeddings, Ollama runs the embedding and chat models. No API keys, no cloud, ~100 lines of Python.

Trace Your AI Agent with Langfuse: Self-Hosted LLM Observability

An agent that misbehaves is a black box until you trace it. Self-host Langfuse with Docker Compose, instrument a tool-calling agent with the Python SDK, and see every LLM call, tool execution, token count, and cost in one trace tree.

Give Your Agent a Browser with Playwright MCP (Without Handing Over Your Logins)

A hands-on setup for Microsoft Playwright MCP: install it in Claude Code, Codex, or VS Code, drive a real page through accessibility snapshots, then close the defaults that let an agent reach your logged-in profile, your files, and any URL it likes.

Building an MCP Server in Go with the Official SDK

A working MCP server in Go: one tool, one resource, a resource template and a prompt, over stdio and streamable HTTP. Every snippet compiled, tested, and the gotchas verified against v1.8.0.

A Typed AI Agent You Can Test Without an API Key

Build a support triage agent where the model cannot call a tool with junk, refunds are validated in Python, retry loops are budgeted, and the whole loop runs in pytest with no network. Pydantic AI 2.63.0, full code.

Docker MCP Gateway: Run MCP Servers in Sandboxed Containers

Set up Docker MCP Gateway from the CLI: profiles, the server catalog, secrets, stdio vs streaming transports, client wiring for Claude Desktop and VS Code, and the cases where a plain stdio config is still the better call.

Build an MCP Server in Python: From Zero to Working Tools

Step-by-step tutorial to build a custom MCP server in Python with SQLite-backed task management tools. Test it with the MCP Inspector, then connect it to Claude Desktop or VS Code.

Stop Prompting for JSON: Constrain the Decoder with Outlines

Compile a Pydantic schema into a token mask so a local model cannot emit malformed JSON. Includes a measurable before/after test, regex and choice constraints, and the vLLM 0.12 API change that breaks older guided decoding code.

MCP Elicitation: Pause a Tool Call and Ask the User

Elicitation lets an MCP tool stop mid-call, ask the user a question, and keep going with the answer. A working resolver-based server on mcp 2.2.0, the flat-schema rules, the 2026-07-28 transport change, and the security requirements you cannot skip.

How to Test and Debug MCP Servers with MCP Inspector

A tight feedback loop for MCP development: launch your server inside the Inspector, inspect its tools, call one by hand, and read the raw response. With the CLI mode for CI and the failure modes that break Claude Desktop connections.

Build an MCP Client That Connects to Multiple Servers in Python

Most MCP tutorials stop at one client, one server. Real agents need many. This guide builds a Python client that connects to two MCP servers in parallel, prefixes their tools to avoid collisions, and hands them to Claude as Anthropic-format tool definitions.

Google ADK 2.0: Build a Graph-Based Agent Workflow in Python

A step-by-step build of a support triage agent with Google ADK 2.0: custom function tools, session state, a Workflow graph with routing, the eval set that locks the routing down, and deploy commands.

Build a Tool-Using AI Agent with the Claude Agent SDK (Python)

Use Anthropic's official Claude Agent SDK to build a Python agent with custom tools, in-process MCP servers, PreToolUse hooks, and streaming output. Real code, no hand-waving.

Your pgvector Index Is Lying About Recall. Measure It in SQL.

A 40-line SQL harness that measures real recall@10 and latency for HNSW and IVFFlat on 50,000 vectors. With measured numbers for ef_search, m, and probes, plus the Docker shared memory error that breaks the first index build.

Build Your First Multi-Agent System with CrewAI

Give each AI agent a specific role, hand them real tools, and let them collaborate. Build a research-and-writing crew that researches a topic and writes a report — in under 30 minutes, all in Python.

Build Your First MCP Server in Python: A Hands-On Guide

Model Context Protocol is becoming the standard way to give LLMs access to tools and data. This guide walks you through building a real MCP server in Python, connecting it to Claude Code, and shipping it in under an hour.

Run a Local LLM Code Reviewer with Ollama and Continue.dev

A practical setup for a private, offline code reviewer. Pull a coding model in Ollama, wire it to VS Code through Continue, and review diffs without your code ever leaving the machine.

Ollama: Run Open-Source LLMs Locally with One Command

A hands-on guide to Ollama: install, pull a model, run it from the CLI, call it from Python and Node, build a custom Modelfile, and know when to use it instead of vLLM or a hosted API.

Agent Skills: Write the Procedure Once, Load It Only When Needed

A skill is a folder with a SKILL.md file, and most first attempts never trigger. Here is the frontmatter, the description pattern, the folder layout, and a validator you can run before you trust it.

Sandboxing AI Agent Code with Docker: Four Tests That Prove the Walls Hold

A plain docker run gives you a container, not a sandbox. Here are the image and the run flags that close off network, filesystem, memory, pids, and privilege escalation, plus four tests that prove each wall holds on your own machine.

Build Your First MCP Server with Python

Give your LLM real tools. Build an MCP server in Python that exposes custom functions and resources — connect it to Claude Desktop in under 15 minutes.

Your Agent Dies Mid-Run. LangGraph and Postgres Pick It Back Up

An agent that pauses for human approval, dies with its worker, and resumes in a different process. Built on a Postgres checkpointer, with the four traps that cause duplicate charges in production.

Load Testing with k6.io: Beginner's Guide

Practical tutorial on using k6.io for load testing. Includes example scripts and result interpretation for production environments.

Trace Your AI Agent with OpenTelemetry GenAI Conventions (Python)

A step-by-step Python setup for tracing the agent loop, its model calls, and every tool call with the OpenTelemetry GenAI conventions. Includes the conversation-id span processor most agents forget, a local mock so you can run it without an API key, and the span output from the actual run.

Build a CLI AI Agent with Ollama Tool Calling in Python

Step-by-step tutorial to build a local AI agent that reads files, runs shell commands, and handles multi-step requests using Ollama and Python. No cloud API needed.

Prompt Caching: Cut LLM API Costs by 50-90% with Claude and OpenAI

Stop paying full price for the same system prompt on every API call. A hands-on guide to prompt caching with Anthropic (automatic + explicit) and OpenAI — with copy-paste Python code and real cost comparisons.

Audit your MCP servers before you trust them

A poisoned MCP tool description stays invisible in the client UI and fully readable by the model. Build a vulnerable server, scan it two ways, pin tool hashes, and see what scanners miss.

MCP Tasks: Long-Running Tool Calls Without Blocking Your Agent

The Tasks extension lets an MCP server hand back a durable task handle instead of holding the connection open. Here is the wire format, a job-and-poll pattern that works on every host today, and where SDK support actually stands.

Build an A2A Agent in Python: Another Agent Can Call Yours

A hands-on guide to Agent2Agent 1.0 with the official Python SDK: publish an agent card, implement an AgentExecutor, stream a task, and skip the two mistakes that break it in production.

Self-Host Coolify: Git Deploys, TLS, and Scheduled Backups on One VPS

Install Coolify on a VPS, lock down the dashboard, deploy an app from Git, connect Postgres, and ship backups to S3. Includes a restore test and when to pick Coolify over Dokku, Kamal, or plain Docker Compose.

Give Your LLM Superpowers: Build an MCP Server in 15 Minutes

A hands-on guide to building a Model Context Protocol server that lets Claude read your files, browse directories, and fetch URLs. Includes copy-paste Python code, MCP Inspector testing, and Claude Desktop integration.

Context Engineering for Long-Running Agents: Compaction, Notes and Subagent Isolation

Build a Python agent harness that stays coherent past turn 40. Measure tokens per request, clear dead tool results on the server side, compact the transcript, keep decisions in a notes file, and delegate search to subagents that return 2000 token summaries instead of 40000 token transcripts.

Stop Hand-Tuning Prompts: Optimize Them With DSPy GEPA

GEPA rewrites your prompt against a metric instead of your intuition. Build a small DSPy triage program, score it, optimize the instructions with text feedback, then run the result on a local Ollama model. Every API call checked against dspy 3.3.1.

Self-Host Open WebUI: Your Own ChatGPT with Ollama, RAG, and Web Search

Stand up a team-wide AI interface on your own hardware in about fifteen minutes: pinned Docker images, a compose stack with SearXNG, knowledge bases over your documents, and the ConfigVar trap that eats an afternoon.

Build a Local AI Agent with Tool Calling: Ollama + qwen3

Turn a local LLM into an agent that actually acts. Build the tool-calling loop from scratch in Python with Ollama and qwen3, no API key and no per-call cost, then learn when to move on to LangGraph.

Build an MCP Server in 15 Minutes with the TypeScript SDK

Stand up a working Model Context Protocol server, expose tools your agent can call, hook it into Claude Code or your own client, and learn the one mistake that breaks every stdio server.

Fine-Tune a Local LLM with Unsloth and Serve It with Ollama

A hands-on pipeline to adapt a 7B model to your domain: build a small dataset, train with QLoRA on a single GPU in Unsloth, and serve the result locally through Ollama.

Build a Private Local RAG Pipeline with Ollama + pgvector

Every RAG tutorial sends your documents to an API provider. This one keeps embeddings, vector search, and the LLM on your own machine with Ollama and pgvector. Two open source tools, zero API keys, runs on a laptop.

Qdrant: Vector Database Setup, Semantic Search, and Hybrid Queries

Hands-on guide to running Qdrant with Docker and building semantic search in Python: collections, payload filters, named vectors, and hybrid search with RRF. Plus a straight answer on when to pick Qdrant over Chroma or pgvector.

Build Your First MCP Server in Python

A copy-paste tutorial using the MCP Python SDK v2: expose tools, resources, and prompts, test with the Inspector, register with a host, and serve over HTTP. Every command verified against the official docs.

Build Your First MCP Server with Python

A hands-on tutorial using the current MCP Python SDK (v2). You will build a weather server, test it with an in-memory client, connect over stdio, and wire it into a real host like Claude Desktop.

Test Your AI Agent with pytest: An Eval Harness That Runs in CI

Chat demos do not catch the day your agent starts refunding orders it never looked up. Here is a pytest eval harness you can build in 30 minutes: golden dataset, deterministic tool-call checks, an LLM-as-judge for open-ended replies, and a CI gate.

Read-Only SQL for AI Agents: Four Guardrails That Hold

A system prompt that says "never delete anything" is a suggestion, not a permission system. Here is what holds: a locked Postgres role, a read-only transaction, a row cap, and a timeout. Full MCP server code, tested on PostgreSQL 18.

Fix Ollama's Context Length Before Your Local Agent Starts Forgetting

Ollama allocates context based on VRAM, not on what the model was trained for. Measure the real allocation, pin it per model, quantize the KV cache, and check every change with token per second numbers from your own machine.

Build a Local RAG Chatbot with Ollama and Chroma

A private, offline retrieval-augmented generation chatbot that answers from your own documents. Copy-paste setup with Ollama for the models and Chroma for the vector store, no cloud API keys.

Structured Outputs: Stop Parsing Broken LLM JSON

Prompting for JSON is not the same as getting JSON. A copy-paste guide to OpenAI and Anthropic structured outputs with Pydantic: raw JSON Schema, refusal handling, schema limits, and a full invoice extractor.

Give Your AI Agent a Durable Human Approval Gate

A crash-proof approval gate for destructive agent actions, built with Temporal Workflows, Signals, and a timeout that fails closed. Every command tested.

MCP Sampling Is Deprecated: Migrate Your LLM-Borrowing Tools

Sampling is deprecated and its back-channel is gone in MCP 2026-07-28. Migrate step by step: call the provider directly, borrow the caller model through InputRequiredResult, or pin v1 while clients catch up.

Build Your First MCP Server in TypeScript

Build a working MCP server in TypeScript with the official SDK. Register a typed tool, test it with the MCP Inspector, and connect it to Claude Desktop, in four steps.

Semantic Search with Chroma: Retrieval Patterns That Actually Work

Hands-on semantic search with Chroma: real queries, metadata filters, full-text search, persistence, and a retrieval pipeline for RAG. Every snippet run for real, with the exact output printed.

Give Your AI Agent Web Search With a Self-Hosted SearXNG

Run SearXNG in Docker, enable its JSON API, and wire it into an agent as a tool. Working config, a tested Python client, and the failure modes that actually bite.

Prompt Caching in Production: Cut LLM Input Costs by Up to 90%

A hands-on guide to the cache_control marker on Anthropic, automatic caching on OpenAI, and explicit caching on Gemini. Includes the cost formula and the breakpoint mistakes that silently kill your cache hits.

Build Your First MCP Server in Python

A hands-on tutorial: build a small system-info MCP server in Python, test it in the MCP Inspector, and wire it into Claude Desktop. Includes copy-paste code and real commands.

Build Your Own MCP Server in Python

MCP lets Claude Desktop, Cursor, and other AI hosts use your tools without custom glue. Build a real weather server with the v2 Python SDK, test it in memory, over stdio, and over HTTP, then wire it into a host. Every snippet verified against mcp 2.0.0.

Lock Down Your Remote MCP Server with OAuth 2.1

A remote MCP server that accepts one static API key hands the same key to every client. Here is how to turn it into a real OAuth 2.1 resource server: publish Protected Resource Metadata, validate token audience, split scopes, and stop token passthrough. Working FastMCP code plus the raw HTTP shapes.

Stream LLM Responses Token by Token with Server-Sent Events

A working end-to-end setup that replaces the dead spinner with a live stream: a FastAPI backend that pushes OpenAI-compatible tokens over SSE, and a browser client that renders them as they arrive.

Build Your First MCP Server in 10 Minutes with the Python SDK

One standard way to hand an LLM tools, resources, and reusable prompts. Build a real MCP server with the official Python SDK, test it in the Inspector, and connect it to a host. Copy-paste ready.