# Justin Poehnelt > Justin Poehnelt on software development, cloud infrastructure, AI agents, and ultra running. Founder and CTO at Helen's Foundry. - Markdown URLs are compact alternate representations for retrieval. Cite the canonical HTML URL included in each file. - Every post is available as Markdown at `/posts/.md` and as JSON at `/posts/.json`, alongside its canonical HTML page at `/posts//`. - Browse the [complete post archive](https://justin.poehnelt.com/posts/), the [XML sitemap](https://justin.poehnelt.com/sitemap.xml), or the [Atom feed](https://justin.poehnelt.com/feed/all.xml) for everything published on the site. - Use the [Google Apps Script guide](https://justin.poehnelt.com/google-apps-script/) for the curated Apps Script collection. - Learn [about Justin Poehnelt](https://justin.poehnelt.com/about/). ## AI agents and developer tooling - [You Need to Rewrite Your CLI for AI Agents](https://justin.poehnelt.com/posts/rewrite-your-cli-for-ai-agents.md): Human DX optimizes for discoverability. Agent DX optimizes for predictability. What I learned building a CLI for agents first. - [The MCP Abstraction Tax](https://justin.poehnelt.com/posts/mcp-abstraction-tax.md): Every layer from App to API to MCP loses fidelity. An exploration of what gets lost and why it matters for enterprise APIs. - [Your App Should Ship an MCP Server](https://justin.poehnelt.com/posts/ship-mcp-server-native-app.md): Why I embedded an MCP server in a native Rust prose editor so an AI agent can drive, inspect, rebuild, and verify the running app. - [Agent Identity for Git Commits](https://justin.poehnelt.com/posts/agent-identity-git-commits.md): How to configure AI agents to push commits to GitHub using a separate bot identity without modifying local git configuration. - [Protect Gmail AI Agents with Model Armor](https://justin.poehnelt.com/posts/building-secure-ai-agents-mcp.md): Use Model Armor in an MCP tool handler to block prompt injection and redact sensitive Gmail content before it reaches an AI agent. ## Google Apps Script - [UrlFetchApp: The Unofficial Documentation](https://justin.poehnelt.com/posts/definitive-guide-to-urlfetchapp.md): The unofficial guide to Google Apps Script UrlFetchApp. Master authentication, fetchAll for parallelism, web scraping, and debugging "Address Unavailable". - [Apps Script Storage Benchmarks](https://justin.poehnelt.com/posts/apps-script-key-value-stores.md): Benchmarks comparing CacheService, PropertiesService, and Firestore in Apps Script, including speed measurements and when each storage option fits. - [PostgreSQL from Google Apps Script](https://justin.poehnelt.com/posts/apps-script-postgresql.md): Connect Apps Script to PostgreSQL via JDBC, including connection strings, JSONB and UUID workarounds, transactions, and PostGIS. - [Using Gemini in Apps Script](https://justin.poehnelt.com/posts/using-gemini-in-apps-script.md): Use Apps Script's Vertex AI advanced service to call Gemini for text, images, structured output, search grounding, and multi-turn chat. - [Building a MCP Client in Google Apps Script](https://justin.poehnelt.com/posts/mcp-client-apps-script.md): Learn how to communicate with Model Context Protocol (MCP) servers using Apps Script and UrlFetchApp. Incorporate the MCP client into Vertex AI tool calling. ## Software engineering - [Optimized Dockerfile for Rust](https://justin.poehnelt.com/posts/rust-optimized-docker-file.md): A multi-stage Rust Dockerfile that caches dependencies with a dummy main.rs before copying source into a slim Debian runtime image. - [Cloudflare Workers: Dev, Staging, and Prod](https://justin.poehnelt.com/posts/cloudflare-workers-wrangler-dev-staging-prod.md): Configure Wrangler environments for Cloudflare Workers, then use GitHub Actions to deploy and promote changes through dev, staging, and production. - [Caching Playwright Binaries in GitHub Actions](https://justin.poehnelt.com/posts/caching-playwright-in-github-actions.md): A GitHub Actions caching strategy for Playwright browser binaries that reduces repeated downloads and speeds up browser-based CI runs. - [React Wrapper for Google Drive Picker](https://justin.poehnelt.com/posts/react-wrapper-google-drive-picker.md): Announcing the new React component for the Google Drive Picker, wrapping usage of the web component for easier integration. ## Ultrarunning - [2022 Mogollon Monster 100 Mile Race Report](https://justin.poehnelt.com/posts/2022-mogollon-monster-race-report.md): A 2022 Mogollon Monster 100 race report: I led early, battled ankle and calf injuries, exhaustion, and nausea, then finished 15th. - [Running and Chronic Exertional Compartment Syndrome](https://justin.poehnelt.com/posts/running-with-exertional-compartment-syndrome.md): Understanding and treating a new running injury, Chronic Exertional Compartment Syndrome. Can I run? Can I race? - [2026 Crazy Mountain 100](https://justin.poehnelt.com/posts/2026-crazy-mountain-100.md): I'm running the Crazy Mountain 100 in 2026! It's a rugged 100 miler in Montana that serves as a Hardrock qualifier. ## Optional - [Miko-bench: 65 AI Models Guess My Puppy's Breed Mix](https://justin.poehnelt.com/posts/miko-bench.md): I asked 65 vision models to rank Miko's likely breeds from the same evidence given to humans, then compared their guesses with her DNA results. - [My 2026 San Juan Softie 100 Race Plan](https://justin.poehnelt.com/posts/2026-san-juan-softie-race-plan.md): My 26-hour and 28-hour pacing plans, aid station splits, fueling, drop bags, lights, and weather strategy for the 2026 San Juan Softie 100. - [Triaging Gmail with Claude Subagents](https://justin.poehnelt.com/posts/triage-gmail-with-subagents.md): A writeup of a small agentic system I built to triage my Gmail inbox, using Claude subagents to organize and assess messages. - [Fiction AST and GLiNER NER in Rust](https://justin.poehnelt.com/posts/building-a-fiction-ast-training-ner-gliner-onnx.md): How I built a fiction-specific AST and named-entity pipeline with LLM labeling, GLiNER fine-tuning, and ONNX inference in Rust. - [VS Code Git Remote Color](https://justin.poehnelt.com/posts/vscode-git-remote-color.md): An open-source VS Code extension that hashes each workspace Git remote and colors the status bar to distinguish open repositories. - [Extracting Gold from Antigravity's Brain](https://justin.poehnelt.com/posts/extracting-gold-from-antigravitys-brain.md): A workflow for extracting architectural patterns and implementation challenges from AI agent walkthroughs to inform later engineering work. - [Abandon Git LFS because AI Agents](https://justin.poehnelt.com/posts/abandon-git-lfs-because-agents.md): Git LFS causes fatal errors in AI agents like Jules due to proxy conflicts and hook limitations. Learn why I abandoned LFS and migrated back to standard Git. - [Currentonly Scopes in Google Apps Script](https://justin.poehnelt.com/posts/apps-script-currentonly-scopes.md): How Apps Script currentonly scopes limit access to an active file, and why Advanced Services, direct API calls, and openById need full scopes. - [Resolve Chat User IDs to Emails: Least Privilege](https://justin.poehnelt.com/posts/resolving-google-chat-user-ids-to-emails.md): Securely resolve Google Chat User IDs to emails without Domain-Wide Delegation. Use Service Account Impersonation and custom Admin roles. - [Apps Script CacheService Limits](https://justin.poehnelt.com/posts/exploring-apps-script-cacheservice-limits.md): Unofficial Apps Script CacheService findings: key and value limits, FIFO batch eviction, edge cases, and practical cache patterns.