<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andrew Barnes</title>
    <description>The latest articles on Forem by Andrew Barnes (@bortlesboat).</description>
    <link>https://forem.com/bortlesboat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3811087%2F1895b112-6ae9-4e20-b060-e83c7a100972.jpeg</url>
      <title>Forem: Andrew Barnes</title>
      <link>https://forem.com/bortlesboat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bortlesboat"/>
    <language>en</language>
    <item>
      <title>Contributing to the Agent Infrastructure Stack: 4 PRs Across 3 Repos in One Weekend</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Fri, 27 Mar 2026 00:32:25 +0000</pubDate>
      <link>https://forem.com/bortlesboat/contributing-to-the-agent-infrastructure-stack-4-prs-across-3-repos-in-one-weekend-g69</link>
      <guid>https://forem.com/bortlesboat/contributing-to-the-agent-infrastructure-stack-4-prs-across-3-repos-in-one-weekend-g69</guid>
      <description>&lt;h1&gt;
  
  
  Contributing to the Agent Infrastructure Stack: 4 PRs Across 3 Repos in One Weekend
&lt;/h1&gt;

&lt;p&gt;Most open source contributions exist in isolation. You fix a bug here, add a feature there. But occasionally you get the chance to contribute across an entire ecosystem in a way where each PR reinforces the others. That's what happened when I spent a weekend contributing to three projects in the MCP agent infrastructure stack -- and in the process, made Bitcoin a first-class citizen across all of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;Three projects, three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;agentregistry&lt;/strong&gt; -- the discovery layer where developers find and install MCP servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;agentgateway&lt;/strong&gt; -- the proxy layer that adds rate limiting, auth, and observability to MCP servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;kagent&lt;/strong&gt; -- the Kubernetes orchestration layer that deploys AI agents with tool access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each project solves a different problem, but together they form the infrastructure that makes MCP servers useful in production. My goal was simple: contribute meaningful work to each layer, using bitcoin-mcp (my own MCP server with 40+ Bitcoin network tools) as the connecting thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR 1: Fixing a CLI Crash in agentregistry
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; Running &lt;code&gt;arctl skill list --page-size -1&lt;/code&gt; crashed the entire CLI with a Go slice bounds panic. Issue #368 had been open, waiting for someone to pick it up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The investigation:&lt;/strong&gt; The &lt;code&gt;--page-size&lt;/code&gt; flag value was being passed directly to slice operations without any validation. In Go, creating a slice with negative bounds causes a runtime panic -- no graceful error, no recovery, just a stack trace dumped to the terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; I added input validation at the command level, before the value ever reaches slice operations. If you pass a negative page-size now, you get a clear error message telling you the value must be positive. Simple, defensive, and exactly what you'd expect from a well-behaved CLI tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; agentregistry's CLI is built with Cobra, and the validation pattern I used follows the same approach used elsewhere in the codebase. Reading the existing code before writing new code always pays off.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR 2: Fixing the Broken Lint Target in agentregistry
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; &lt;code&gt;make lint&lt;/code&gt; had been broken since PR #253 removed &lt;code&gt;golangci-lint&lt;/code&gt; from the Go tools list. The Makefile still tried to invoke it via &lt;code&gt;go install&lt;/code&gt;, which no longer worked. Issue #377 documented the failure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The investigation:&lt;/strong&gt; The root cause was a dependency change that wasn't fully propagated. When golangci-lint was removed from the project's Go tool management, the Makefile target that depended on it wasn't updated. This is a classic problem in projects with multiple build system entry points.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt; Updated the lint target to use the system-installed &lt;code&gt;golangci-lint&lt;/code&gt; binary directly, with a clear error message if it's missing. The error message includes the official installation command so contributors can get unblocked immediately. This aligns with golangci-lint's own documentation, which recommends against &lt;code&gt;go install&lt;/code&gt; for linter binaries due to version management issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Broken CI/linting targets are a silent contributor barrier. People clone the repo, try to run &lt;code&gt;make lint&lt;/code&gt; before submitting a PR, it fails, and they either skip linting or give up on contributing. Fixing developer experience issues has outsized impact relative to the size of the diff.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR 3: Bitcoin ToolServer + SRE Agent for kagent
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; kagent had great examples for web and cloud tools, but nothing for blockchain infrastructure. Bitcoin node operators running Kubernetes had no way to deploy an AI agent that could monitor their infrastructure using real blockchain data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; I added two files to kagent's contrib directory:&lt;/p&gt;

&lt;p&gt;First, a &lt;code&gt;bitcoin-mcp&lt;/code&gt; ToolServer definition (&lt;code&gt;contrib/tools/bitcoin-mcp.yaml&lt;/code&gt;) following the established pattern used by other community tools like context7. This tells kagent how to connect to bitcoin-mcp as a tool provider.&lt;/p&gt;

&lt;p&gt;Second, a Bitcoin SRE Agent (&lt;code&gt;contrib/agents/bitcoin-sre.yaml&lt;/code&gt;) with a detailed system prompt that encodes actual operational knowledge. The agent knows how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor block production intervals and alert on delays&lt;/li&gt;
&lt;li&gt;Analyze mempool congestion and recommend fee strategies&lt;/li&gt;
&lt;li&gt;Triage fee spikes by examining mempool composition&lt;/li&gt;
&lt;li&gt;Detect and assess chain reorganizations&lt;/li&gt;
&lt;li&gt;Correlate network issues with hashrate changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't a generic "Bitcoin helper" -- it's a runbook encoded as an agent prompt, written by someone who actually operates Bitcoin infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; kagent's YAML-based agent definition is remarkably clean. The separation between tool definitions and agent prompts means you can iterate on the operational knowledge independently from the infrastructure config. I structured the bitcoin-mcp tool definition to match context7.mcp.yaml exactly, which made the PR easy to review because it followed an established pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR 4: Bitcoin Example with Rate Limiting for agentgateway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; agentgateway had examples for generic MCP servers but nothing demonstrating a real-world use case with production concerns like rate limiting and CORS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; I added &lt;code&gt;examples/bitcoin/&lt;/code&gt; with a complete configuration that proxies bitcoin-mcp through agentgateway. The example demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting (10 requests per minute by default) to protect the upstream API&lt;/li&gt;
&lt;li&gt;CORS configuration for browser-based MCP clients&lt;/li&gt;
&lt;li&gt;Zero additional configuration -- bitcoin-mcp's free hosted Satoshi API works out of the box, so anyone can run the example immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The README walks through setup, configuration, and common queries so developers can see agentgateway's value proposition in action: add security, observability, and traffic management to any MCP server without modifying the server itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; agentgateway's configuration model is well-designed for exactly this kind of layered concern. You define listeners, targets, and policies independently, which means you can swap out the upstream MCP server without changing your security configuration. The Bitcoin example makes this concrete in a way that a generic "hello world" example can't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Connecting Theme
&lt;/h2&gt;

&lt;p&gt;These four PRs aren't just four independent contributions -- they tell a story about what it means to make a protocol implementation production-ready.&lt;/p&gt;

&lt;p&gt;Having an MCP server (bitcoin-mcp) is step one. But to be useful in production, that server needs to be discoverable (agentregistry), securable (agentgateway), and deployable (kagent). By contributing to all three layers, Bitcoin becomes a reference implementation that demonstrates the full stack working together.&lt;/p&gt;

&lt;p&gt;The two bug fixes in agentregistry matter too. They lower the barrier for other contributors who might want to add their own MCP servers to the registry. A CLI that doesn't crash and a lint target that actually works are prerequisites for a healthy contributor experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;All four PRs are submitted and under review. Regardless of whether they merge on the hackathon timeline, the work demonstrates something I believe strongly: the best way to contribute to an ecosystem is to use it for something real. Bitcoin infrastructure monitoring is not a toy example. It involves real operational concerns, real data, and real users. That's what makes these contributions worth reviewing.&lt;/p&gt;

&lt;p&gt;If you're building MCP servers and want to see how the infrastructure stack fits together, check out the PRs linked in the README. And if you're running Bitcoin infrastructure on Kubernetes, the kagent Bitcoin SRE agent might be exactly what you need.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Andy Barnes is the creator of &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt;, an MCP server providing 40+ tools for querying and analyzing the Bitcoin network. Find him on GitHub at &lt;a href="https://github.com/Bortlesboat" rel="noopener noreferrer"&gt;@Bortlesboat&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>mcp</category>
      <category>bitcoin</category>
      <category>agents</category>
    </item>
    <item>
      <title>Building a Bitcoin SRE Agent: Incident Response Meets AI</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Fri, 27 Mar 2026 00:28:51 +0000</pubDate>
      <link>https://forem.com/bortlesboat/building-a-bitcoin-sre-agent-incident-response-meets-ai-2dag</link>
      <guid>https://forem.com/bortlesboat/building-a-bitcoin-sre-agent-incident-response-meets-ai-2dag</guid>
      <description>&lt;h1&gt;
  
  
  Building a Bitcoin SRE Agent: Incident Response Meets AI
&lt;/h1&gt;

&lt;p&gt;What if your Bitcoin node had an AI SRE on call 24/7?&lt;/p&gt;

&lt;p&gt;Not a chatbot that answers "what is Bitcoin?" -- an actual site reliability engineer that detects fee spikes at 3am, investigates mempool floods, diagnoses root causes, and tells you exactly what to do. One that follows the same incident response protocol your best on-call engineer follows, except it never sleeps and never forgets a runbook.&lt;/p&gt;

&lt;p&gt;That's what I built for the MCP &amp;amp; AI Agents Hackathon. Here's how.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Bitcoin Monitoring Today
&lt;/h2&gt;

&lt;p&gt;Running Bitcoin infrastructure is operationally demanding. A node operator deals with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fee volatility&lt;/strong&gt;: Fees can jump 10x in minutes during inscription mints or exchange consolidations. Send a transaction at the wrong time and you overpay by $50. Wait too long and your payment doesn't confirm for hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mempool floods&lt;/strong&gt;: 200,000+ unconfirmed transactions pile up, memory usage spikes, and your node starts evicting low-fee transactions. You need to know if this is transient or sustained.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mining anomalies&lt;/strong&gt;: A major pool goes offline, hashrate drops 15%, block times stretch to 25 minutes. Is this a temporary outage or something to worry about?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node health&lt;/strong&gt;: Your node falls behind, loses peers, or runs low on disk. By the time Grafana pages you, you've already missed blocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The standard response is a wall of dashboards, static alert thresholds, and a runbook wiki page that was last updated six months ago. The operator wakes up, SSHs in, runs commands, cross-references block explorers, and makes a judgment call. This process is slow, error-prone, and doesn't scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: An AI Agent That Follows SRE Protocol
&lt;/h2&gt;

&lt;p&gt;The Bitcoin SRE Agent replaces the runbook with an AI agent that follows a structured four-phase incident response protocol:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DETECT&lt;/strong&gt; -- Compare current state against baseline thresholds. Is this fee rate 3x the 7-day average? Are there more than 100K unconfirmed transactions? Has it been 20+ minutes since the last block?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INVESTIGATE&lt;/strong&gt; -- Gather context. If fees spiked, check the mempool composition. Are inscription transactions dominating? Is block production normal? What does the next block template look like?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DIAGNOSE&lt;/strong&gt; -- Correlate signals. Fee spike + mempool flood + inscription surge = Ordinals mint event. Fee spike + normal mempool = estimation overshoot. Slow blocks + hashrate drop = mining pool outage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RECOMMEND&lt;/strong&gt; -- Produce actionable guidance. "Wait 2 hours, fees should normalize. Use 15 sat/vB if time-sensitive. No escalation needed." Or: "CRITICAL -- fees above 500 sat/vB sustained for 3 blocks. Alert the team."&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Three Sponsor Projects Working Together
&lt;/h2&gt;

&lt;p&gt;The agent uses all three hackathon sponsor projects, each in its natural role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agentregistry (discover bitcoin-mcp)
    |
    v
agentgateway (rate limit + OTEL traces)
    |
    v
kagent ToolServer (bitcoin-mcp, 49 tools)
    |
    v
kagent Agent CRD (Bitcoin SRE Agent)
    |
    v
Incident Response Loop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;kagent&lt;/strong&gt; provides the orchestration layer. The &lt;code&gt;ToolServer&lt;/code&gt; CRD wraps &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt; -- my MCP server with 49 tools for querying the Bitcoin network. The &lt;code&gt;Agent&lt;/code&gt; CRD defines the SRE agent itself, including a 500+ word system prompt that encodes the full incident response protocol, detection thresholds, diagnostic patterns, and safety rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;agentgateway&lt;/strong&gt; sits in front of bitcoin-mcp, enforcing rate limits (60 req/min to prevent runaway investigation loops) and exporting OpenTelemetry traces to Jaeger. After an incident, you can replay every tool call the agent made -- complete forensics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;agentregistry&lt;/strong&gt; publishes bitcoin-mcp so other agents and operators can discover it. The registry entry describes all 49 tools across 9 categories, making it composable into other agent workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo: A Fee Spike at 3am
&lt;/h2&gt;

&lt;p&gt;Here's what happens when you run the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== Bitcoin SRE Agent -- Incident Response Demo ===

[1/4] NODE HEALTH CHECK
  Block Height:    889,241
  Sync Status:     GREEN -- SYNCED (height 889,241)
  Network:         main

[2/4] FEE ENVIRONMENT
  Assessment:      YELLOW -- Elevated (28.0 sat/vB)
  Recommendation:  Non-urgent txs should wait. Use 17 sat/vB if time-sensitive.

[3/4] MEMPOOL ANALYSIS
  Assessment:      YELLOW -- Congested (67,234 txs, 245 MB)
  Recommendation:  Estimated clearing time: ~3 hours at current hashrate.

[4/4] SITUATION REPORT
  Overall Status:  YELLOW
  Diagnosis:       Fee spike correlated with mempool congestion.
                   Likely organic demand surge or inscription event.
  Recommendation:  Non-urgent transactions should wait.
                   Monitor for resolution over next 1-3 hours.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent called three bitcoin-mcp tools (&lt;code&gt;get_blockchain_info&lt;/code&gt;, &lt;code&gt;get_fee_estimates&lt;/code&gt;, &lt;code&gt;get_mempool_info&lt;/code&gt;), analyzed the results against its built-in thresholds, correlated the signals, and produced a structured situation report. No dashboards, no manual investigation, no runbook lookups.&lt;/p&gt;

&lt;h2&gt;
  
  
  The System Prompt: Encoding Operator Knowledge
&lt;/h2&gt;

&lt;p&gt;The most interesting part of this project isn't the code -- it's the system prompt in the kagent Agent CRD. It encodes years of operator knowledge into structured rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fee interpretation&lt;/strong&gt;: Normal is 1-10 sat/vB. Elevated is 10-50. High is 50-200. Crisis is 200+.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnostic patterns&lt;/strong&gt;: Fee spike + mempool flood + inscriptions = mint event. Fee spike + normal mempool = estimation overshoot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety rules&lt;/strong&gt;: Never broadcast a transaction without explicit approval. Never make financial recommendations. Always caveat uncertainty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalation criteria&lt;/strong&gt;: Alert humans when peers drop below 2, node falls 100+ blocks behind, or fees exceed 500 sat/vB for 3+ blocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the key insight: &lt;strong&gt;the agent's intelligence comes from the prompt, not the code.&lt;/strong&gt; The code just calls tools and formats output. The prompt makes it an SRE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Pattern Matters Beyond Bitcoin
&lt;/h2&gt;

&lt;p&gt;The architecture -- domain MCP server + kagent orchestration + agentgateway security -- isn't Bitcoin-specific. It's a template for any infrastructure SRE agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database SRE&lt;/strong&gt;: Wrap &lt;code&gt;pg_stat_statements&lt;/code&gt; as MCP tools. Detect slow queries, recommend index changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes SRE&lt;/strong&gt;: Wrap &lt;code&gt;kubectl&lt;/code&gt; as MCP tools. Detect crash loops, recommend resource adjustments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network SRE&lt;/strong&gt;: Wrap SNMP/NetFlow as MCP tools. Detect anomalous traffic, recommend firewall rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern is always the same: domain tools (MCP server) + structured reasoning (agent prompt) + guardrails (gateway) + discoverability (registry). kagent makes the agent Kubernetes-native. agentgateway makes it production-safe. agentregistry makes it composable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone and run the demo&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;bitcoin-mcp
python demo.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Bitcoin node required -- bitcoin-mcp falls back to the free Satoshi API automatically. The demo connects, runs a health check, analyzes fees and mempool, and produces a situation report in about 10 seconds.&lt;/p&gt;

&lt;p&gt;For the full stack with agentgateway and Jaeger tracing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
python demo.py &lt;span class="nt"&gt;--gateway&lt;/span&gt;
&lt;span class="c"&gt;# Open http://localhost:16686 to see traces in Jaeger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All code, CRDs, and configs are in the &lt;a href="https://github.com/Bortlesboat/hackathon-mcp/tree/main/submissions/agents" rel="noopener noreferrer"&gt;&lt;code&gt;submissions/agents/&lt;/code&gt;&lt;/a&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This is a proof of concept, but the path to production is clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled execution&lt;/strong&gt;: Run the health check on a cron (every 15 minutes via kagent). Alert on severity changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Historical baselines&lt;/strong&gt;: Store past readings and compare against rolling averages instead of static thresholds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-node&lt;/strong&gt;: Monitor a fleet of Bitcoin nodes, not just one. The ToolServer CRD supports multiple instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated remediation&lt;/strong&gt;: For safe operations (restart a stuck node, add peers), let the agent act without human approval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A composition&lt;/strong&gt;: Other agents can delegate to the Bitcoin SRE agent via kagent's A2A protocol. A general infrastructure agent could ask "is Bitcoin healthy?" and get a structured response.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The future of infrastructure operations isn't more dashboards. It's agents that understand your systems, follow your runbooks, and wake you up only when they need to.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://mcphackathon.dev" rel="noopener noreferrer"&gt;MCP &amp;amp; AI Agents Hackathon&lt;/a&gt; -- Building Cool Agents category.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tools: &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt; | &lt;a href="https://kagent.dev" rel="noopener noreferrer"&gt;kagent&lt;/a&gt; | &lt;a href="https://agentgateway.dev" rel="noopener noreferrer"&gt;agentgateway&lt;/a&gt; | &lt;a href="https://agentregistry.dev" rel="noopener noreferrer"&gt;agentregistry&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>bitcoin</category>
      <category>kubernetes</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built My First AI Agent That Understands Bitcoin -- Here's How</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Thu, 26 Mar 2026 23:59:38 +0000</pubDate>
      <link>https://forem.com/bortlesboat/i-built-my-first-ai-agent-that-understands-bitcoin-heres-how-4aoj</link>
      <guid>https://forem.com/bortlesboat/i-built-my-first-ai-agent-that-understands-bitcoin-heres-how-4aoj</guid>
      <description>&lt;h1&gt;
  
  
  I Built My First AI Agent That Understands Bitcoin -- Here's How
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;A beginner's guide to MCP, agentgateway, and bitcoin-mcp&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I wanted to build an AI agent that could answer questions about Bitcoin. Not from a static FAQ -- I mean real-time data. Current block height. Mempool congestion. Fee estimates. Mining stats.&lt;/p&gt;

&lt;p&gt;I figured this would take days of API wrangling, authentication headaches, and custom plumbing. It took 10 minutes.&lt;/p&gt;

&lt;p&gt;Here's what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;AI models are smart, but they're stuck in the past. Ask Claude or GPT about the current Bitcoin block height and you'll get a polite "I don't have access to real-time data." Fair enough -- but what if you could give them that access?&lt;/p&gt;

&lt;p&gt;That's what MCP does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; is an open standard that lets AI models call external tools. Think of it like USB for AI: a universal plug that connects any AI client to any data source. An MCP &lt;em&gt;server&lt;/em&gt; exposes tools (like "get the current Bitcoin block height"). An MCP &lt;em&gt;client&lt;/em&gt; (like Claude Desktop or a custom script) calls those tools. The AI model decides which tools to call based on your question.&lt;/p&gt;

&lt;p&gt;The beauty is separation of concerns. The Bitcoin logic lives in the MCP server. The AI logic lives in the client. They speak the same protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is agentgateway?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;agentgateway&lt;/strong&gt; is a lightweight proxy that sits between your AI client and your MCP servers. Why do you need a proxy? A few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Protocol translation&lt;/strong&gt; -- it can bridge different MCP transports (stdio, SSE, Streamable HTTP)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing&lt;/strong&gt; -- it can fan out to multiple MCP servers from a single endpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; -- it's where you'd add authentication, rate limiting, and audit logging in production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our purposes, it gives us a clean HTTP endpoint that any MCP client can connect to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;Here's what we're building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Client  ---&amp;gt;  agentgateway (port 3000)  ---&amp;gt;  bitcoin-mcp (port 8000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three components. Two commands to start. One config file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Build It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install bitcoin-mcp
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bitcoin-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire Bitcoin integration. bitcoin-mcp ships with 49 tools for querying the Bitcoin network, and it works out of the box -- no API keys, no local node required. It connects to the free Satoshi API by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Start bitcoin-mcp
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bitcoin-mcp &lt;span class="nt"&gt;--transport&lt;/span&gt; sse &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts an MCP server on port 8000 using Server-Sent Events transport. Leave this terminal running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Get agentgateway
&lt;/h3&gt;

&lt;p&gt;Download the binary from the &lt;a href="https://github.com/agentgateway/agentgateway/releases" rel="noopener noreferrer"&gt;agentgateway releases page&lt;/a&gt; for your platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Create the Config
&lt;/h3&gt;

&lt;p&gt;Save this as &lt;code&gt;config-sse.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;binds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3000&lt;/span&gt;
  &lt;span class="na"&gt;listeners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;allowOrigins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;allowHeaders&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
          &lt;span class="na"&gt;exposeHeaders&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mcp-Session-Id"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;backends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mcp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bitcoin-mcp&lt;/span&gt;
            &lt;span class="na"&gt;sse&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8000/sse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells agentgateway to listen on port 3000 and forward everything to bitcoin-mcp.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Start agentgateway
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./agentgateway &lt;span class="nt"&gt;-f&lt;/span&gt; config-sse.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Connect
&lt;/h3&gt;

&lt;p&gt;Open &lt;a href="https://github.com/modelcontextprotocol/inspector" rel="noopener noreferrer"&gt;MCP Inspector&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @modelcontextprotocol/inspector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the transport to &lt;strong&gt;Streamable HTTP&lt;/strong&gt;, enter &lt;code&gt;http://localhost:3000&lt;/code&gt;, and click Connect.&lt;/p&gt;

&lt;p&gt;Go to the Tools tab. You'll see 49 tools. Click &lt;code&gt;get_situation_summary&lt;/code&gt; and hit Call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Aha" Moment
&lt;/h2&gt;

&lt;p&gt;When I called &lt;code&gt;get_situation_summary&lt;/code&gt; for the first time, I got back a wall of structured data: block height, hashrate, difficulty adjustment progress, mempool size, fee tiers, mining pool distribution. Real data. Live from the Bitcoin network.&lt;/p&gt;

&lt;p&gt;I didn't write any Bitcoin code. I didn't parse any APIs. I didn't handle any authentication. I installed an MCP server, pointed a proxy at it, and connected.&lt;/p&gt;

&lt;p&gt;That's when MCP clicked for me. The AI doesn't need to know how Bitcoin works. It just needs to know which tool to call. The MCP server handles everything else.&lt;/p&gt;

&lt;p&gt;I tried more tools. &lt;code&gt;get_fee_estimates&lt;/code&gt; told me exactly what fee to use for a transaction right now. &lt;code&gt;analyze_mempool&lt;/code&gt; showed me the current congestion. &lt;code&gt;get_mining_info&lt;/code&gt; gave me hashrate and difficulty data. Each one returned structured, accurate, real-time data.&lt;/p&gt;

&lt;p&gt;Then I connected it to Claude Desktop (just a one-line config change) and asked in natural language: "What's the current state of the Bitcoin mempool?" Claude called the right tools automatically and gave me a clear, conversational summary backed by live data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP is simpler than I expected.&lt;/strong&gt; I kept looking for the catch -- the complex authentication step, the mandatory configuration file with 200 options, the thing that would take an hour to debug. It wasn't there. The protocol is genuinely simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;agentgateway solves real problems.&lt;/strong&gt; Without it, you'd need every AI client to support every MCP transport. With it, you expose one HTTP endpoint and route to any backend. It's the missing piece between "I have an MCP server" and "any client can use it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tool ecosystem is the killer feature.&lt;/strong&gt; bitcoin-mcp alone has 49 tools. Imagine stacking multiple MCP servers -- weather, databases, APIs, Bitcoin -- all accessible through one gateway. That's where this gets powerful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separation of concerns matters.&lt;/strong&gt; The AI model picks which tools to call. The MCP server implements the tools. The gateway handles routing and security. Each piece does one thing well.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This starter example runs everything locally with no authentication. For production, you'd want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; -- agentgateway supports JWT validation and API keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; -- prevent abuse&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit logging&lt;/strong&gt; -- track what tools are being called and by whom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm also looking into publishing bitcoin-mcp to an MCP registry so anyone can discover and use it without knowing the GitHub URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The full code is in the &lt;a href="https://github.com/Bortlesboat/hackathon-mcp/tree/main/submissions/starter" rel="noopener noreferrer"&gt;hackathon repo&lt;/a&gt;. Clone it, follow the README, and you'll have a working Bitcoin AI agent in 10 minutes.&lt;/p&gt;

&lt;p&gt;If you've been curious about MCP but haven't tried it yet -- this is your on-ramp. The barrier is genuinely low, and the payoff is seeing an AI agent answer questions with real-time data for the first time.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt;, &lt;a href="https://github.com/agentgateway/agentgateway" rel="noopener noreferrer"&gt;agentgateway&lt;/a&gt;, and an unreasonable enthusiasm for Bitcoin tooling.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>bitcoin</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Securing AI Access to Financial Data: How We Govern Bitcoin MCP with agentgateway</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Thu, 26 Mar 2026 23:59:33 +0000</pubDate>
      <link>https://forem.com/bortlesboat/securing-ai-access-to-financial-data-how-we-govern-bitcoin-mcp-with-agentgateway-506n</link>
      <guid>https://forem.com/bortlesboat/securing-ai-access-to-financial-data-how-we-govern-bitcoin-mcp-with-agentgateway-506n</guid>
      <description>&lt;h1&gt;
  
  
  Securing AI Access to Financial Data: How We Govern Bitcoin MCP with agentgateway
&lt;/h1&gt;

&lt;p&gt;What happens when an AI agent has a tool called &lt;code&gt;send_raw_transaction&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;That's not a hypothetical. &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt; is a Model Context Protocol server that gives AI agents access to 49 tools for querying the Bitcoin network -- block analysis, fee estimation, mempool inspection, address lookups, transaction decoding, and yes, broadcasting signed transactions to the network.&lt;/p&gt;

&lt;p&gt;For a data analyst building a dashboard, these tools are a goldmine. For a production deployment without guardrails, they're an open door.&lt;/p&gt;

&lt;p&gt;We built &lt;strong&gt;Bitcoin Gateway Guard&lt;/strong&gt; to close that door and hand out keys only to the people who should have them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Threat Model
&lt;/h2&gt;

&lt;p&gt;AI agents are not users. They don't have judgment. They do exactly what their prompt says, and prompts can be injected, manipulated, or just poorly written. Consider what goes wrong when an AI agent has unrestricted access to Bitcoin tools:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accidental broadcast.&lt;/strong&gt; A developer testing transaction construction accidentally calls &lt;code&gt;send_raw_transaction&lt;/code&gt; instead of &lt;code&gt;decode_raw_transaction&lt;/code&gt;. The transaction is irreversible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt injection.&lt;/strong&gt; A malicious input tricks the agent into calling &lt;code&gt;generate_keypair&lt;/code&gt;, and the private key appears in a response that gets logged, cached, or displayed in a UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Runaway loops.&lt;/strong&gt; A bug in the agent's reasoning causes it to hammer the Bitcoin node with thousands of requests per minute, degrading service for everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shadow access.&lt;/strong&gt; Six months later, nobody can tell you which agents accessed what data, when, or why. Your compliance team is not happy.&lt;/p&gt;

&lt;p&gt;These are not exotic attacks. They are the predictable consequences of deploying AI agents on financial infrastructure without the same controls you'd apply to human users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four Layers of Defense
&lt;/h2&gt;

&lt;p&gt;Bitcoin Gateway Guard places &lt;a href="https://agentgateway.dev" rel="noopener noreferrer"&gt;agentgateway&lt;/a&gt; -- an open-source MCP security gateway built in Rust -- between AI agents and bitcoin-mcp. Every request passes through four independent security layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: JWT Authentication
&lt;/h3&gt;

&lt;p&gt;No anonymous access. Every request must carry a valid JWT signed with RS256. The gateway validates the signature, issuer (&lt;code&gt;bitcoin-gateway-guard&lt;/code&gt;), audience (&lt;code&gt;bitcoin-mcp&lt;/code&gt;), and expiration before the request touches any downstream logic.&lt;/p&gt;

&lt;p&gt;No token? HTTP 401. Expired token? HTTP 401. Wrong issuer? HTTP 401.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Role-Based Access Control
&lt;/h3&gt;

&lt;p&gt;We define two roles using CEL (Common Expression Language) expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;jwt.role&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"admin"&lt;/span&gt;
&lt;span class="n"&gt;jwt.role&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"reader"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;mcp.tool.name&lt;/span&gt; &lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"send_raw_transaction"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;mcp.tool.name&lt;/span&gt; &lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"generate_keypair"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;reader&lt;/code&gt; role gets access to 47 read-only tools -- everything you need for dashboards, analytics, research, and monitoring. The two tools that can modify state or create sensitive material -- &lt;code&gt;send_raw_transaction&lt;/code&gt; and &lt;code&gt;generate_keypair&lt;/code&gt; -- are reserved for &lt;code&gt;admin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a single line of policy. No code. No middleware. No if-else chains buried in application logic. The policy is auditable, declarative, and lives in a YAML config file that can be version-controlled and reviewed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: Rate Limiting
&lt;/h3&gt;

&lt;p&gt;A token bucket algorithm caps every consumer at 10 requests per minute with burst capacity of 10. This is deliberately conservative. A legitimate dashboard refresh needs one request every few seconds. An agent stuck in a loop will hit the limit in under a second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;localRateLimit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;maxTokens&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
    &lt;span class="na"&gt;tokensPerFill&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="na"&gt;fillInterval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;60s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rate limiting is the safety net that catches everything else. Even if authentication and authorization both pass, a runaway agent cannot overload your Bitcoin node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: Audit Trail
&lt;/h3&gt;

&lt;p&gt;Every tool invocation generates an OpenTelemetry span exported to Jaeger. Each span records the tool name, the JWT subject (who), the JWT role, the authorization decision (allowed or denied), the HTTP status, and the latency.&lt;/p&gt;

&lt;p&gt;Open Jaeger at &lt;code&gt;localhost:16686&lt;/code&gt;, select the &lt;code&gt;agentgateway&lt;/code&gt; service, and you have a complete, searchable, time-ordered record of every AI agent interaction with your Bitcoin data. Feed it into your SIEM, set up PagerDuty alerts on denied requests, run weekly access reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo
&lt;/h2&gt;

&lt;p&gt;Setup takes two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python scripts/generate_keys.py   &lt;span class="c"&gt;# Generate RSA keys + JWT tokens&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;               &lt;span class="c"&gt;# Start bitcoin-mcp + agentgateway + Jaeger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then test the security model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Reader queries block height -- works fine&lt;/span&gt;
python scripts/test_rbac.py &lt;span class="nt"&gt;--user&lt;/span&gt; reader &lt;span class="nt"&gt;--tool&lt;/span&gt; get_block_count
&lt;span class="c"&gt;# Result: ALLOWED&lt;/span&gt;

&lt;span class="c"&gt;# Reader tries to broadcast a transaction -- blocked&lt;/span&gt;
python scripts/test_rbac.py &lt;span class="nt"&gt;--user&lt;/span&gt; reader &lt;span class="nt"&gt;--tool&lt;/span&gt; send_raw_transaction
&lt;span class="c"&gt;# Result: DENIED (authorization)&lt;/span&gt;

&lt;span class="c"&gt;# Burst 15 requests -- rate limited after 10&lt;/span&gt;
python scripts/test_rbac.py &lt;span class="nt"&gt;--user&lt;/span&gt; reader &lt;span class="nt"&gt;--tool&lt;/span&gt; get_fee_estimates &lt;span class="nt"&gt;--burst&lt;/span&gt; 15
&lt;span class="c"&gt;# Summary: 10 allowed, 5 rate-limited&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every one of these interactions shows up in Jaeger with full context. The denied requests are flagged. The rate-limited requests are logged. Nothing is invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why agentgateway?
&lt;/h2&gt;

&lt;p&gt;We evaluated building custom middleware, wrapping bitcoin-mcp with authentication logic, and using a general-purpose API gateway. agentgateway won because it understands MCP natively.&lt;/p&gt;

&lt;p&gt;A generic API gateway can rate-limit HTTP requests and validate JWTs. But it cannot inspect MCP tool names, apply per-tool authorization rules, or trace MCP-specific context. agentgateway speaks the protocol. Its CEL-based authorization rules reference &lt;code&gt;mcp.tool.name&lt;/code&gt; directly. No regex on request bodies. No custom plugins. No fragile parsing.&lt;/p&gt;

&lt;p&gt;The configuration is 40 lines of YAML. The entire security policy -- authentication, authorization, rate limiting, and tracing -- is declared in a single file that a security engineer can review in five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;The AI industry is moving fast toward giving agents access to real-world systems. Financial data. Infrastructure controls. Business operations. The tools are getting more powerful. The guardrails are not keeping up.&lt;/p&gt;

&lt;p&gt;MCP is becoming the standard protocol for AI agent tool access. But MCP itself has no built-in security model. There's no authentication, no authorization, no rate limiting, and no audit trail in the protocol specification. That's by design -- MCP is a transport protocol, not a security framework.&lt;/p&gt;

&lt;p&gt;The security has to come from the deployment layer. And it has to be as easy to configure as the tools themselves, or teams will skip it.&lt;/p&gt;

&lt;p&gt;Bitcoin Gateway Guard demonstrates that you can add enterprise-grade security to any MCP server -- not just bitcoin-mcp -- with a single configuration file and zero code changes to the underlying server. The same pattern applies to database MCP servers, cloud infrastructure tools, payment APIs, or anything else you'd hesitate to give an AI agent unrestricted access to.&lt;/p&gt;

&lt;p&gt;The question is not whether AI agents should have access to financial tools. They should -- the productivity gains are real. The question is whether that access is governed with the same rigor we apply to human users.&lt;/p&gt;

&lt;p&gt;With agentgateway, the answer is yes. And you can prove it to your auditors.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Bitcoin Gateway Guard is open source. The full configuration, Docker setup, and test scripts are available at &lt;a href="https://github.com/Bortlesboat/bitcoin-gateway-guard" rel="noopener noreferrer"&gt;github.com/Bortlesboat/bitcoin-gateway-guard&lt;/a&gt;. Built with &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt; and &lt;a href="https://agentgateway.dev" rel="noopener noreferrer"&gt;agentgateway&lt;/a&gt; for the &lt;a href="https://aihackathon.dev" rel="noopener noreferrer"&gt;MCP &amp;amp; AI Agents Hackathon&lt;/a&gt; -- Secure &amp;amp; Govern MCP category.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>bitcoin</category>
      <category>devops</category>
    </item>
    <item>
      <title>From PyPI to Production: Publishing bitcoin-mcp to agentregistry</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Thu, 26 Mar 2026 23:59:26 +0000</pubDate>
      <link>https://forem.com/bortlesboat/from-pypi-to-production-publishing-bitcoin-mcp-to-agentregistry-3m9j</link>
      <guid>https://forem.com/bortlesboat/from-pypi-to-production-publishing-bitcoin-mcp-to-agentregistry-3m9j</guid>
      <description>&lt;h1&gt;
  
  
  From PyPI to Production: Publishing bitcoin-mcp to agentregistry
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;How we turned a 49-tool Bitcoin MCP server into a one-command deployment for any AI agent.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The MCP Server Discovery Problem
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol ecosystem is exploding. There are over 100 MCP servers on PyPI and npm right now, covering everything from GitHub to Slack to databases. But here is the uncomfortable truth: &lt;strong&gt;finding and deploying them is still painful.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The typical workflow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google "bitcoin mcp server"&lt;/li&gt;
&lt;li&gt;Find a GitHub repo (maybe)&lt;/li&gt;
&lt;li&gt;Read the README to figure out installation&lt;/li&gt;
&lt;li&gt;Determine the transport type (stdio? SSE? streamable HTTP?)&lt;/li&gt;
&lt;li&gt;Manually edit your IDE's MCP configuration file&lt;/li&gt;
&lt;li&gt;Restart your IDE and pray it connects&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is 2026. We send agents to browse the web and write code. We should not need 10 minutes of manual config to add a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter agentregistry
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://agentregistry.dev" rel="noopener noreferrer"&gt;agentregistry&lt;/a&gt; solves this by creating a centralized, searchable registry for MCP servers, skills, and agent blueprints. Think of it as npm for AI agents — you search, you install, you go.&lt;/p&gt;

&lt;p&gt;We decided to register &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt; as the first Bitcoin-focused entry. Here is how that went.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Registration Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What We Had
&lt;/h3&gt;

&lt;p&gt;bitcoin-mcp is a production MCP server for Bitcoin network analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;49 tools&lt;/strong&gt; for mempool analysis, fee estimation, block inspection, transaction decoding, mining insights, and market data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;116 tests&lt;/strong&gt; with full CI coverage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero configuration&lt;/strong&gt; — it auto-detects a local Bitcoin Core node or falls back to the free Satoshi API&lt;/li&gt;
&lt;li&gt;Already published on &lt;strong&gt;PyPI&lt;/strong&gt; as &lt;code&gt;bitcoin-mcp&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The server was ready. What it lacked was discoverability.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We Built
&lt;/h3&gt;

&lt;p&gt;Three pieces make up the agentregistry submission:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Server Registration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The straightforward part. We registered bitcoin-mcp as a PyPI-sourced server with stdio transport:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;arctl register server &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; bitcoin-mcp &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--source&lt;/span&gt; pypi &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--package&lt;/span&gt; bitcoin-mcp &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--transport&lt;/span&gt; stdio &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--command&lt;/span&gt; bitcoin-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;arctl search bitcoin&lt;/code&gt; finds it. &lt;code&gt;arctl install bitcoin-mcp&lt;/code&gt; installs it. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The Bitcoin Skill&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where it gets interesting. MCP servers give agents tools. But tools without context are like giving someone a stethoscope without medical school. They can press buttons, but they do not know what the results mean.&lt;/p&gt;

&lt;p&gt;We created a &lt;strong&gt;Bitcoin Intelligence Skill&lt;/strong&gt; — a structured knowledge document (&lt;code&gt;SKILL.md&lt;/code&gt;) that teaches the agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When to use &lt;code&gt;get_fee_estimates&lt;/code&gt; vs &lt;code&gt;estimate_smart_fee&lt;/code&gt; vs &lt;code&gt;get_fee_recommendation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to interpret mempool congestion (50 MB = congested, 100 MB = severely congested)&lt;/li&gt;
&lt;li&gt;Confirmation thresholds based on transaction value ($1K = 1 conf, $100K = 6+ conf)&lt;/li&gt;
&lt;li&gt;How to read mining pool rankings and difficulty adjustments&lt;/li&gt;
&lt;li&gt;Correlation patterns between on-chain data and market movements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The skill turns a generic tool-caller into a Bitcoin analyst.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The Agent Blueprint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;agent.yaml&lt;/code&gt; ties everything together into a single deployable unit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bitcoin-intelligence&lt;/span&gt;
&lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bitcoin-skill&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bitcoin-mcp&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pypi&lt;/span&gt;
    &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bitcoin-mcp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command deploys the complete package: &lt;code&gt;arctl deploy bitcoin-intelligence&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Demo
&lt;/h2&gt;

&lt;p&gt;Here is what one-command deployment looks like in practice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;arctl deploy bitcoin-intelligence
Installing bitcoin-mcp from PyPI... &lt;span class="k"&gt;done
&lt;/span&gt;Loading bitcoin-skill... &lt;span class="k"&gt;done
&lt;/span&gt;Configuring IDE... &lt;span class="k"&gt;done

&lt;/span&gt;Bitcoin Intelligence agent is ready.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in your AI assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt; "Should I send this Bitcoin transaction now or wait?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; &lt;em&gt;checks mempool (42MB, moderate congestion), gets fee estimates (12 sat/vB for next block), looks at recent block intervals (9.2 min average — slightly fast)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"The mempool is moderately congested at 42MB. Current next-block fee is 12 sat/vB (~$2.40 for a typical transaction). Blocks are coming slightly faster than average, so the mempool should clear over the next hour. If you can wait 30-60 minutes, you will likely see fees drop to 6-8 sat/vB. If it is urgent, 12 sat/vB will get you into the next block."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That response required three different tools, domain knowledge about fee interpretation, and an understanding of how block timing affects mempool dynamics. The skill makes this possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Skills are the missing layer.&lt;/strong&gt; Everyone talks about MCP tools, but domain knowledge is what separates a useful agent from a button-masher. The skill concept in agentregistry is underexplored and powerful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-config matters for registries.&lt;/strong&gt; bitcoin-mcp works without any API keys or node setup because it falls back to a hosted API. This is critical for registry deployments — if &lt;code&gt;arctl install&lt;/code&gt; requires a 10-step configuration guide, you have lost the whole point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent blueprints enable composition.&lt;/strong&gt; The &lt;code&gt;agent.yaml&lt;/code&gt; format lets you bundle servers and skills into opinionated packages. Imagine a "DeFi analyst" blueprint that combines bitcoin-mcp, an Ethereum MCP server, and a cross-chain skill. Registries make this composable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;arctl
arctl search bitcoin
arctl deploy bitcoin-intelligence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three commands. Zero to Bitcoin intelligence.&lt;/p&gt;

&lt;p&gt;The full source is at &lt;a href="https://github.com/Bortlesboat/hackathon-mcp/tree/main/submissions/registry" rel="noopener noreferrer"&gt;github.com/Bortlesboat/hackathon-mcp&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://mcphackathon.devpost.com/" rel="noopener noreferrer"&gt;MCP Hackathon&lt;/a&gt; — Explore Agent Registry category.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;bitcoin-mcp: &lt;a href="https://pypi.org/project/bitcoin-mcp/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt; | &lt;a href="https://github.com/Bortlesboat/bitcoin-mcp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;agentregistry: &lt;a href="https://agentregistry.dev" rel="noopener noreferrer"&gt;agentregistry.dev&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>bitcoin</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built a REST API for Bitcoin Core - Here's what I Learned</title>
      <dc:creator>Andrew Barnes</dc:creator>
      <pubDate>Sat, 07 Mar 2026 15:46:43 +0000</pubDate>
      <link>https://forem.com/bortlesboat/i-built-a-rest-api-for-bitcoin-core-heres-what-i-learned-4888</link>
      <guid>https://forem.com/bortlesboat/i-built-a-rest-api-for-bitcoin-core-heres-what-i-learned-4888</guid>
      <description>&lt;p&gt;I run a Bitcoin full node. When I started building apps against it, I hit the same wall everyone hits: Bitcoin Core's JSON-RPC is designed for node operators, not application developers.&lt;/p&gt;

&lt;p&gt;The RPC works. It's stable, well-documented, and battle-tested. But if you've ever tried to build a product on top of it, you know the pain points. So I spent a few months wrapping it in a proper REST API, and I learned some things worth sharing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Bitcoin Core's RPC returns fees in BTC/kVB. Every application developer on earth thinks in sat/vB. That's a multiplication, a unit conversion, and a mental model mismatch — on every single call.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;estimatesmartfee&lt;/code&gt; returns one estimate per call. Want fee recommendations for 1, 3, 6, and 144 blocks? That's four RPC round-trips, four response parses, and you still have to write the logic to tell your user "fees are moderate right now, you can wait."&lt;/p&gt;

&lt;p&gt;&lt;code&gt;getmempoolinfo&lt;/code&gt; gives you transaction count and total size. Useful, but what developers actually need is: "How congested is the mempool? What fee rate gets me into the next block? What does the fee distribution look like?"&lt;/p&gt;

&lt;p&gt;Raw RPC is a power tool. Most apps need a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://bitcoinsapi.com" rel="noopener noreferrer"&gt;Satoshi API&lt;/a&gt; is a thin REST layer over Bitcoin Core. &lt;code&gt;pip install&lt;/code&gt;, point at your node, get 40 clean endpoints with analyzed data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bitcoin-api
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BITCOIN_RPC_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_user
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;BITCOIN_RPC_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_password
bitcoin-api  &lt;span class="c"&gt;# http://localhost:9332/docs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the entire setup. Here's what the fee endpoint looks like versus calling &lt;code&gt;estimatesmartfee&lt;/code&gt; five times yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://bitcoinsapi.com/api/v1/fees/recommended
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"recommendation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fees are moderate. For next-block confirmation use 25 sat/vB. If you can wait 1 hour, 12 sat/vB should suffice."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"estimates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;25.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;18.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"6"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;12.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"25"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"144"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-05T12:00:00+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"node_height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;939462&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One call. Human-readable recommendation. All targets. Units already in sat/vB. The &lt;code&gt;meta&lt;/code&gt; envelope tells you exactly which chain and height this came from.&lt;/p&gt;

&lt;p&gt;But the interesting part isn't the API itself — it's the design decisions I had to make along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Analyzed Data &amp;gt; Raw Data
&lt;/h2&gt;

&lt;p&gt;The biggest ROI came from adding an analysis layer between the RPC and the REST response. Bitcoin Core gives you primitives. Apps need derived insights.&lt;/p&gt;

&lt;p&gt;The mempool endpoint is a good example. Raw &lt;code&gt;getmempoolinfo&lt;/code&gt; tells you there are 14,832 transactions using 7.5 MB. The analyzed endpoint tells you the mempool is at "medium" congestion, the minimum fee to make the next block is 8.2 sat/vB, and breaks down the fee distribution into buckets so you can visualize where your transaction would land.&lt;/p&gt;

&lt;p&gt;The transaction analysis endpoint detects SegWit, Taproot, and inscriptions automatically. Block analysis includes weight utilization percentage and a SegWit adoption ratio. None of this is hard to compute, but doing it once in the API layer saves every downstream consumer from reimplementing it.&lt;/p&gt;

&lt;p&gt;If you're wrapping any RPC-style backend in a REST API, consider what your consumers actually want to &lt;em&gt;know&lt;/em&gt;, not just what the backend &lt;em&gt;returns&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: Not All Blocks Are Created Equal
&lt;/h2&gt;

&lt;p&gt;This one bit me early. I added caching (obviously — you don't want to re-fetch block 500,000 every time someone asks for it). But blocks near the chain tip can be orphaned by a reorg. Cache a tip block for an hour and you might serve stale data after a reorg.&lt;/p&gt;

&lt;p&gt;The solution is depth-aware caching with two separate stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deep blocks&lt;/strong&gt; (6+ confirmations): 1-hour TTL. These are effectively immutable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tip blocks&lt;/strong&gt; (&amp;lt; 6 confirmations): 30-second TTL. Short enough to catch reorgs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable data&lt;/strong&gt; (fees, mempool): 5-10 second TTL. Always near-fresh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a block request comes in, the cache checks &lt;code&gt;tip_height - block_height&lt;/code&gt; to decide which store to use. Block 100,000 gets cached once and served for an hour. The latest block gets re-validated every 30 seconds. Fees refresh every 10 seconds.&lt;/p&gt;

&lt;p&gt;This pattern applies to any blockchain API. If you're caching chain data, you need to think about finality depth, not just time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: Rate Limit Your Own Node
&lt;/h2&gt;

&lt;p&gt;This sounds counterintuitive — why would you rate limit yourself? Because Bitcoin Core's RPC server is single-threaded. Flood it with concurrent requests from multiple apps and you'll block your own wallet operations.&lt;/p&gt;

&lt;p&gt;Satoshi API has four tiers (Anonymous at 30/min, Free at 100/min, Pro at 500/min, Enterprise at 2,000/min) with per-minute sliding windows in memory and daily limits backed by SQLite so they survive restarts. Even if you're the only user, the rate limiter prevents any single runaway script from starving your node.&lt;/p&gt;

&lt;p&gt;The per-minute window is in-memory for speed. Daily counters persist in SQLite (WAL mode, so reads don't block writes). Every response includes &lt;code&gt;X-RateLimit-Remaining&lt;/code&gt; headers so clients can self-throttle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 4: Response Envelopes Save Everyone's Time
&lt;/h2&gt;

&lt;p&gt;Every successful response returns &lt;code&gt;{ data, meta }&lt;/code&gt;. Every error returns &lt;code&gt;{ error: { status, title, detail, request_id } }&lt;/code&gt;. No exceptions.&lt;/p&gt;

&lt;p&gt;This seems trivial, but it eliminates an entire category of client-side bugs. You never have to guess whether the response is the data directly or wrapped in an object. You never parse a 200 response that's actually an error message. The &lt;code&gt;request_id&lt;/code&gt; (UUID on every response via header and body) makes debugging trivial — "this request failed" becomes "request &lt;code&gt;550e8400-...&lt;/code&gt; returned 404 with detail 'Transaction not found'."&lt;/p&gt;

&lt;p&gt;If you're building any API from scratch in 2026, standardize your envelope on day one. Retrofitting it later is painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Agent Angle
&lt;/h2&gt;

&lt;p&gt;This is the part I'm most excited about. The third layer of the stack is &lt;a href="https://bitcoinsapi.com/bitcoin-api-for-ai-agents" rel="noopener noreferrer"&gt;bitcoin-mcp&lt;/a&gt;, a Model Context Protocol server that lets AI agents query your node directly.&lt;/p&gt;

&lt;p&gt;Add this to your Claude Desktop config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bitcoin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uvx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"bitcoin-mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"BITCOIN_API_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9332"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can ask Claude: "What's the current mempool congestion?" or "Analyze the latest block" and it hits your node, gets structured JSON, and reasons over it. No third-party API. No privacy leakage.&lt;/p&gt;

&lt;p&gt;As far as I know, no other Bitcoin API has native AI agent support. The pipeline is three clean layers: &lt;code&gt;bitcoinlib-rpc&lt;/code&gt; (typed Python library) -&amp;gt; &lt;code&gt;satoshi-api&lt;/code&gt; (REST) -&amp;gt; &lt;code&gt;bitcoin-mcp&lt;/code&gt; (AI interface). Each layer has one job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-Hosting Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;When you use a hosted Bitcoin API, every address lookup, transaction query, and fee check is correlated with your IP. The API provider builds a profile of which addresses you care about. For a technology built on financial privacy, that's a significant tradeoff most developers don't think about.&lt;/p&gt;

&lt;p&gt;Self-hosting Satoshi API means your queries never leave your network. Your node, your data, your privacy. The three-line setup makes this practical, not just aspirational.&lt;/p&gt;

&lt;p&gt;There's also a &lt;a href="https://bitcoinsapi.com" rel="noopener noreferrer"&gt;free hosted tier&lt;/a&gt; if you want to prototype before running your own node — but for production, self-hosting is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The API currently covers blocks, transactions, mempool, fees, mining, and network info — everything Bitcoin Core exposes via RPC. The roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Address lookups&lt;/strong&gt; via Electrs/Fulcrum integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus metrics&lt;/strong&gt; endpoint for node monitoring dashboards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook notifications&lt;/strong&gt; for new blocks and mempool events&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live API + docs playground&lt;/strong&gt;: &lt;a href="https://bitcoinsapi.com/docs" rel="noopener noreferrer"&gt;bitcoinsapi.com/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Bortlesboat/bitcoin-api" rel="noopener noreferrer"&gt;github.com/Bortlesboat/bitcoin-api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyPI&lt;/strong&gt;: &lt;a href="https://pypi.org/project/satoshi-api/" rel="noopener noreferrer"&gt;pypi.org/project/satoshi-api/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison with other Bitcoin APIs&lt;/strong&gt;: &lt;a href="https://bitcoinsapi.com/best-bitcoin-api-for-developers" rel="noopener noreferrer"&gt;bitcoinsapi.com/best-bitcoin-api-for-developers&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed, 95 unit tests + 21 E2E tests, CI pipeline. If you run a node and want a clean API on top of it, I'd love feedback — open an issue or drop a comment below.&lt;/p&gt;

</description>
      <category>bitcoin</category>
      <category>api</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
