<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[faizan khan's blog]]></title><description><![CDATA[https://eff-kay.github.io]]></description><link>https://faizank.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png</url><title>faizan khan&apos;s blog</title><link>https://faizank.substack.com</link></image><generator>Substack</generator><lastBuildDate>Sun, 16 Aug 2026 02:37:56 GMT</lastBuildDate><atom:link href="https://faizank.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[faizan khan]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[faizan10114@gmail.com]]></webMaster><itunes:owner><itunes:email><![CDATA[faizan10114@gmail.com]]></itunes:email><itunes:name><![CDATA[eff-kay]]></itunes:name></itunes:owner><itunes:author><![CDATA[eff-kay]]></itunes:author><googleplay:owner><![CDATA[faizan10114@gmail.com]]></googleplay:owner><googleplay:email><![CDATA[faizan10114@gmail.com]]></googleplay:email><googleplay:author><![CDATA[eff-kay]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[How to Set Up a Remote MCP Server for Your SaaS]]></title><description><![CDATA[MCP is straightforward in theory and messy in practice. This guide covers what MCP is, why remote MCP matters for SaaS products, the main deployment options, and how to get to tokenless onboarding wit]]></description><link>https://faizank.substack.com/p/how-to-set-up-a-remote-mcp-server</link><guid isPermaLink="false">https://faizank.substack.com/p/how-to-set-up-a-remote-mcp-server</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Wed, 20 May 2026 22:05:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tIcc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p><strong>If you are building a SaaS product right now, there is a good chance users will eventually want Claude, Cursor, or another AI client to talk to it directly.</strong> MCP is the cleanest way to do that, but the interesting work starts after the tools are defined. The hard part is deciding how the server should be deployed, how authentication should work, and how much setup friction you are willing to push onto the user.</p><p>This guide is about that part. It explains what MCP is, why remote MCP matters for SaaS products, the different ways you can ship it, and what it takes to get to the version most teams actually want: a hosted integration where the user signs in and approves access instead of generating and pasting a token.</p><div><hr></div><h2>What MCP Actually Is</h2><p>MCP is a protocol that lets AI clients interact with external systems in a structured way. Instead of hoping a model can scrape your web app, infer your API shape, and guess the right mutation flow, you expose a smaller and more explicit surface: tools, resources, and sometimes prompts. The AI client does not need to know the full internals of your product. It only needs to know what operations you have chosen to expose and how to call them safely.</p><p>Under the hood, the important distinction is usually transport. A local MCP server commonly uses stdio. A remote MCP server uses HTTP, which is what makes hosted auth, hosted discovery, and normal SaaS-style onboarding possible. For a SaaS product, that usually means operations like reading data, searching, creating records, updating records, or triggering workflows. If those capabilities already exist inside your application, MCP is often the shortest path from &#8220;this works internally&#8221; to &#8220;an AI client can use this with a stable contract.&#8221; That is why MCP matters. It reduces scraping, reduces prompt glue, and gives you a narrower place to enforce auth, validation, and limits.</p><p></p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tIcc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tIcc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 424w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 848w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 1272w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tIcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png" width="722" height="607" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:607,&quot;width&quot;:722,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85800,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://faizank.substack.com/i/198625602?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tIcc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 424w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 848w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 1272w, https://substackcdn.com/image/fetch/$s_!tIcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bb39c4e-d65e-44ef-9c64-9e9a13622f95_722x607.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>Why Remote MCP Matters for SaaS Products</h2><p>A local MCP server is fine for internal tools, prototypes, or products aimed only at technical users. A hosted SaaS product, though, usually wants a remote MCP server as the end state because the alternative is to ship part of your integration story onto the user&#8217;s machine. Once that happens, your product inherits local runtime issues, PATH issues, install issues, and credential-management issues that have nothing to do with the core value of the app.</p><p>Remote MCP keeps the business logic in your infrastructure, where you can monitor it, rate-limit it, update it, and keep it aligned with the rest of your product. Just as importantly, it lets you move toward a normal onboarding flow. That matters because most users do not actually want &#8220;MCP support.&#8221; They want to connect an AI client to your app without turning themselves into part-time integration engineers.</p><div><hr></div><h2>The Three Practical Ways to Ship MCP</h2><p>If you are building this today, you usually end up choosing between three models.</p><h3>1. Local stdio server</h3><p>This is the fastest way to get something working. The user runs a local process, often through <code>npx</code> or a downloaded binary, and the AI client talks to it over stdio. This model is excellent for internal tooling and for technical users who are comfortable with local setup. It is also the easiest model to document because you are only solving for one environment at a time.</p><p>If you are building in TypeScript, the normal starting point is the <a href="https://ts.sdk.modelcontextprotocol.io/">MCP TypeScript SDK</a> with <code>StdioServerTransport</code>. In practice, that usually means something like:</p><pre><code><code>npm install @modelcontextprotocol/sdk zod
</code></code></pre><p>For customers, onboarding looks like this:</p><ol><li><p>Install your MCP package or binary.</p></li><li><p>Add a local command to their MCP client.</p></li><li><p>Run that command on their own machine whenever the client connects.</p></li></ol><p>The downside is that your onboarding now depends on the user&#8217;s machine. Node versions, binary distribution, shell quirks, and local config all become part of your product whether you wanted them or not.</p><h3>2. Remote MCP with manual token auth</h3><p>This is a common middle step. The server is hosted, which is a big improvement, but the user still has to generate a token and paste it into the client. Depending on the client, they may also still need a local bridge to reach the hosted server. This version can already be useful, especially if your target users are technical and motivated, but it still leaks setup friction into the experience.</p><p>For the hosted server itself, you can still use the <a href="https://ts.sdk.modelcontextprotocol.io/">MCP TypeScript SDK</a> and switch to Streamable HTTP instead of stdio. If your target client only knows how to spawn local commands, the usual bridge is <code>mcp-remote</code>:</p><pre><code><code>npm install @modelcontextprotocol/sdk zod
npm install -g mcp-remote
</code></code></pre><p>or, if the user is launching it ad hoc:</p><pre><code><code>npx mcp-remote https://yourapp.com/dashboard-mcp
</code></code></pre><p>For customers, onboarding usually looks like this:</p><ol><li><p>Create a token in your product.</p></li><li><p>Add your hosted MCP URL or a local <code>mcp-remote</code> bridge command.</p></li><li><p>Paste the token into the client config.</p></li></ol><h3>3. Remote MCP with hosted OAuth and tokenless onboarding</h3><p>This is the model most SaaS teams eventually want. The user adds a connector URL, signs in, approves access, and starts using the integration. There is no manual token creation, no pasted bearer secret, and no local helper process just to reach your hosted endpoint. It is the cleanest version from the user&#8217;s point of view, and it is usually the hardest one to build because it forces auth, discovery, deployment, and product UX to line up cleanly.</p><p>Implementation-wise, this is still the same remote server shape. The difference is that you finish the auth layer. In practice that usually means:</p><pre><code><code>npm install @modelcontextprotocol/sdk zod
</code></code></pre><p>and then building the OAuth and discovery routes around that server instead of shipping manual token setup.</p><p>For customers, onboarding becomes:</p><ol><li><p>Open the connector UI in the client.</p></li><li><p>Paste your hosted MCP URL.</p></li><li><p>Sign in to your product.</p></li><li><p>Approve access.</p></li></ol><p>Model Useful package(s) How customers onboard Main downside Local stdio <code>@modelcontextprotocol/sdk</code> with stdio transport Install package or binary, add local command Local runtime and config become part of your product Remote MCP + manual token <code>@modelcontextprotocol/sdk</code> for the server, <code>mcp-remote</code> when a client still expects local stdio Add hosted URL or bridge command, then paste token Credential and bridge friction remain Remote MCP + hosted OAuth <code>@modelcontextprotocol/sdk</code> with Streamable HTTP plus your OAuth layer Add hosted URL, sign in, approve access Hardest to implement cleanly</p><div><hr></div><h2>A Minimal Way to Start</h2><p>If you want a sane implementation path, do not start with OAuth. Start by proving that your tool surface is useful locally, then move the exact same operations behind a hosted transport, and only then add the auth and discovery layers.</p><p>A minimal local TypeScript server looks like this:</p><pre><code><code>import * as z from "zod/v4";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({
  name: "my-server",
  version: "1.0.0",
});

server.registerTool(
  "greet",
  {
    description: "Test tool",
    inputSchema: {
      name: z.string(),
    },
  },
  async ({ name }) =&gt; ({
    content: [{ type: "text", text: `Hello, ${name}!` }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);
</code></code></pre><p>That does not get you a hosted connector, but it does answer the first question that matters: are your tools coherent enough that an AI client can do something useful with them?</p><p>Once the local version is working, the recommended build order is:</p><ol><li><p>Keep the same tool definitions and move them behind Streamable HTTP.</p></li><li><p>Give the server one clean public MCP URL.</p></li><li><p>Add the unauthenticated <code>401</code> challenge.</p></li><li><p>Publish protected-resource and auth-server metadata.</p></li><li><p>Add consent and token issuance.</p></li><li><p>Test the entire flow through a public tunnel before calling it done.</p></li></ol><p>That order matters because most remote MCP projects do not fail on the first tool. They fail in the layers around it.</p><div><hr></div><h2>Step 1: Define the Smallest Useful Tool Surface</h2><p>The tool layer is rarely the hardest part, but it is still where the project should start. The trick is not to expose every internal operation you have. Start with the smallest set of tools that covers a real workflow end to end. A good MCP surface should feel deliberate because it needs to map to things users actually want the model to do, not to your raw internal API topology.</p><p>If your product is documentation software, the surface might look like: list docs, inspect a manifest, pull content, push content, publish. If your product is a CRM, it might be: search contacts, fetch an account, create a note, update a stage. The details vary, but the rule stays the same: expose coherent workflows, not just miscellaneous RPC endpoints.</p><div><hr></div><h2>Step 2: Give the Server a Real Public URL</h2><p>Once you move beyond local development, the MCP URL becomes part of the integration design. This is easy to overlook because teams often expose whatever internal-looking route already exists, then wonder why the integration still feels unfinished. A clean public path does not solve protocol problems, but it does help make the feature feel like a first-class product surface instead of an implementation detail that escaped from your router.</p><p>In practice, that means preferring something like:</p><pre><code><code>https://yourapp.com/dashboard-mcp
</code></code></pre><p>over something like:</p><pre><code><code>https://yourapp.com/api/internal/v1/mcp
</code></code></pre><p>The first reads like a capability. The second reads like a leak. Users notice this even when they do not say it out loud.</p><p>As one concrete example, DocsAlot moved its write-capable dashboard MCP flow onto a canonical public path, <code>https://docsalot.dev/dashboard-mcp</code>, and kept the older internal-looking route only as a compatibility alias. That made the integration easier to explain, easier to document, and easier to recognize as a product surface instead of an API accident.</p><div><hr></div><h2>Step 3: Implement the MCP Endpoint Like a Real Transport</h2><p>Current remote MCP servers should behave like proper HTTP transports, not just &#8220;an API route that happens to accept JSON.&#8221; In practice, that means implementing the Streamable HTTP shape cleanly. The server exposes one MCP endpoint. Clients send JSON-RPC messages to it over HTTP POST. The server can reply with normal JSON for simple requests or <code>text/event-stream</code> when it wants to stream messages, progress, or notifications back to the client.</p><p>That one detail matters more than it sounds. A lot of integrations feel flaky because the tool layer exists, but the endpoint still behaves like an ad hoc RPC surface rather than the transport the client expects.</p><p>At a minimum, your endpoint should be able to handle something like this:</p><pre><code><code>POST /dashboard-mcp
Accept: application/json, text/event-stream
Content-Type: application/json
MCP-Protocol-Version: 2025-06-18

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}
</code></code></pre><p>If you want stateful sessions, return an <code>Mcp-Session-Id</code> during initialization and require that header on subsequent requests. If you do not want sessions, you can stay stateless, but make that choice intentionally. Either way, the endpoint should be acting like an MCP transport, not a loose collection of tool handlers.</p><div><hr></div><h2>Step 4: Make the Unauthenticated Endpoint Useful</h2><p>If you want tokenless onboarding, the unauthenticated endpoint cannot just say &#8220;missing token&#8221; and stop there. It has to tell the client how to continue. In practice, that means returning a <code>401</code> with a <code>WWW-Authenticate</code> header that points to your protected-resource metadata.</p><pre><code><code>GET /dashboard-mcp

401 Unauthorized
WWW-Authenticate: Bearer realm="yourapp", resource_metadata="https://yourapp.com/.well-known/oauth-protected-resource/dashboard-mcp"
</code></code></pre><p>That <code>resource_metadata</code> URL is where the client learns what resource it is trying to access and how to find the rest of the authorization flow. Once you have this in place, the endpoint stops being &#8220;something that eventually wants a token&#8221; and starts behaving like a remote integration surface that knows how to onboard a client properly. This one step is where many half-finished remote servers reveal themselves, because the hosted endpoint is present but the hosted onboarding path is still missing.</p><div><hr></div><h2>Step 5: Publish the Discovery Documents and Support Client Registration</h2><p>The <code>401</code> challenge is only the start. A client still needs to discover two things:</p><ol><li><p>Which authorization server is responsible for this MCP resource.</p></li><li><p>Which authorization, token, and registration endpoints that server exposes.</p></li></ol><p>That usually means publishing:</p><ul><li><p>protected-resource metadata for the MCP URL</p></li><li><p>authorization-server metadata for the OAuth server</p></li><li><p>dynamic client registration, if you want new MCP clients to onboard without pre-created client credentials</p></li></ul><p>The shape looks roughly like this:</p><pre><code><code>// /.well-known/oauth-protected-resource/dashboard-mcp
{
  "authorization_servers": ["https://yourapp.com/oauth"]
}
</code></code></pre><pre><code><code>// OAuth server metadata
{
  "issuer": "https://yourapp.com/oauth",
  "authorization_endpoint": "https://yourapp.com/oauth/authorize",
  "token_endpoint": "https://yourapp.com/oauth/token",
  "registration_endpoint": "https://yourapp.com/oauth/register"
}
</code></code></pre><p>The exact metadata shape depends on your auth server, but the practical point is simple: a client should be able to start from your MCP URL and discover the rest without hardcoded tribal knowledge. If you skip dynamic client registration, every new client either needs a pre-provisioned client ID or a manual setup screen. That is usually where &#8220;tokenless onboarding&#8221; quietly turns back into a configuration project.</p><div><hr></div><h2>Step 6: Treat Discovery Routes as First-Class Routes</h2><p>This is where a lot of teams lose time. The main MCP URL works, the app is up, and yet the connector still fails because the client is probing issuer-specific <code>/.well-known/...</code> URLs that your main routing stack is not handling correctly. Instead of returning JSON metadata, those paths often return HTML, redirects, or some generic page response because they fell through to the wrong handler.</p><p>The fix is not complicated, but it needs to be explicit. Define the discovery routes directly and test them directly. Do not assume your framework routing will get them right by accident. If you are using Next.js, Rails, Laravel, or anything else with a large implicit routing layer, hit each discovery endpoint with <code>curl</code> before you trust the connector flow. If those routes are wrong, the rest of your onboarding work never gets a chance to matter.</p><div><hr></div><h2>Step 7: Reuse Your Existing Login System, but Add a Real Consent Layer</h2><p>If your SaaS product already has a working sign-in system, the MCP OAuth flow should usually land inside that system. This is one of the biggest advantages of hosted onboarding. The user does not have to think about &#8220;API credentials&#8221; as a separate universe. They just sign in to the product they already know and approve access.</p><p>But a normal login page is not enough. You still need a consent step that is specific to the MCP resource and its scopes. That is where you decide whether the connector can read, write, publish, delete, or trigger actions. For a lot of SaaS products, the right move is to reuse the same user session and identity system while adding a separate grant model for the MCP server itself.</p><p>This is also the point where subtle bugs tend to show up, because your app auth, your public domain, your redirect handling, and your MCP metadata all need to agree. When they do not, you get failures that look almost healthy. The endpoint responds. The auth page opens. Sign-in appears to work. The callback still fails because a cookie, origin, or redirect assumption broke somewhere in the chain.</p><p>The rule here is simple but unforgiving: the connector flow needs one stable public identity. If the public host changes halfway through the handshake, you are going to get confusing failures.</p><div><hr></div><h2>Step 8: Validate Resource Indicators and Token Audience</h2><p>This is one of the more technical parts of the current MCP auth model, and it is worth implementing correctly. The client should request a token for a specific MCP resource, not just &#8220;whatever this auth server hands out.&#8221; In OAuth terms, that means carrying a <code>resource</code> parameter that points at the canonical MCP server URI.</p><p>In practice, the auth and token requests end up looking more like this:</p><pre><code><code>GET /oauth/authorize?...&amp;resource=https%3A%2F%2Fyourapp.com%2Fdashboard-mcp
POST /oauth/token
resource=https://yourapp.com/dashboard-mcp
</code></code></pre><p>On the server side, you should not just mint a token and hope for the best. Validate that the token was issued for the MCP resource that is receiving it. If your product hosts multiple MCP surfaces, or if your auth infrastructure is shared across products, this becomes a real security boundary rather than a theoretical nicety.</p><p>If you skip this, you are much closer to &#8220;opaque bearer string that happens to work&#8221; than to a clean remote MCP implementation.</p><div><hr></div><h2>Step 9: Protect the HTTP Edge</h2><p>Most of the painful failures are not in the tool handler itself. They are in the edge conditions around the HTTP transport. There are a few checks worth treating as mandatory:</p><ol><li><p>Validate the <code>Origin</code> header on incoming HTTP connections.</p></li><li><p>Never accept access tokens in query strings.</p></li><li><p>Return <code>401</code>, <code>403</code>, and <code>400</code> distinctly so clients can tell auth failure from permission failure from malformed requests.</p></li><li><p>Be strict about the MCP endpoint shape and headers, especially on initialize and token-bearing requests.</p></li></ol><p>The <code>Origin</code> validation piece is easy to miss, but it matters for local and browser-adjacent deployments because it helps defend against DNS rebinding-style problems. If you are hosting a remote MCP server on the public internet, that is part of the real implementation, not just optional hardening for later.</p><div><hr></div><h2>Step 10: Budget for Tunnel-Based Testing</h2><p>Remote connectors are awkward to test locally because &#8220;local&#8221; is only part of the truth. For the full loop to work, the client still needs a publicly reachable HTTPS endpoint. That usually means running your app locally and exposing it through a tunnel, then aligning your app base URL and callback URLs to that temporary hostname.</p><p>This is where a lot of real bugs show up. Social sign-in providers reject callback mismatches. Discovery URLs resolve differently than they do in production. Session cookies behave differently across hostnames. If you are testing with Claude custom connectors specifically, there is one more wrinkle: the connection comes from Anthropic&#8217;s cloud, not from the Claude Desktop app on your own machine. If you only test the app on localhost, you will miss some of the most important onboarding failures. In practice, the first fully working tunnel-based test tells you more about your real connector than a week of localhost confidence.</p><p>The simplest way to do this is with <a href="https://ngrok.com/docs/guides/share-localhost/quickstart">ngrok</a>. Their <a href="https://ngrok.com/docs/guides/share-localhost/tunnels">tunnels documentation</a> is also worth reading because it explains exactly how the public URL is forwarded back to your local port.</p><p>If your app is running on port <code>3000</code>, the basic setup is:</p><pre><code><code>brew install ngrok/ngrok/ngrok
ngrok config add-authtoken &lt;your-ngrok-token&gt;
ngrok http 3000
</code></code></pre><p>Once that is running, ngrok gives you a public HTTPS URL. Use that hostname for the parts of your auth flow that care about the public origin:</p><ol><li><p>your app&#8217;s public base URL</p></li><li><p>your MCP URL</p></li><li><p>your OAuth callback allowlist</p></li><li><p>any social sign-in callback settings you depend on</p></li></ol><p>So the practical advice is: treat tunnel-based auth testing as part of the feature, not as cleanup work after the feature. It is not cleanup. It is where the real system finally reveals itself.</p><div><hr></div><h2>What to Expect to Go Wrong</h2><p>The hardest bugs will probably not be in your tool handlers. They will be in the edges around them. Discovery routes returning HTML instead of JSON is common. Public origin mismatches are common. Redirect and cookie problems are common. Time handling inside auth flows can also surprise you more than it should, especially if you compare expiration values across different layers and different assumptions about timestamps.</p><p>This is one reason MCP can feel deceptively simple at the start. The first tool call might be easy. The part where a real desktop client discovers the server, signs in, stores the authorization state correctly, and comes back later for the second tool call is where you find out whether the integration is actually finished.</p><div><hr></div><h2>A Good End State</h2><p>If you are building a remote MCP server for a SaaS product, a good end state looks like this:</p><ol><li><p>The public URL is clean and stable.</p></li><li><p>The tool surface is narrow and intentional.</p></li><li><p>Discovery and protected-resource metadata are explicit.</p></li><li><p>The user signs in through your normal app auth.</p></li><li><p>The user approves access instead of creating a token manually.</p></li><li><p>The whole flow works without local runtime setup.</p></li></ol><p>That is the version that reduces friction. It is also the version that starts to feel less like a protocol demo and more like a real product feature.</p><p>MCP itself is not the hard part. The hard part is making the onboarding disappear.</p>]]></content:encoded></item><item><title><![CDATA[How Many Organic Votes Can You Get on PH Without Paying Anyone? A Case Study]]></title><description><![CDATA[I launched Agent-Ready Docs Benchmark on Product Hunt without paying a hunter, influencers, or anyone else to push it.]]></description><link>https://faizank.substack.com/p/how-many-organic-votes-can-you-get</link><guid isPermaLink="false">https://faizank.substack.com/p/how-many-organic-votes-can-you-get</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Wed, 13 May 2026 22:55:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!94IK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p></p><p><strong>I launched <a href="https://www.producthunt.com/products/agent-ready-docs-benchmark">Agent-Ready Docs Benchmark on Product Hunt</a> without paying a hunter, influencers, or anyone else to push it. It ended with </strong><code>51</code><strong> votes and </strong><code>#19</code><strong> overall.</strong></p><p>This was not a paid launch. I did not pay a hunter. I did not pay influencers. I did not run ads. I shared it myself, messaged people directly, posted on LinkedIn and X, and dropped it into WhatsApp and Slack groups I am part of.</p><p>The short version is that Product Hunt is less of a neutral leaderboard than I thought. It is a one-day distribution event. The product matters, but so do your private network, the way you ask for support, and whether the platform gives you enough visibility to matter.</p><p>If you want the plain answer to the title, my answer was <code>51</code> votes and a <code>#19</code> finish. That is what this launch produced without paying anyone. The rest of this post is about what seemed to drive that result and what I would do differently next time.</p><h2>I wanted a trial run, not a perfect launch</h2><p>I picked the benchmark because I wanted a narrow product surface for the experiment. I wanted to see how Product Hunt behaves when the product is easy to describe, the ask is simple, and the launch is mostly about learning.</p><p>The page got real attention, people actually used the product, and the launch was concrete enough to tell me something useful. It was a good reminder that narrow products are often better launch vehicles because they are easier for other people to understand and easier for you to evaluate honestly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!94IK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!94IK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 424w, https://substackcdn.com/image/fetch/$s_!94IK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 848w, https://substackcdn.com/image/fetch/$s_!94IK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!94IK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!94IK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg" width="1200" height="760" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:760,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:123892,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://faizank.substack.com/i/197599249?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!94IK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 424w, https://substackcdn.com/image/fetch/$s_!94IK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 848w, https://substackcdn.com/image/fetch/$s_!94IK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!94IK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3967bf54-288e-42a9-8a29-7e4ee5ea0f24_1200x760.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>The launch was more private than public</h2><p>The biggest lesson is that LinkedIn DMs were probably the main driver of votes. That is not a very glamorous answer, but I think it is the right one.</p><p>I cannot prove that cleanly with analytics because most of this lives inside direct messages, copied links, group chats, and other dark social channels. But when I compare the weak contribution from X with the responses I got from people I reached out to directly, the pattern is pretty obvious. LinkedIn DMs did more work than public posting. WhatsApp groups and Slack groups helped as well. X barely moved the needle. It likely contributed only <code>3</code> or <code>4</code> votes in total.</p><p>That was useful to learn because it changed how I think about launch-day effort. I would now treat direct outreach as the main channel, not as a supporting tactic around public posting.</p><p>This also changed my mental model of Product Hunt a bit. From the outside, it can look like a public internet event driven by homepage exposure and social momentum. In practice, at least for me, it behaved much more like a private trust event compressed into one day. A lot of the real movement happened in inboxes, chats, and small groups, not out in the open.</p><h2>Being featured matters more than I thought</h2><p>The other big lesson is that being featured matters more than I thought. This came up repeatedly in conversations with other founders. A lot of people said some version of the same thing: if you are not featured by Product Hunt, the launch gets much harder, and some founders will even cancel and relaunch rather than waste the day.</p><p>That sounded a little dramatic to me before this launch. It sounds much less dramatic now. The more I looked into it, the more obvious it became that visibility on Product Hunt is not evenly distributed.</p><p>Product Hunt is not just a neutral scoreboard for product quality. It is a distribution system with its own visibility rules. Once I accepted that, the outcome made a lot more sense. If I do this again, I will treat featuring as part of the launch plan itself because it can make or break the launch, not just as a nice bonus if it happens.</p><h2>I had to separate launch-day signal from post-launch noise</h2><p>One thing I am glad I checked carefully was what happened after the launch day. I went through the traffic and made sure to separate the launch-day traffic from the post-launch noise so I could see the carryover effects more clearly.</p><p>Every run on the benchmark creates a public report slug, so there is a natural second wave once people start sharing those links around. But those pages also attract crawlers and probes, which means not all carryover traffic should be read the same way.</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4-32!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4-32!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4-32!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4-32!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4-32!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4-32!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg" width="1200" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:111485,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://faizank.substack.com/i/197599249?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4-32!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4-32!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4-32!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4-32!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba75077c-6deb-4781-9d42-066a52b2a913_1200x700.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>What I would do differently next time</h2><p>If I run another Product Hunt launch, I would change a few things.</p><p>First, I would build the launch around direct outreach from the beginning. I would prepare the contact list earlier, write shorter asks, and spend more time on the people who are actually likely to show up.</p><p>Second, I would treat featuring as a core part of the plan. I would not assume that a good product is enough to get featured. <a href="https://www.producthunt.com/posts/how-product-hunt-decides-what-to-feature">This thread</a> has some insights about how PH decides who to feature, and I would use that to inform the launch strategy. I would also prepare for the possibility of not being featured and have a backup plan for how to get visibility in that case.</p><p>Some tricks other founders have mentioned include being active on Product Hunt before the launch, engaging with the community, and reaching out to the PH team directly to build relationships. Getting hunted by a well-known hunter can help too if you are willing to pay someone or know someone.</p><p>Finally, some people hire a dedicated &#8220;launch guy&#8221; just for launch day to focus on outreach, monitoring, and engagement. That might be worth considering if the stakes are high enough.</p><h2>Final take</h2><p>My simple conclusion is that Product Hunt was useful for exactly what I needed from it. It let me run a trial launch on a narrow product, learn how much direct outreach matters, and see how much of the outcome depends on visibility inside the platform.</p><p>The TLDR is this: LinkedIn DMs mattered more than public social. WhatsApp and Slack groups helped. X did very little. Being featured matters a lot. If I want a better result next time, I need to treat distribution and launch mechanics with the same seriousness as the product page itself. Product Hunt also discounts upvotes from newly created accounts, so if people want to support you, have them create their accounts a few weeks before launch.</p><p>I am also genuinely grateful for every one of those <code>51</code> votes. That number is still small enough that it feels personal. I can roughly tell who many of those people were, and I know they took a moment to support something I built. I do not take that lightly.</p>]]></content:encoded></item><item><title><![CDATA[How well AI agents are reading your docs]]></title><description><![CDATA[TLDR: We built a public docs benchmark that measures how readable your documentation is for AI agents.]]></description><link>https://faizank.substack.com/p/how-well-ai-agents-are-reading-your</link><guid isPermaLink="false">https://faizank.substack.com/p/how-well-ai-agents-are-reading-your</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Mon, 04 May 2026 23:43:42 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ls6D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ls6D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ls6D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 424w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 848w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 1272w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ls6D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png" width="1259" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:1259,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:333370,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://faizank.substack.com/i/196485708?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ls6D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 424w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 848w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 1272w, https://substackcdn.com/image/fetch/$s_!ls6D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5bf5650a-dc01-4675-b736-e56dbe851cb7_1259x626.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong><br>TLDR: We built a public docs benchmark that measures how readable your documentation is for AI agents. We had internal tools for this, but decided to make it transparent and vendor-neutral. The benchmark tests discovery, structure, task-readiness, and clean delivery&#8212;following patterns from the Agent-Friendly Documentation Spec.</strong></p><p>AI agents are reading documentation more than humans now.</p><p>Every day, agents crawl docs sites to understand APIs, find integration examples, and figure out authentication flows. When they can&#8217;t parse your docs cleanly, they fail at tasks that should be straightforward. The problem isn&#8217;t model capability&#8212;it&#8217;s interface design.</p><p>We&#8217;ve been tracking this at Docsalot through internal agent traffic analysis. Most documentation failures happen at basic structural levels: no machine-readable entry points, HTML-only content, missing examples, unclear auth requirements.</p><p>We had closed internal benchmarks for analyzing this, but realized the broader ecosystem needed transparent measurement tools.</p><p>Most AI benchmarks have the same problem: vendors run them and also want to win them. This doesn&#8217;t make them dishonest, but it makes them hard to trust. If you define the scoring, pick the tests, and rank your own framework first, you&#8217;re writing a product page, not running a benchmark.</p><p>We faced this building Docsalot&#8217;s <a href="https://docsalot.dev/benchmarks/docs">public docs benchmark</a>. The obvious move: ship a flattering leaderboard, rank our stack high, call ourselves the best. The incentives are clear&#8212;benchmarks are free distribution.</p><p>That felt wrong.</p><p>Software has machine users now. We need measurements that reveal actual machine-readability, not which vendor wrote the test.</p><h2>Narrow claims are useful claims</h2><p>This isn&#8217;t a benchmark for &#8220;how good AI agents are&#8221; or &#8220;whether an agent can use your product end to end.&#8221;</p><p>It tests one thing: can an agent discover your docs, fetch them in machine-readable format, understand the structure, and find enough information to proceed without guessing?</p><p>Many &#8220;AI foundation model failures&#8221; are actually interface failures:</p><ul><li><p>no machine-readable entry point</p></li><li><p>HTML-only docs with no clean markdown path</p></li><li><p>navigation and cookie banners mixed into machine-facing content</p></li><li><p>no clear prerequisites or auth constraints</p></li><li><p>no examples</p></li><li><p>no troubleshooting or recovery information</p></li></ul><p>Humans skim and infer. Agents don&#8217;t.</p><h2>What we actually score</h2><p>The public benchmark uses four weighted buckets.</p><h3>1. Discovery and delivery</h3><p>This bucket checks whether the docs expose basic machine-readable entry points and retrievable text:</p><ul><li><p>does <code>/llms.txt</code> exist</p></li><li><p>does <code>/llms-full.txt</code> exist</p></li><li><p>do sampled documentation pages have valid <code>.md</code> versions</p></li></ul><p>We sample from <code>llms.txt</code> links when available, otherwise fall back to <code>/getting-started</code>, <code>/guide</code>, <code>/api</code>, <code>/reference</code>.</p><h3>2. Content structure</h3><p>This bucket checks whether <code>llms.txt</code> is actually usable, not merely present:</p><ul><li><p>does it have an H1 title</p></li><li><p>does it include a blockquote description</p></li><li><p>does it use meaningful H2 sections</p></li><li><p>do list items contain links</p></li><li><p>do those links include descriptions</p></li><li><p>is there an <code>## Optional</code> section for lower-priority material</p></li></ul><p>This follows patterns from <a href="https://afdocs.dev/">The Agent-Friendly Documentation Spec (AFDocs)</a> and its <a href="https://github.com/agent-ecosystem/afdocs">GitHub repository</a>. The idea is simple: if a machine-readable index exists, it should help agents prioritize instead of forcing blind exploration.</p><h3>3. Task readiness</h3><p>This bucket checks whether the docs contain the kinds of details agents repeatedly need to complete real tasks:</p><ul><li><p>a clear opening description of what the product actually does</p></li><li><p>prerequisites and constraints</p></li><li><p>integration information</p></li><li><p>troubleshooting or error-handling material</p></li><li><p>concrete examples or code blocks</p></li></ul><p>Pretty docs often fail here. Sites look polished but force agents to guess about auth, setup, limits, errors.</p><h3>4. Access and recovery</h3><p>This bucket checks whether the content is delivered in a form agents can actually use:</p><ul><li><p>do markdown pages return valid markdown rather than HTML or error pages</p></li><li><p>are responses reasonably fast</p></li><li><p>is the main content present in the initial HTML, or does it effectively require client-side JavaScript</p></li><li><p>do pages support <code>Accept: text/markdown</code></p></li><li><p>is markdown output clean, or polluted with nav, footer, and consent cruft</p></li></ul><p>Clean matters. Markdown with nav cruft is technically readable but practically noisy.</p><h2>The methodology has to be inspectable</h2><p>Benchmarks need transparency. We store breakdowns, individual checks, and methodology versions. External scores stay labeled as external.</p><p>Leaderboards collapse to integers, but the failure pattern matters more than the score. Did you lose points for missing <code>llms.txt</code>, dirty markdown, or no examples?</p><p>We disable domain-specific adjustments in benchmark mode. Our score widget has host-specific tweaks for user experience, but public benchmarks can&#8217;t have hidden exceptions.</p><p>Benchmark mode is stricter by design.</p><h2>Why vendor neutrality matters</h2><p>Neutrality isn&#8217;t about moral purity&#8212;it&#8217;s about diagnostic value. If your stack always wins, teams learn what you sell, not what works.</p><p>A credible benchmark needs to be willing to produce uncomfortable outputs:</p><ul><li><p>another docs stack can beat yours</p></li><li><p>your own customers can outrank you</p></li><li><p>open-source sites can outperform commercial platforms</p></li><li><p>a site with plain design can beat a visually polished one because the machine-facing delivery is better</p></li></ul><p>That is useful.</p><p>It creates a feedback loop around operability rather than brand preference.</p><h2>What this benchmark still misses</h2><p>This has limits. We don&#8217;t test full workflows, validate code, or exercise APIs. This measures docs operability, not software operability.</p><p>Still worth doing&#8212;docs are often the first interface agents hit. But we need separate benchmarks for CLI, API, auth, and recovery flows.</p><p>Seeing agent failures from missing structure makes the broader pattern obvious: this will happen in auth, setup, and recovery too.</p><h2>Why this matters now</h2><p>Software has machine users now. Buying, onboarding, support workflows start with agents reading docs.</p><p>If that first contact fails, adoption suffers before humans get involved.</p><p>We need benchmarks that are narrow, explicit, and neutral. Not because scores matter, but because visible failure modes give teams something to fix.</p>]]></content:encoded></item><item><title><![CDATA[Why an Agent Benchmark Needs to Exist]]></title><description><![CDATA[If AI agents are going to operate real software, we need an independent benchmark]]></description><link>https://faizank.substack.com/p/why-an-agent-benchmark-needs-to-exist</link><guid isPermaLink="false">https://faizank.substack.com/p/why-an-agent-benchmark-needs-to-exist</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Fri, 01 May 2026 21:30:04 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>The argument for better AI agents is now familiar. Better models, better scaffolds, better tools, better data. What is less discussed is that agents do not meet the world directly. They meet software interfaces, and those interfaces are often much worse than we admit.</p><p>An agent can fail because the model is weak. It can also fail because the documentation is incomplete, the authentication flow is brittle, the CLI is inconsistent, the API surface is awkward, the system hides state that matters, or the product provides no clean way to verify success after side effects. Humans routinely work around these problems with patience and guesswork. Agents usually cannot. That difference matters because it means a large fraction of agent failure is not just about reasoning. It is about operability.</p><p>This is why an agent benchmark needs to exist. More precisely, we need a benchmark for how well agents can use real software under realistic conditions.</p><h2>The Evaluation Gap</h2><p>Most evaluation still focuses on one of three things. Benchmarks measure whether a model can solve a predefined task. Demos show that a happy path can be made to work. Product scorecards isolate one part of the stack and grade it in place. Each of these is useful, but none answers the full operational question.</p><p>There is already meaningful work on pieces of the problem. <a href="https://docsalot.dev/tools/docsagent-score">DocsAgent Score</a>, <a href="https://buildwithfern.com/agent-score">Fern Agent Score</a>, and the <a href="https://afdocs.dev/">Agent-Friendly Documentation Spec</a> all make the same point from different angles: if the documentation layer is malformed, unstable, or opaque to machines, the agent begins half-blind. On another axis, <a href="https://www.usesapient.com/leaderboard/claudecode/cli">Sapient&#8217;s CLI leaderboard</a> is important because it treats tool use as something that can be tested in live environments rather than described abstractly.</p><p>The problem is that software does not fail one layer at a time. Agents succeed or fail across a chain: discover the right interface, understand the docs, configure the environment, authenticate correctly, use the right surface, verify the result, and recover when something breaks. Measuring one link in isolation tells you something, but not enough. The real technical question is whether the system as a whole is operable by an agent.</p><h2>Why Start With the Terminal</h2><p>The recent <a href="https://arxiv.org/abs/2601.11868">Terminal-Bench paper</a> is the clearest evidence I have seen that this problem is real and still undermeasured. Its importance is not that it is about shell commands. Its importance is that terminal work strips away a lot of benchmark theater and forces the agent to interact with a real environment. It has to inspect state, make decisions under uncertainty, respond to failures, and validate outcomes instead of merely narrating them.</p><p>Several lessons from that paper should shape any serious benchmark. Realistic long-horizon tasks are still difficult even for strong systems. Verification quality is central rather than optional. Many failures are operational: missing dependencies, bad paths, weak recovery, poor environment understanding. Token count and turn count are poor proxies for competence. An agent that wanders for 400 steps before stumbling into an answer is doing something categorically different from an agent that understands the environment, uses the right interface, and exits with a verified result.</p><p>That is why the terminal is a good starting layer. It exposes operational intelligence cleanly. But it should remain a starting layer. The larger question is not whether an agent can survive inside a shell. It is whether it can operate software across the interfaces modern systems actually expose.</p><h2>What Agent Bench Should Measure</h2><p>A useful agent benchmark should treat operability as layered.</p><p><strong>Discovery.</strong> Can the agent find the right entry point, whether that is a doc page, a command, an endpoint, or a machine-facing tool surface?</p><p><strong>Setup and authentication.</strong> Can it configure the environment correctly, understand the access model, and supply credentials in a way the system can actually use?</p><p><strong>Interface use.</strong> Can it operate the available surface correctly, whether that surface is a CLI, an API, or an MCP-style interface? The question is not whether the interface exists. It is whether correct use is legible to a machine.</p><p><strong>Verification.</strong> Can the agent determine that the action really succeeded? This is where many products appear usable in demos and then fall apart in practice.</p><p><strong>Recovery.</strong> Can the agent detect partial failure, retry safely, and avoid hallucinating completion?</p><p>Once you frame the problem this way, the benchmark starts doing more than producing a score. It helps separate three things that are currently entangled in most discussions of agents: model capability, scaffold quality, and software quality. That separation is necessary if we want to know what actually needs to improve.</p><h2>Why It Must Be Independent</h2><p>The strongest reason to build this benchmark outside the frontier labs is not politics. It is measurement integrity.</p><p>If the dominant benchmark for software operability is controlled by the same organizations building the frontier models, the benchmark will be subjected to intense optimization pressure from the people with the most resources and the strongest incentives to win. That does not require anyone to cheat. It is enough that the benchmark becomes part of the development loop. Over time, a benchmark under that kind of pressure tends to become a coordination artifact for a handful of large actors rather than a durable public instrument.</p><p>Independence also matters because a lab-controlled benchmark will naturally reflect the assumptions of the labs closest to it: their harnesses, their preferred abstractions, their toolchains, their definition of what counts as agent progress. That narrows the scope of what gets measured. A genuinely independent benchmark can ask broader questions about interface design, verification burden, recovery quality, documentation structure, and software-side friction.</p><p>More importantly, independence is what makes the benchmark useful to the rest of the ecosystem. Product teams, infrastructure companies, open-source projects, and researchers need a measurement system they can treat as public infrastructure rather than as an extension of one model vendor&#8217;s go-to-market strategy. If the benchmark is going to tell uncomfortable truths about where software breaks agents, it has to be able to publish those truths without being subordinated to any one lab&#8217;s incentives.</p><p>There is also a deeper reason. The long-run value of this benchmark is not only that it ranks agents. It is that it creates a body of evidence about how software itself needs to change. If agents repeatedly fail on the same kinds of interfaces, auth patterns, setup flows, and verification gaps, that is not just model feedback. It is design feedback for the software layer of the AI era. That feedback loop is too important to leave entirely inside the labs.</p><h2>Why This Matters</h2><p>Software now has two users: the human operating the system and the machine acting on the human&#8217;s behalf. That shift changes the meaning of usability. We are no longer asking only whether a person can understand a product. We also need to ask whether the product exposes enough structure for an agent to discover it, configure it, act through it, verify results, and recover safely.</p><p>If we fail to measure that well, two things happen. We overstate model capability because demos hide the cost of brittle setup and weak recovery. And we deprive software teams of a serious feedback loop for building systems that agents can actually use.</p><p>A good benchmark would do the opposite. It would make failures legible, separate model limitations from interface limitations, and provide a shared technical standard for what agent-operable software looks like. That is why Agent Bench matters. Not as a marketing badge, and not as a narrow contest between frontier labs, but as public infrastructure for a world in which software increasingly has machine users.</p><h2>References</h2><ul><li><p><a href="https://docsalot.dev/tools/docsagent-score">DocsAgent Score</a></p></li><li><p><a href="https://buildwithfern.com/agent-score">Fern Agent Score</a></p></li><li><p><a href="https://afdocs.dev/">Agent-Friendly Documentation Spec (AFDocs)</a></p></li><li><p><a href="https://www.usesapient.com/leaderboard/claudecode/cli">Sapient CLI Leaderboard / DevToolArena CLI benchmark</a></p></li><li><p><a href="https://arxiv.org/abs/2601.11868">Terminal-Bench: Benchmarking Agents on Hard, Realistic Tasks in Command Line Interfaces</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[I Redesigned My Landing Page So AI Agents Can Read It]]></title><description><![CDATA[I spent this week redesigning my landing page.]]></description><link>https://faizank.substack.com/p/i-redesigned-my-landing-page-so-ai</link><guid isPermaLink="false">https://faizank.substack.com/p/i-redesigned-my-landing-page-so-ai</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Mon, 27 Apr 2026 03:01:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p><strong>I spent this week redesigning my landing page. The surprising part was not the typography, the footer, or the mobile nav. It was realizing that the page had to work in two completely different modes: persuasive HTML for humans, and boring markdown for agents.</strong></p><p>That sounds obvious in hindsight. Of course it should work for both. The product I am building is about documentation that works for both humans and AI systems. If the landing page itself only works for humans, that is a weird contradiction.</p><p>But I think a lot of us still separate these things mentally.</p><p>We think of the landing page as the glossy marketing layer.<br>We think of <code>llms.txt</code>, markdown routes, and agent access as documentation infrastructure.</p><p>The more I worked on this, the less convinced I became that those are separate jobs.</p><p>If someone asks an agent &#8220;what does this product do?&#8221;, or &#8220;how much does it cost?&#8221;, or &#8220;is there a CLI?&#8221;, the answer is probably not coming from your docs reference first. It is often coming from your landing page, your pricing page, your tools page, your blog, and whatever else explains the product in plain language.</p><p>If those pages are hard to read mechanically, then a decent amount of your product positioning is trapped in human-only HTML.</p><h2>The landing page is part of the interface now</h2><p>There is a simple version of this argument:</p><p>If more product discovery is happening through AI answers, then the pages that explain the product are part of the API surface whether we like it or not.</p><p>Not API surface in the strict REST sense. I mean interface surface.</p><p>They answer questions like:</p><ul><li><p>what problem does this solve?</p></li><li><p>who is it for?</p></li><li><p>what do I do first?</p></li><li><p>is there a free plan?</p></li><li><p>does this have a CLI?</p></li><li><p>does this support API docs?</p></li></ul><p>For years, landing pages were allowed to be a little hand-wavy because a human reader could fill in the gaps. They could infer things from layout, screenshots, tone, and the general vibe of the page.</p><p>Agents are worse at that.</p><p>They are better at following structure.<br>They are better at clear copy.<br>They are better at plain text.<br>They are better when you give them a predictable place to look.</p><p>That means a lot of normal landing-page habits stop being enough.</p><h2>The first problem was content, not code</h2><p>Once you decide a page should have a machine-readable version, the fluff gets exposed instantly. A human reader might skim past inflated language. A markdown file makes every weak sentence much more obvious.</p><p>That ended up being useful. It forced me to write the page in a way that was clearer, more literal, and more defensible.</p><p>I think that is one of the more underrated side effects of building for agents: it is a good test for whether your copy makes sense at all.</p><h2>I did not want a separate &#8220;AI site&#8221;</h2><p>One tempting solution here is to build a totally different AI-facing microsite or dump a bunch of product facts into <code>llms.txt</code> and call it a day.</p><p>I did not want that.</p><p>The maintenance cost is bad, but the bigger problem is conceptual: if the human-facing page and the agent-facing page disagree, which one is real?</p><p>So I used a simpler rule:</p><p>The human page stays the canonical experience in the browser.<br>The machine-readable page should be a cleaner representation of the same reality.</p><p>That led to a structure like this:</p><ul><li><p><code>/</code> stays the normal landing page</p></li><li><p><code>/index.md</code> becomes the canonical machine-readable landing page</p></li><li><p><code>/llms.txt</code> serves the same underlying content as <code>/index.md</code></p></li><li><p><code>/pricing.md</code>, <code>/tools.md</code>, and <code>/blog.md</code> do the same for the main supporting routes</p></li></ul><p>I also added a visible way for humans to switch to the markdown version, mostly because I dislike hidden infrastructure. If something is important enough to exist, it should usually be visible somewhere.</p><h2>Why I kept both <code>Accept: text/markdown</code> and <code>.md</code> routes</h2><p>In theory, content negotiation should be enough.</p><p>If a client sends:</p><pre><code><code>Accept: text/markdown
</code></code></pre><p>then the same route can return markdown instead of HTML.</p><p>That part is nice because the URL does not change. A browser asks for HTML, an agent asks for markdown, everyone gets what they want.</p><p>But the web is never that clean.</p><p>Some agents send the right headers.<br>Some do not.<br>Some tools are inconsistent.<br>Some users just want a stable URL they can paste into a config file or inspect manually.</p><p>So I kept both:</p><ol><li><p>explicit <code>.md</code> routes like <code>/pricing.md</code></p></li><li><p>content negotiation on the corresponding human routes</p></li></ol><p>Nothing especially clever there. The important part was being strict about explicit markdown media types instead of treating <code>curl</code>&#8217;s default <code>*/*</code> as a signal.</p><p>That would have caused too many false positives.</p><h2><code>llms.txt</code> is useful, but it is not enough</h2><p>I still think <code>llms.txt</code> matters. It is a good discovery mechanism.</p><p>But one thing I keep noticing is that people treat it as if it solves the whole problem.</p><p>It does not.</p><p><code>llms.txt</code> helps an agent discover what exists.<br>It does not automatically make the content of the actual product pages cheap or easy to consume.</p><p>If someone pastes your pricing page into an agent, or the agent follows a link to the landing page, the thing that matters in that moment is not that <code>llms.txt</code> exists. The thing that matters is whether the page itself can be represented cleanly.</p><p>That is why I made <code>/llms.txt</code> and <code>/index.md</code> serve the same underlying landing content. I wanted discovery and representation to stay aligned instead of becoming two independent documents with their own drift.</p><h2>The design work and the machine-readable work were the same project</h2><p>I do not think of this as &#8220;I redesigned the landing page, and separately I added some AI files.&#8221;</p><p>It was one project.</p><p>The design pass forced the page to be simpler and more legible:</p><ul><li><p>clearer navbar</p></li><li><p>less clutter in the hero</p></li><li><p>cleaner CTA structure</p></li><li><p>more consistent footer resources</p></li><li><p>better mobile behavior</p></li><li><p>more honest pricing copy</p></li></ul><p>The machine-readable pass forced the underlying content and route structure to be more explicit:</p><ul><li><p>stable markdown URLs</p></li><li><p>shared canonical content</p></li><li><p>discovery headers</p></li><li><p>CLI onboarding path that agents can actually follow</p></li></ul><p>Those two things reinforced each other.</p><p>A simpler human page made the markdown representation better.<br>A better markdown representation made the human copy less sloppy.</p><p>That is probably the part I did not expect going in.</p><h2>Why I think this matters beyond my site</h2><p>I do not think every marketing site needs to become an AI-first artifact.</p><p>But I do think more teams are going to discover the same problem:</p><p>their knowledge-base may be in decent shape, while the pages that explain the product, pricing, setup, and workflow are still inaccessible or expensive for agents to consume.</p><p>That becomes a weird bottleneck.</p><p>The docs say one thing.<br>The landing page says another.<br>The pricing page is trapped in a JavaScript-heavy layout.<br>The CLI exists, but the onboarding path is only obvious to a human clicking around.</p><p>Agents can work around a lot of this. That does not mean they should have to.</p><p>My guess is that the next normal version of public product pages will have two equally intentional representations:</p><ul><li><p>the designed page for humans</p></li><li><p>the plain representation for machines</p></li></ul><p>Not because of ideology. Just because the distribution surface has changed.</p><h2>What I would do first if I were retrofitting another site</h2><p>If I had to do this again on a different site, I would do it in this order:</p><ol><li><p>fix the copy first</p></li><li><p>create a canonical markdown version of the landing page</p></li><li><p>add <code>llms.txt</code></p></li><li><p>add markdown routes for pricing and other high-intent pages</p></li><li><p>add explicit discovery headers</p></li><li><p>only then bother with fancier switching and UI affordances</p></li></ol><p>The order matters because clean content beats clever plumbing.</p><p>If the page is still vague, markdown just exposes vague text faster.</p><h2>The useful takeaway</h2><p>The practical lesson for me was pretty small:</p><p>Do not treat your landing page as separate from your agent surface.</p><p>If the page explains what the product is, how it works, how much it costs, and how to get started, then that page is already part of the input material for agents.</p><p>You can either make that representation explicit, or let every tool scrape and guess.</p><p>I would rather make it explicit.</p><p>That ended up being one of the more satisfying weeks I have had in a while, partly because the result is visible and partly because it removed a contradiction that had been bothering me.</p>]]></content:encoded></item><item><title><![CDATA[Why I’m Building Yet Another Docs Platform]]></title><description><![CDATA[TLDR: The docs market looks crowded if you count the number of vendors.]]></description><link>https://faizank.substack.com/p/why-im-building-yet-another-docs</link><guid isPermaLink="false">https://faizank.substack.com/p/why-im-building-yet-another-docs</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Tue, 14 Apr 2026 20:40:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vJPB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vJPB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vJPB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vJPB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png" width="1080" height="1080" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1080,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:807550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://faizank.substack.com/i/194230466?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vJPB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 424w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 848w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!vJPB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73a44231-a53e-4c6e-8795-a2896946f154_1080x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><strong>TLDR: The docs market looks crowded if you count the number of vendors. It looks a lot less crowded if you look at the documentation most teams actually ship. That&#8217;s the short version of why I think <a href="https://docsalot.dev?utm-source=ss">DocsAlot</a> should exist. Its customer driven, not investor driven. Most existing platforms are bloated, and trying to be everything to everyone.  </strong></p><p>I am not arguing that competition does not exist. It obviously does. I am saying there is plenty of room at the bottom</p><p>GitBook is established. Scalar has a strong API-first position. Docusaurus, Fumadocs, starlight are solid open-source options. There are plenty of smaller tools too.</p><p>But &#8220;there are competitors&#8221; is not the same thing as &#8220;the market is closed.&#8221;</p><p>One of the cleaner explanations of this came from Max Rozen, who wrote about <a href="https://maxrozen.com/on-four-years-running-saas-competitive-market">building OnlineOrNot</a> in a category with roughly 200 listed alternatives. His point was not that competition is fake. It was that markets are messier and product fit is uneven. Buyers are rarely choosing from a tidy spreadsheet of ten well-understood options. A lot of them are using whatever they already know, whatever a friend mentioned, or whatever happened to show up first.</p><p>That framing matches what I see in documentation.</p><h2><strong>The docs market is not one market</strong></h2><p>People talk about &#8220;documentation platforms&#8221; as if they all solve the same problem. They do not.</p><p>From where I sit, the category is splitting into at least three different buckets.</p><p><strong>1. AI-native and automation-first products</strong></p><p>This bucket is optimizing for structured specs, generated SDKs, machine-readable outputs, agent access, and automation pipelines.</p><p>Mintlify is a clear example of this. Even the product framing has moved well beyond &#8220;nice docs site.&#8221; The company now describes itself as an intelligent knowledge platform, with features around AI answers.<br><br>The direction of travel is obvious: not just hosted docs, but infrastructure for knowledge consumption. A common pattern when you have raised a lot of money is to expand the vision and the product at the same time. That is what I see happening here. If they go along this direction, expect customer support bots like Pylon, as that&#8217;s a bigger market.</p><p>Fern is in a similar family, but from the API side. The core pitch is spec-first API infrastructure: generate SDKs, generate docs, keep them aligned, and increasingly support agent-readable surfaces like llms.txt and MCP. It is a serious product for teams that want their API surface treated like a system, not just a website. Fern recently was acquired by Postman, which is another sign that this side of the market is converging with broader API platform infrastructure rather than staying a narrow docs category forever.</p><p>These are not bad products. They are doing the rational thing. But once a company starts expanding in that direction, the product changes.</p><p><strong>2. Human-native workflow platforms</strong></p><p>This bucket is stronger when the problem is editorial workflow, internal collaboration, permissions, review loops, and narrative authoring across teams.</p><p>GitBook is the obvious example. It has a strong editor, collaborative workflows, permissions, publishing controls, AI answers, Git sync, and an MCP server. That makes sense if your real problem is not &#8220;render my API reference beautifully,&#8221; but &#8220;help multiple humans across support, engineering, product, and solutions keep a large knowledge surface coherent.&#8221;</p><p>That is a real need. It is just a different one.</p><p><strong>3. Open-source frameworks</strong></p><p>Then there is the third category: tools like <a href="https://docusaurus.io/">Docusaurus</a> and <a href="https://fumadocs.dev/">Fumadocs</a>.</p><p>These are not really &#8220;buying a docs platform&#8221; in the SaaS sense. They are frameworks. They give you a strong starting point, but you still assemble and run the system yourself. You choose hosting, deployment, content workflow, permissions, previews, analytics, and whatever agent-facing pieces you want to bolt on.</p><p>In summary, that distinction matters because people often look at a list that includes GitBook, Docusaurus, and Fumadocs and conclude that the category is saturated. I think that is the wrong read. What I see instead is fragmentation. These products are solving adjacent jobs, not identical ones.</p><h2><strong>Why I think documentation demand goes up from here</strong></h2><p>The bigger reason I am comfortable building in this market is that I think the need for documentation is increasing.</p><ol><li><p><strong>APIs are moving closer to the default</strong></p></li></ol><p>I do not mean every product will expose a perfect public REST API next quarter. The transport does not matter that much. Some products will expose APIs. Some will expose agent actions. Some will expose MCP-compatible tooling. Some will wrap existing product surfaces in a machine-friendly layer later.</p><p>The underlying pressure is the same: software is becoming more composable, and products that are easy to integrate into automated workflows have a large advantage.</p><p>That changes the role of docs. Documentation used to be downstream from the product. Build the thing, then explain it. But increasingly, documentation is part of the interface.</p><p>If a user is onboarding through a coding agent, the docs are no longer just a support artifact for a human engineer skimming examples. They are part of the material that lets the agent understand what the product is, what operations are available, what the constraints are, and how to combine actions safely.</p><ol start="2"><li><p><strong>More people are going to act like developers</strong></p></li></ol><p>I also think the total number of people producing software behavior is going up because AI is making software construction more accessible.</p><p>That does not mean everyone turns into a strong software engineer. It means more people can express intent in software-adjacent ways: shipping workflows, wiring tools together, automating ops, building internal utilities, and standing up small products without traditional teams.</p><p>Whether you call them developers or not is secondary. The important part is that they still need interfaces they can understand and trust.</p><p>More builders means more APIs, more integration surfaces, and more documentation demand.</p><p>This is one of the places where I think people underestimate the second-order effect of coding agents. Even if code generation gets easier, the surrounding coordination problem gets bigger. More software gets made. More endpoints exist. More tools become partly programmable. More documentation has to exist to explain all of that to humans and to machines.</p><ol start="3"><li><p><strong>Docs now need human and machine affordances</strong></p></li></ol><p>The docs page is no longer the whole artifact.</p><p>Now you also need the machine-readable and agent-discoverable layer around it: llms.txt, MCP endpoints, skill files, structured reference, and other small artifacts that make a product legible in AI-native workflows.</p><p>The good news is that these are not especially hard to produce once you have the right source of truth.</p><p>The bad news is that if you do not produce them, your product becomes less visible and less usable in the workflows that are growing fastest.</p><p>That is another reason I do not think this category collapses into a few incumbents. The requirements are expanding.</p><h2><strong>Why strong competitors do not close the market for a smaller product</strong></h2><p>The strongest argument against building DocsAlot is obvious: why enter a market with credible incumbents?</p><p>My answer is that incumbents do not just create competition. They also create openings.</p><p>As companies raise more money, move upmarket, or get pulled into adjacent categories, they usually get broader. That is rational. Customers ask for more workflow, more enterprise controls, more AI, more governance, more analytics, more collaboration, more import paths, and more content types.</p><p>That is how a clean product turns into a platform.</p><p>Sometimes that broadening creates a better product. Often it creates a heavier one. We have all seen what happens when a sharp tool keeps absorbing new obligations.</p><p>I am not using &#8220;enshittification&#8221; here as a slogan. I mean something simpler: products accumulate obligations. They stop being allowed to stay narrow. They have to serve more segments, more stakeholders, and more edge cases than they originally did.</p><p>That broadening is one of the main reasons small products can still win in seemingly crowded categories.</p><p>From the outside, a company like Fern looks like a docs competitor. And it is. But it is also increasingly an AI knowledge product. GitBook is a docs competitor, but it is also a workflow and knowledge collaboration product and a customer support bot. Fern is a docs competitor, but it is also an SDK generation product. Docusaurus and Fumadocs are alternatives, but they are really framework choices.</p><p>That leaves room for a narrower thesis.</p><h2><strong>The thesis for DocsAlot</strong></h2><p>The DocsAlot thesis is not &#8220;we will beat everyone by having every feature.&#8221; That is the fastest way to become mediocre.</p><p>The thesis is smaller:</p><ol><li><p><strong>Make good-looking public docs.</strong></p></li><li><p><strong>Keep them in sync as soon as people commit doc changes.</strong></p></li><li><p><strong>Make the docs legible to agents as well as humans.</strong></p></li></ol><p>That sounds almost too small, but I think that is the point.</p><p>There is a lot of demand for a product that does one thing well: take docs-as-code seriously, publish something attractive, keep it updated without ceremony, and generate the adjacent machine-facing assets that now matter.</p><p>Not an internal wiki. Not an all-purpose knowledge platform. Not an everything suite for docs, support, product education, and AI governance.</p><p>Just a sharp, opinionated product for teams that want their docs to look good, stay current, and be easy for both people and agents to consume.</p><p>That is especially interesting to me because the failure mode in docs is often not &#8220;we picked the wrong platform.&#8221; It is &#8220;we stopped maintaining the docs because the workflow was too annoying.&#8221; Or &#8220;the docs were technically there, but the public experience was bad.&#8221; Or &#8220;the product worked for humans but had no machine-readable discovery layer.&#8221; Or &#8220;the framework was flexible, but now we are maintaining a docs stack instead of shipping the product.&#8221;</p><p>A smaller product can take those failure modes more seriously because it is not trying to solve seven adjacent problems at the same time.</p><h2><strong>Competition matters less than clarity</strong></h2><p>The part of Max Rozen&#8217;s argument that stuck with me is that the existence of many competitors does not mean the buyer is seeing all of them clearly. Often they are seeing almost none of them clearly.</p><p>That feels true in docs. Most teams are not running a perfect market scan of every documentation platform and every open-source option. They are taking recommendations from friends, copying the last tool they used, defaulting to whatever their VP of Engineering already knows, or hacking together the path of least resistance.</p><p>That is why I think lack of awareness matters more than competitor count.</p><p>If the product is clear, the setup is simple, the docs look good, the sync story is strong, and the agent-facing artifacts are handled automatically, there is still plenty of room to matter.</p><p>You do not need to &#8220;win the market&#8221; in the abstract. You need to become the obvious answer for one kind of team.</p><p>For DocsAlot, the bet is that there will be more of those teams over time, not fewer:</p><ul><li><p>teams shipping APIs faster because agents make software construction cheaper</p></li><li><p>teams that want docs-as-code, but not a giant internal platform</p></li><li><p>teams that care about aesthetics and readability</p></li><li><p>teams that need docs to be understandable by humans and machines</p></li><li><p>teams that do not want to maintain a custom docs stack forever</p></li></ul><p>If that bet is right, the crowdedness of the category matters less than the direction of the category.</p><p>My read is that the direction is favorable.</p><h2><strong>A final note on &#8220;crowded&#8221;</strong></h2><p>Crowded markets are often good markets.</p><p>They mean the pain is real.</p><p>The more important question is whether the pain is solved cleanly for the specific segment you care about. In docs, I do not think it is. The category already contains strong products, but they are increasingly optimized for different ends: platform breadth, enterprise workflow, API infrastructure, or framework flexibility.</p><p>I think there is still room for a smaller, more opinionated product that treats documentation as a first-class interface layer, keeps it synced to the codebase, and makes the result legible to both people and agents.</p><p>Maybe the market proves me wrong. But &#8220;there are already competitors&#8221; is not a good enough reason not to build.</p><p>If anything, in documentation right now, it is a reason to be more precise about what kind of product you are actually building.</p><h2><strong>References</strong></h2><ul><li><p>Richard Feynman,</p><p><a href="https://calteches.library.caltech.edu/47/2/1960Bottom.pdf">There&#8217;s Plenty of Room at the Bottom: An Invitation to Enter a New Field of Physics</a></p></li><li><p>Max Rozen on operating in a crowded market:</p><p><a href="https://maxrozen.com/on-four-years-running-saas-competitive-market">On four years of running a SaaS in a competitive market</a></p></li><li><p>Docusaurus and Fumadocs as frameworks rather than hosted docs platforms: <a href="https://docusaurus.io/">Docusaurus</a>, <a href="https://docusaurus.io/docs/deployment">Deployment</a>, <a href="https://fumadocs.dev/">Fumadocs</a>, <a href="https://fumadocs.dev/docs">Docs</a></p></li><li><p>https://docsalot.dev</p></li></ul>]]></content:encoded></item><item><title><![CDATA[MCP still matter]]></title><description><![CDATA[Even and especially for Devtools]]></description><link>https://faizank.substack.com/p/mcp-still-matter</link><guid isPermaLink="false">https://faizank.substack.com/p/mcp-still-matter</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Sun, 12 Apr 2026 19:57:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p><strong>TLDR: A good CLI solves part of the problem. It does not solve cross-OS distribution, desktop client compatibility, or non-technical adoption. For Docsalot, MCP matters because it gives us one protocol surface instead of a growing pile of binaries.<br><br><br><br></strong>A good CLI is still worth building. We built one for Docsalot. But a CLI does not remove the need for MCP. In some ways it makes the remaining problem more obvious.</p><p>The reason is simple: once you ship a CLI, you own distribution.</p><p>Not just the npm package or the README. The actual operational surface. macOS. Linux. Windows. Node versions. PATH issues. Shell behavior. Desktop clients that do not want a shell at all. Users who are not comfortable in a terminal. Every one of those becomes part of the product whether you wanted it or not.</p><p>That is the part people skip when they say &#8220;why not just expose a CLI?&#8221;</p><p>A CLI is one interface. MCP is a protocol.</p><p>That difference matters a lot.</p><div><hr></div><h2>What the CLI Solves</h2><p>A CLI is great when the user is already technical and already in a shell.</p><p>For Docsalot, our CLI gave us a clean workflow for:</p><ul><li><p>authenticating with API tokens</p></li><li><p>listing documentations</p></li><li><p>pulling docs locally</p></li><li><p>pushing docs back as a version</p></li><li><p>publishing a version</p></li><li><p>previewing docs locally</p></li></ul><p>That is a real product surface. It is useful. It also maps well to agents that can run terminal commands.</p><p>If the world stopped there, we could have just kept improving the CLI.</p><p>But it does not stop there.</p><div><hr></div><h2>What the CLI Does Not Solve</h2><p>A CLI does not magically become universal just because it exists.</p><p>To make it broadly usable, you still have to answer questions like:</p><ul><li><p>How do we distribute this cleanly across macOS, Linux, and Windows?</p></li><li><p>What runtime assumptions are we making?</p></li><li><p>What happens when the user&#8217;s shell environment is weird?</p></li><li><p>What happens when a desktop AI client does not want to manage a local binary?</p></li><li><p>What happens when the person updating docs is not technical enough to debug <code>PATH</code>, <code>npx</code>, or Node versions?</p></li></ul><p>We ran into exactly this kind of friction while testing the MCP path through desktop clients.</p><p>Even when the Docsalot server was fine, the local environment could still fail in annoying ways:</p><ul><li><p>an old <code>npx</code> being picked from the wrong Node install</p></li><li><p>a client resolving the wrong <code>node</code> binary from <code>PATH</code></p></li><li><p>a remote bridge working on one machine and failing on another</p></li></ul><p>None of those are really &#8220;documentation problems.&#8221; They are packaging and runtime problems.</p><p>That is the hidden tax of a CLI-first distribution model.</p><div><hr></div><h2>The Distribution Problem Is Worse Than It Looks</h2><p>When people say &#8220;just ship a CLI,&#8221; they usually mean &#8220;technical users can figure it out.&#8221;</p><p>That is often true. It is also a weak standard if you want broad adoption.</p><p>A CLI means you are effectively shipping multiple operational experiences:</p><ul><li><p>one for macOS users</p></li><li><p>one for Linux users</p></li><li><p>one for Windows users</p></li><li><p>one for whoever has the wrong language/runtime version installed</p></li><li><p>one for whoever is trying to call your tool through an AI desktop app instead of a shell</p></li></ul><p>Even if the commands are logically the same, the support burden is not the same.</p><p>You do not just have one product anymore. You have the combinatorics of product &#215; operating system &#215; runtime &#215; client behavior.</p><p>That is manageable for a small technical audience.<br>It is not a great default if your goal is: &#8220;connect once and let any compatible client use the workflow.&#8221;</p><div><hr></div><h2>What MCP Changes</h2><p>MCP gives you a stable protocol surface instead of asking every user to adopt your local runtime assumptions.</p><p>That is the key point.</p><p>With a remote MCP server, the client only needs to know how to speak MCP. The server owns the implementation details. The auth model is explicit. The tool schemas are explicit. The request/response format is explicit.</p><p>For our Docsalot docs-management flow, that means we can expose:</p><ul><li><p><code>list_documentations</code></p></li><li><p><code>pull_documentation</code></p></li><li><p><code>push_documentation</code></p></li><li><p><code>publish_documentation</code></p></li></ul><p>as one authenticated surface at <code>/api/cli/v1/mcp</code>.</p><p>Now the integration problem shifts from:</p><p>&#8220;Can this user install and run our binary correctly on this machine?&#8221;</p><p>to:</p><p>&#8220;Can this client talk MCP?&#8221;</p><p>That is a much better question.</p><p>It is narrower. It is more standard. It ages better.</p><div><hr></div><h2>Why This Matters Specifically for Docsalot</h2><p>Docsalot is not just serving docs to engineers in terminals.</p><p>We also care about:</p><ul><li><p>coding agents operating documentation directly</p></li><li><p>desktop MCP clients</p></li><li><p>less technical users making documentation updates without learning a CLI</p></li><li><p>workflows that should behave the same way across different environments</p></li></ul><p>If we stayed CLI-only, we would keep paying the binary tax forever.</p><p>That means:</p><ul><li><p>more packaging work</p></li><li><p>more support work</p></li><li><p>more environment debugging</p></li><li><p>more platform-specific docs</p></li><li><p>more chances for &#8220;works on my machine&#8221; to become part of the user experience</p></li></ul><p>MCP does not make all integration problems disappear. It does remove one big class of them.</p><p>Instead of shipping the same docs-management workflow as multiple binaries and hoping each client environment behaves, we can expose one protocol surface and let MCP-compatible clients connect to it.</p><p>That matters even more when the user is not technical.</p><p>If a product manager, support lead, or founder can connect through a desktop app and update docs without touching a shell, that is not a nice-to-have. That is a real expansion of who can use the system.</p><div><hr></div><h2>This Is Not an Argument Against CLIs</h2><p>CLIs are still useful.</p><p>In our case, the CLI still matters for:</p><ul><li><p>local preview</p></li><li><p>terminal-native workflows</p></li><li><p>direct automation</p></li><li><p>users who want explicit command-level control</p></li></ul><p>The point is not &#8220;MCP replaces the CLI.&#8221;</p><p>The point is that a CLI and an MCP server solve different distribution problems.</p><p>The CLI is for users who want to run your workflow locally.<br>MCP is for users and clients that want a stable protocol surface without inheriting your packaging story.</p><p>Those are not the same thing.</p><div><hr></div><h2>The More Honest Framing</h2><p>I think the more honest way to talk about MCP is this:</p><p>MCP matters when you want one interface to work across many clients without shipping your implementation details to every user environment.</p><p>That is the win.</p><p>For Docsalot, that means we can keep the CLI for local power users and still expose docs management through a protocol that works across MCP-native clients.</p><p>That gives us:</p><ul><li><p>less cross-OS binary overhead</p></li><li><p>less environment-specific breakage</p></li><li><p>better compatibility with desktop clients</p></li><li><p>a more accessible path for non-technical users</p></li></ul><p>Or, more bluntly:</p><p>Connect once, communicate forever is a better distribution model than shipping the same docs workflow as a growing pile of binaries.</p>]]></content:encoded></item><item><title><![CDATA[How to Get a Free Custom Email Address with Cloudflare]]></title><description><![CDATA[You don&#8217;t need Google Workspace.]]></description><link>https://faizank.substack.com/p/how-to-get-a-free-custom-email-address</link><guid isPermaLink="false">https://faizank.substack.com/p/how-to-get-a-free-custom-email-address</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Sun, 08 Mar 2026 16:41:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>You can get a custom email address that forwards to your Gmail inbox for free using Cloudflare&#8217;s Email Routing feature. You can even send from that custom address using Gmail&#8217;s &#8220;Send mail as&#8221; feature. The whole thing costs you nothing except the domain itself.</p><p>Here is the full walkthrough.</p><div><hr></div><h2>What You Need</h2><p>Three things. You probably already have two of them.</p><ol><li><p><strong>A domain name</strong>: $10&#8211;15/year from Namecheap, Porkbun, or any registrar. Budget options like <code>.xyz</code>, <code>.site</code>, or <code>.online</code> run $2&#8211;5/year.</p></li><li><p><strong>A Gmail account</strong>: free.</p></li><li><p><strong>A Cloudflare account</strong>: free.</p></li></ol><div><hr></div><h2>Step 1: Get a Domain</h2><p>If you don&#8217;t have one already, go buy a domain. Namecheap, Porkbun, whatever. Pick something short, memorable, and on-brand for you.</p><p>If you already own a domain, skip ahead.</p><div><hr></div><h2>Step 2: Add Your Domain to Cloudflare</h2><ol><li><p>Sign up at <a href="https://cloudflare.com/">cloudflare.com</a>. The free plan is all you need.</p></li><li><p>Click <strong>&#8220;Add a site&#8221;</strong> and type in your domain.</p></li><li><p>Cloudflare will scan your existing DNS records automatically.</p></li><li><p>It will give you two nameservers. Copy them.</p></li><li><p>Go back to your domain registrar (Namecheap, Porkbun, wherever you bought the domain) and replace the default nameservers with the two Cloudflare gave you.</p></li><li><p>Wait about 5&#8211;10 minutes for DNS propagation.</p></li></ol><p>That&#8217;s it. Your domain is now on Cloudflare. Everything else happens inside their dashboard.</p><div><hr></div><h2>Step 3: Enable Email Routing</h2><p>This is where the magic happens.</p><ol><li><p>In your Cloudflare dashboard, navigate to <strong>Email &#8594; Email Routing</strong>.</p></li><li><p>Click <strong>&#8220;Get Started&#8221;</strong> to enable the feature.</p></li><li><p>Enter your Gmail address as the destination.</p></li><li><p>Cloudflare will send a confirmation email to that Gmail address.</p></li><li><p>Open Gmail, find the email, click the verification link.</p></li></ol><p>Done. Cloudflare now knows where to forward your mail.</p><div><hr></div><h2>Step 4: Create Your Custom Email Addresses</h2><p>Now you get to pick whatever addresses you want.</p><ol><li><p>In the Email Routing section, click <strong>&#8220;Create address.&#8221;</strong></p></li><li><p>Type the local part you want &#8212; <code>hello@</code>, <code>contact@</code>, <code>hi@</code>, <code>support@</code>, <code>sales@</code>, whatever.</p></li><li><p>Select your Gmail as the destination.</p></li><li><p>Click Save.</p></li></ol><p>Repeat this for as many addresses as you want. They are all free. Unlimited. Each one can point to the same Gmail or to different inboxes if you have multiple Google accounts.</p><p>At this point, emails sent to <code>hello@yourdomain.com</code> land in your regular Gmail inbox. That alone is useful. But we can do better.</p><div><hr></div><h2>Step 5: Send FROM Your Custom Email</h2><p>This is the part that makes it feel real. Right now you can <em>receive</em> emails at your custom address, but when you reply, Gmail sends from your <code>@gmail.com</code> address. That&#8217;s ugly. Let&#8217;s fix it.</p><ol><li><p>Open Gmail &#8594; <strong>Settings</strong> &#8594; <strong>See all settings</strong>.</p></li><li><p>Go to the <strong>&#8220;Accounts and Import&#8221;</strong> tab.</p></li><li><p>Under <strong>&#8220;Send mail as&#8221;</strong>, click <strong>&#8220;Add another email address.&#8221;</strong></p></li><li><p>Enter your name and your custom email (e.g., <code>hello@yourdomain.com</code>).</p></li><li><p>On the next screen, Gmail asks for SMTP server details. <strong>This is the part people mess up.</strong></p></li></ol><p>Here is what to enter:</p><p>Field Value <strong>SMTP Server</strong> <code>smtp.gmail.com</code> <strong>Port</strong> <code>587</code> <strong>Username</strong> Your full Gmail address (e.g., <code>you@gmail.com</code>) <strong>Password</strong> A Google App Password (see below)</p><p><strong>Important:</strong> Gmail will pre-populate the SMTP server field with something from Cloudflare&#8217;s MX records. Delete that. Replace it with <code>smtp.gmail.com</code>. If you skip this, it will not work.</p><h3>Getting a Google App Password</h3><p>You need this because Gmail won&#8217;t let you use your regular password for SMTP.</p><ol><li><p>Go to Google Account &#8594; Security</p></li><li><p>Make sure <strong>2-Step Verification</strong> is enabled. (If not, enable it first.)</p></li><li><p>Search for or navigate to <strong>App passwords</strong>.</p></li><li><p>Generate a new app password for &#8220;Mail.&#8221;</p></li><li><p>Copy the 16-character password Google gives you.</p></li><li><p>Paste it into the Gmail SMTP setup from above.</p></li></ol><h3>Finishing Up</h3><ol><li><p>Click <strong>&#8220;Add Account.&#8221;</strong></p></li><li><p>Gmail sends a verification email to your custom address.</p></li><li><p>Cloudflare forwards it right back to your Gmail inbox. (See? The routing is already working.)</p></li><li><p>Enter the confirmation code or click the link.</p></li></ol><p>You can now compose emails in Gmail and choose your custom address in the &#8220;From&#8221; dropdown. Replies to emails received at your custom address will default to sending from that address too.</p><div><hr></div><h2>Step 6: Verify Your DNS Records</h2><p>Cloudflare automatically sets up SPF, DKIM, and DMARC records when you enable email routing. You don&#8217;t need to touch anything manually. But if you want to double-check:</p><ol><li><p>Go to <strong>Cloudflare &#8594; DNS &#8594; Records</strong>.</p></li><li><p>You should see <strong>MX records</strong> pointing to Cloudflare&#8217;s mail servers.</p></li><li><p>You should see <strong>TXT records</strong> for SPF and DKIM already in place.</p></li></ol><p>If something looks wrong, try disabling and re-enabling email routing. That usually resets everything correctly.</p><h3>A Note on DKIM and Deliverability</h3><p>Here is the one honest caveat. Unlike Google Workspace, regular Gmail does not sign outgoing emails with your custom domain&#8217;s DKIM key. This means some recipients, especially stricter corporate mail servers, might flag your messages or land them in spam.</p><p>In practice, I have not had issues. But if you start noticing deliverability problems at scale, that is the point where paying for Google Workspace actually makes sense.</p><div><hr></div><h2>What You End Up With</h2><ul><li><p>Emails sent to <code>hello@yourdomain.com</code> arrive in your normal Gmail inbox.</p></li><li><p>You can reply from that custom address directly in Gmail.</p></li><li><p>You look professional.</p></li><li><p>You pay <strong>$0/month</strong> for email. Just the annual domain cost.</p></li><li><p>No separate storage limits. It is all using your free Gmail storage (15 GB).</p></li></ul><p>That is a professional email setup for roughly <strong>$10/year</strong> instead of $72+/year with Google Workspace.</p><div><hr></div><h2>Limitations</h2><p>This setup is not a full replacement for Google Workspace. Here is where it falls short:</p><ul><li><p><strong>Cloudflare only forwards.</strong> It does not store emails or give you a separate mailbox. If your Gmail goes down, you have no backup.</p></li><li><p><strong>Outgoing emails might hit spam initially</strong> until SPF reputation builds up for your domain.</p></li><li><p><strong>Gmail&#8217;s sending limit is 500 emails/day</strong> from custom addresses. Fine for most people. Not fine if you are doing cold outreach at volume.</p></li><li><p><strong>No DKIM signing on your custom domain.</strong> Covered above &#8212; but worth repeating.</p></li></ul><div><hr></div><h2>That&#8217;s It</h2><p>This is not sponsored by Cloudflare. I just happened to know this method and it felt like the kind of thing worth writing up. If you know other free or cheap hacks like this, I&#8217;d genuinely like to hear about them.</p>]]></content:encoded></item><item><title><![CDATA[Elo Driven Development]]></title><description><![CDATA[The next breakthrough in AI may come from a playground where two outputs fight and a stranger picks the winner]]></description><link>https://faizank.substack.com/p/elo-driven-development</link><guid isPermaLink="false">https://faizank.substack.com/p/elo-driven-development</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Thu, 05 Mar 2026 15:50:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p><strong>In January/26, Arena, the platform formerly known as LMArena, formerly known as LMSYS Chatbot Arena, <a href="https://arena.ai/blog/series-a/">announced a $150 million Series A</a> led by Felicis and UC Investments, with participation from Andreessen Horowitz, Kleiner Perkins, and Lightspeed.</strong> That is on top of the <a href="https://www.prnewswire.com/news-releases/lmarena-raises-150-million-to-build-the-worlds-most-trusted-ai-evaluation-platform-302653012.html">$100 million seed round</a> they closed less than a year earlier. A quarter billion dollars for a platform whose core mechanic is: show two outputs, hide the labels, ask a stranger which one is better.</p><h2>The Core Claim</h2><p>Everyone already agrees that data matters. That is not the argument.</p><p>The argument is this: <strong>the best product for collecting useful model feedback is a blind comparison interface.</strong> Not a benchmark suite. Not a multiple-choice exam. A head-to-head fight in front of a human judge who does not know which model produced which answer.</p><p>Arena proved this for text. Over 50 million votes from real users, across 400+ models, spanning text, vision, code, image, video, and search. The platform started as a PhD research experiment at UC Berkeley. It is now, by funding and by influence, one of the most important pieces of AI infrastructure in the world.</p><p><a href="https://www.designarena.ai/">Design Arena</a>, built by Arcada Labs, is proving it for interface and visual generation. 2.2 million users picking winners across website design, game dev, 3D modeling, data visualization, logo, video, and more, all rated with the same Elo-based Bradley-Terry system. When Claude Opus 4.6 sits at the top of that leaderboard, it is not because Anthropic said so. It is because strangers on the internet, who did not know which model made which output, clicked on it more often.</p><p>The mechanism is the same every time:</p><p>Two answers appear.<br>The user picks one.<br>The system updates rankings.<br>The platform learns what people actually prefer.</p><p>That loop is the point.</p><p></p><p></p><h2>Why This Product Pattern Wins</h2><p>Three things, and they compound.</p><p><strong>First, brand bias disappears.</strong> If users do not know the model name, they judge output quality, not reputation. This matters more than it sounds. There is a well-documented tendency in AI evaluation for people to rate GPT-4 outputs higher when they know it is GPT-4. Remove the label and the rankings shift. Arena&#8217;s entire credibility rests on this insight.</p><p><strong>Second, binary decisions scale.</strong> A/B choices are fast, clear, and cognitively cheap. You do not need an expert to say &#8220;this website looks better.&#8221; You need a lot of people saying it, quickly, and a good statistical model to aggregate. That is exactly what Elo provides.</p><p><strong>Third, evaluation becomes continuous.</strong> Instead of waiting for a quarterly benchmark release (which may not even reflect how people actually use models), arena platforms measure quality in real time. A model that ships an update on Tuesday has new signal on Wednesday.</p><p>This is why teams trust arena-style rankings. They are not perfect. But they track real preference in real time, which turns out to be far more useful than a static leaderboard that measures performance on a fixed test set.</p><p></p><p></p><h2>The Evidence: Follow the Money</h2><p>Arena&#8217;s $250 million in total funding is the most visible signal. But it is not the only one.</p><p>The entire training-data and evaluation stack is <a href="https://www.datagravity.dev/p/rl-environments-for-agentic-ai-who">converging toward the same thesis</a>. <a href="https://scale.com/">Scale AI</a>, the incumbent in post-training data and RLHF, is evolving from raw labeling into workflow-level RL environments. <a href="https://datacurve.ai/">Datacurve</a> runs a &#8220;bounty hunter&#8221; marketplace where skilled engineers tackle complex code and data tasks for frontier model training. <a href="https://mercor.com/">Mercor</a> connects AI labs with domain experts for RLHF. <a href="https://www.surgehq.ai/">Surge AI</a> focuses on expert labeling for reasoning and long-form tasks. <a href="https://www.turing.com/">Turing</a> provides large expert workforces for fine-tuning and evals. <a href="https://invisible.co/">Invisible</a> turns complex, multi-step human workflows into verifiable work traces that function as de facto training environments.</p><p>But here is the key distinction, and it is why this post is not about the training-data ecosystem. Those companies improve models by generating better data. The arena pattern improves models by generating better <em>signal</em>. A blind head-to-head vote does not teach a model what to say. It tells the lab which model already says it better &#8212; and by how much. That is a fundamentally different feedback mechanism: not data supply, but preference measurement. The data companies feed the training loop. The arenas close it.</p><p>The smart money is flowing into both. But the arenas are the part that scales with users rather than annotators, which is why a voting platform can raise a quarter billion dollars.</p><p></p><p></p><h2>Why It Matters for Model Companies</h2><p>Model labs need a reliable way to answer one practical question: <strong>did the last update make users happier, or not?</strong></p><p>Traditional benchmarks answer a different question: did the model get better at tasks we defined in advance? The gap between those two questions is where most evaluation failure lives. A model can improve on MMLU, HumanEval, and every public benchmark while regressing on the things users actually care about: tone, helpfulness, creativity, visual coherence, code that runs on the first try.</p><p>Blind comparison products close that gap. They measure what people prefer, not what a test suite rewards. That is why every major lab now watches Arena rankings obsessively. It is why OpenAI, Google, Anthropic, and a dozen others submit models under codenames before public release. The arena is their pre-launch focus group, except the sample size is in the millions and the methodology is more rigorous than any internal eval.</p><p></p><h2>But what about the objections</h2><p><strong>&#8220;Arena rankings are gameable.&#8221;</strong> True in theory. Model providers can optimize specifically for arena-style prompts. But in practice, the sheer volume and diversity of users makes this harder than gaming a fixed benchmark. 50 million votes from strangers is a harder target to overfit than 1,000 curated test cases.</p><p><strong>&#8220;Human preference is noisy and inconsistent.&#8221;</strong> Also true. But Elo systems are designed precisely for this. They extract a stable signal from many noisy pairwise comparisons. That is literally what the algorithm was built to do, originally for chess, now for language models.</p><p><strong>&#8220;Blind comparison only works for simple outputs.&#8221;</strong> This is the strongest objection. For complex, multi-step agent tasks, a simple A/B vote may not capture quality. That is exactly where players like Halluminate are building: richer evaluation environments where the &#8220;judgment&#8221; is more structured than a single click. The core pattern (human feedback, captured systematically, turned into a ranking signal) still holds. The interface just needs more surface area.</p><p></p><p></p><h2>Elo Driven Development</h2><p>Elo systems are useful here because they do something no static benchmark can: they turn many small pairwise decisions into a ranking that moves with user preference, continuously.</p><p>The development loop for a frontier model increasingly looks like this: train a model, ship it to an arena, watch the Elo rating, identify where it loses, retrain on the gaps, ship again, watch the Elo move. The arena is not just the evaluation layer. It is becoming the development feedback loop itself.</p><p>This is a structural shift.</p><p></p><h2>What Happens if Everyone Behaves Rationally</h2><p>Start with the big labs. If you are OpenAI, Google, or Anthropic, you now have an external scoreboard that your customers, your investors, and your recruits all watch. You cannot ignore it. The rational move is to treat arena rankings as a first-class product metric, right alongside internal evals and revenue. That means submitting every model update to Arena and Design Arena before launch, building internal tooling that correlates Elo movement with architecture changes, and staffing teams whose job is to close gaps that arena data reveals. Some labs are already doing this. Within a year, all of them will be.</p><p>The second-order move is more interesting. If arena rankings drive reputation, and reputation drives enterprise contracts, then labs have an incentive to invest directly in arena infrastructure. Not to manipulate rankings, but to ensure the arenas they depend on remain credible and well-funded. Expect to see labs become strategic partners, data contributors, or even minority investors in arena platforms. Arena&#8217;s Series A investor list (a16z, Kleiner Perkins, Lightspeed) already reads like a who&#8217;s-who of AI lab backers. That is not a coincidence.</p><p>Now consider VCs. The arena pattern has a clear power-law dynamic: the platform with the most users generates the most votes, which produces the most trusted rankings, which attracts more models, which attracts more users. That flywheel favors early movers and makes the category winner-take-most per modality. If you are a VC, the rational play is to identify the emerging arena for each new modality (code, design, video, audio, agentic workflows) and fund the front-runner before the flywheel becomes self-sustaining. Arena and Design Arena are already there for text and visual generation. The next arenas to watch are for agent evaluation, audio, and domain-specific verticals like legal, medical, and finance.</p><p>For startup founders, the calculus is different. Building a general-purpose arena to compete with Arena head-on is probably a losing bet. But building a vertical arena, one that serves a specific modality, domain, or user base, is wide open. Design Arena proved this: you do not need to be Arena to matter. You need a focused judge pool, a clear modality, and enough model coverage to make the rankings useful. The founders who understand this will build arenas for niches that the general platforms cannot serve well. Think: an arena for medical summarization judged by physicians. An arena for contract analysis judged by lawyers. An arena for code review judged by senior engineers. Each is a small market on its own, but the ranking data they produce is extraordinarily valuable to any lab building models for those verticals.</p><p>The final actor is the training-data ecosystem: the Scale AIs and Datacurves of the world. If arena rankings become the scoreboard that matters, then the value of their work rises in direct proportion. Better training data leads to higher Elo. Every point of Elo translates into deals, press, and recruiting advantage for the lab. That makes the data companies direct beneficiaries of the arena economy, and it means they will increasingly price and position their services around Elo improvement as a deliverable, not just data volume.</p><p>Put it all together and you get a new equilibrium: labs compete on arenas, VCs fund the arenas and the data infrastructure around them, founders build vertical arenas for underserved modalities, and data companies sell Elo points instead of labeled rows. The arena becomes the central coordination mechanism for the entire AI improvement stack.</p><p>A quarter billion dollars for a voting interface. The market is telling you that the next breakthrough in AI may come from building a better arena.</p>]]></content:encoded></item><item><title><![CDATA[Anything You Want: A Tiny Book With Big Founder Lessons]]></title><description><![CDATA[Derek Sivers&#8217; book.]]></description><link>https://faizank.substack.com/p/anything-you-want-a-tiny-book-with</link><guid isPermaLink="false">https://faizank.substack.com/p/anything-you-want-a-tiny-book-with</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Tue, 03 Mar 2026 14:44:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>I read one book a month (<a href="https://docs.google.com/spreadsheets/d/1BJRpnOaCwdzyyXzR6ajzYp2B5tkWLHD04IR2KKHLHR4/edit?gid=0#gid=0">here&#8217;s the list</a>), and <em>Anything You Want</em> by Derek Sivers was my February pick. I don&#8217;t usually write essays about the books I read, but this one was so relevant to where I am in my journey that I had to spend some time distilling my notes.</p><p></p><h2>Core Idea: Help First, Money Second</h2><p>One theme repeats throughout the book: <strong>don&#8217;t do things just for money</strong>.</p><p>Money matters because it keeps the work sustainable, but it should not be the point of the work. The point is helping people solve real problems.</p><p>That framing sounds simple, but it changes everything, and it&#8217;s not just indie founder wisdom. PG argues the same thing for funded startups: the best early-stage tactic is an almost pathological focus on making users happy (<a href="https://paulgraham.com/ds.html">https://paulgraham.com/ds.html</a>).</p><p>It changes:</p><ul><li><p>what products you build</p></li><li><p>who you serve</p></li><li><p>what you say no to</p></li><li><p>how you define success</p></li></ul><h2>All Notes</h2><h3>1) Start before you feel ready</h3><p>Sivers makes the case that plans are mostly guesses until customers show up. You only discover what people want by shipping something and listening.</p><p>So instead of thinking big, start with a tiny problem and solve it well.</p><p>Paul Graham makes the <a href="https://paulgraham.com/ds.html">same point</a>, Stripe&#8217;s founders didn&#8217;t wait for signups&#8212;they walked up to people and installed it on their laptops on the spot.</p><p></p><h3>2) Execution beats ideas</h3><p>Ideas are a multiplier of execution. If execution is zero, ideas are zero.</p><p>This is one of the most useful filters for founders: less theorizing, more shipping, more iteration.</p><p>PG&#8217;s version of this: obsessing over a big coordinated launch is a trap&#8212;steady, compounding effort is what actually works.</p><p></p><h3>3) Many small customers create freedom</h3><p>A business dependent on one giant customer is fragile.</p><p>A business with many small customers is resilient. No single customer controls your roadmap, and you can optimize for the majority you truly want to serve.</p><p></p><h3>4) Exclusion is strategy</h3><p>Trying to be everything to everyone usually means being meaningful to no one.</p><p>Be explicit about who your product is for, and who it is not for.</p><p>PG calls this the &#8220;contained fire&#8221; strategy (<a href="https://paulgraham.com/ds.html">https://paulgraham.com/ds.html</a>), Facebook launched as Harvard-only, and building course lists school by school is what made students feel the site was <em>theirs</em>.</p><p></p><h3>5) Build a business that runs without you</h3><p>A strong line in the book is making yourself unnecessary in day-to-day operations.</p><p>If everything depends on you, you own a stressful job. If the system runs without you, you own a business.</p><p></p><h3>6) &#8220;Hell yeah or no&#8221;</h3><p>If you&#8217;re not excited about an opportunity, decline it. Saying yes to everything dilutes your focus. Raising your bar for a yes creates space for the things that actually matter.</p><p></p><h3>7) If it&#8217;s not a hit, switch</h3><p>Success comes from consistently improving and inventing, not from stubbornly promoting what isn&#8217;t working. Sivers compares it to music: when you have a hit song, it promotes itself. When you don&#8217;t, no amount of pushing will save it.</p><p>Persistence matters, but apply it to <em>iterating your way to a hit</em>, not to repeating a failing approach.</p><p></p><h3>8) Little things make all the difference</h3><p>CD Baby answered the phone within two rings. They customized the &#8220;from&#8221; name on emails to say &#8220;CD Baby loves [customer&#8217;s first name].&#8221;</p><p>You don&#8217;t need a huge budget for this. You just need to care enough to add a small moment of delight where nobody expects one.</p><p></p><h3>9) Formalities are fear</h3><p>Stay away from corporate formalities as much as you can. No amount of privacy policy or terms of service is going to save you. There are shops like Jim&#8217;s Shiva Shack earning real money without any of that.</p><p>People will scare you into thinking horrible things will happen if you don&#8217;t do this or that. Most of the time, they won&#8217;t.</p><p></p><h3>10) Your first idea is just one of many options</h3><p>No business goes as planned. Sivers suggests making ten different plans for the same idea i.e. different price points, different markets, different models.</p><p>Realizing the initial choice you made was just one of many brings a kind of weathered wisdom. The same applies to life: there&#8217;s no single correct path, just the one you&#8217;re currently exploring.</p><p></p><h3>11) Start by sharing whatever you&#8217;ve got</h3><p>Don&#8217;t wait until you have something polished. Start by sharing whatever you have, charge something for the effort so the thing can continue, but the starting point is generosity, not perfection.</p><p></p><h2>My Takeaways</h2><p>I&#8217;m walking away with a few practical rules:</p><ul><li><p>Ask customers directly: &#8220;How can I help?&#8221;. That alone simplies the roadmap more than you think. Customers are busy, they don&#8217;t know how anyone can help them. If you simply ask, they will think about it and tell you.</p></li><li><p>Start small and do unscalable things early. (PG&#8217;s <a href="https://paulgraham.com/ds.html">entire essay</a> on doing things that don&#8217;t scale is the VC-backed version of this same instinct.) Derek had half the book devoted to this point.</p></li><li><p>Charge enough to sustain the work. This points relates to infinite games by James Carse. If you want to play an infinite game, you need to make sure the game can continue. That means charging something for your work, even if it&#8217;s not much. (<a href="https://www.amazon.ca/Finite-Infinite-Games-James-Carse/dp/1476731713">https://www.amazon.ca/Finite-Infinite-Games-James-Carse/dp/1476731713</a>)</p></li><li><p>Find your own measure of success. Different people have different definitions. If you don&#8217;t have one, you will be living up to other peoples definition of success.</p></li></ul><p></p><h2>Final Thought</h2><p>The book&#8217;s biggest shift for me is this: if you keep helping real people and keep improving what you ship, direction emerges.</p><p>That&#8217;s enough to begin.</p>]]></content:encoded></item><item><title><![CDATA[Inference as a Service]]></title><description><![CDATA[Why Running an Inference Startup Is So Damn Hard]]></description><link>https://faizank.substack.com/p/inference-as-a-service</link><guid isPermaLink="false">https://faizank.substack.com/p/inference-as-a-service</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Fri, 20 Feb 2026 07:42:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div><hr></div><p>Inference demand is exploding. Inference startups are still getting acquired or shutting down. Both statements are true at the same time.</p><p><strong>TLDR:</strong> most independent inference platforms don&#8217;t fail because demand is weak; they fail because they mistake revenue momentum for economic durability.</p><div><hr></div><h2>The Pattern So far</h2><ul><li><p>BentoML &#8212; acquired</p></li><li><p>Ploomber &#8212; shut down</p></li><li><p>Modelbit &#8212; shut down</p></li><li><p>Replicate &#8212; acquired</p></li><li><p>Lepton AI &#8212; acquired</p></li><li><p>Brev &#8211; acquired</p></li><li><p>Predibase &#8211; acquired </p></li><li><p>Openpipe &#8211; acquired</p></li><li><p>OctoAI &#8211; acquired (raised ~$130M+ before acquisition)</p></li></ul><p>Whether every item remains exactly current by the time you read this matters less than the directional truth: standalone inference providers keep getting pushed toward consolidation.</p><p>Why? Because this is a balance-sheet business pretending to be a pure software business.</p><div><hr></div><h2>A Simple Framework: Three Clocks You Don&#8217;t Control</h2><p>Most founders model one clock (revenue growth). Inference startups live under three:</p><ol><li><p><strong>Cost clock</strong> &#8212; GPU pricing, availability, and model mix can reprice your COGS (cost of goods sold) quickly.</p></li><li><p><strong>Demand clock</strong> &#8212; customer traffic is lumpy, seasonal, and frequently non-linear.</p></li><li><p><strong>Reliability clock</strong> &#8212; enterprise expectations rise faster than your team headcount.</p></li></ol><p>If those clocks drift out of sync, margins collapse. Short run vs long run is the key contrast here.</p><p>In the short run, demand spikes look like PMF.<br>In the long run, only contribution margin quality compounds.</p><div><hr></div><h2>What I Saw Running SlashML</h2><p>This isn&#8217;t just theory for me. I saw it firsthand while building <a href="https://github.com/slashml/magemaker">SlashML</a>.</p><p>We closed multiple pilots, and most of the serious buyer interest looked less like &#8220;self-serve infra&#8221; and more like applied AI services for regulated industries.</p><p>That&#8217;s where a lot of the real money sits: compliance-heavy workflows, integration complexity, and customers who pay for outcomes, not just raw tokens.</p><p>We also got to about <strong>a few Ks in MRR</strong> from GPU reselling.</p><p>On paper, that looked like fast validation.</p><p>In practice, it was fragile economics. Those were not our GPUs, and we could tolerate thinner economics largely because AWS credits absorbed part of the hit. That is useful for learning, but it is not a durable long-term margin model.</p><p>If anything, that experience reinforced the core point: headline revenue is easy to celebrate; durable contribution margin is what determines whether you survive.</p><div><hr></div><h2>The Mechanism (If X, Then Y, Therefore Z)</h2><h3>1) If COGS is volatile, fixed pricing becomes a hidden liability</h3><p>Your effective cost per token/image/second depends on:</p><ul><li><p>GPU contract structure</p></li><li><p>model mix shifts</p></li><li><p>latency SLO overprovisioning</p></li><li><p>regional redundancy requirements</p></li></ul><p>If your customer contracts are static while these inputs move, you are silently repricing your business downward.</p><h3>2) If utilization swings, revenue quality diverges fast</h3><p>Two providers can post similar monthly revenue and be in completely different realities.</p><ul><li><p>One runs a steady, committed base load.</p></li><li><p>The other runs bursty, low-commit, support-heavy traffic.</p></li></ul><p>Same revenue, different survivability.</p><h3>3) If reliability expectations are cloud-level, operating expenses grows before pricing power does</h3><p>Customers expect near-perfect uptime, predictable latency, instant incident response, and multi-region resilience.</p><p>They do not care that your company is 18 people.</p><p>So you staff and build like a much larger cloud org, but you bill like a startup fighting procurement comparisons.</p><h3>4) If you are squeezed upstream and downstream, differentiation has to be real</h3><ul><li><p><strong>Upstream:</strong> model and infrastructure vendors can shift your cost base.</p></li><li><p><strong>Downstream:</strong> buyers benchmark and switch when they perceive parity.</p></li></ul><p>If your pitch is &#8220;we host models too,&#8221; you are a line item, not a platform.</p><p>Therefore Z: consolidation is not an accident; it is the default equilibrium.</p><div><hr></div><h2>&#8220;But Demand Is Huge, So Isn&#8217;t This Fine?&#8221;</h2><p>This is the strongest objection, and it&#8217;s worth taking seriously.</p><p>Yes, demand is huge. Yes, usage is growing. Yes, AI application teams need inference partners.</p><p>What this view gets right: the market is real.</p><p>What it misses: market growth does not forgive bad unit economics. It can actually hide them longer.</p><p>Growth can fund optimism.<br>Only margins fund survival.</p><div><hr></div><h2>&#8220;Can&#8217;t You Just Raise More?&#8221;</h2><p>You can. Many do. The category has absorbed a lot of capital.</p><p>Approximate publicly reported funding (subject to change):</p><ul><li><p><strong>Baseten:</strong> ~$500M+</p></li><li><p><strong>Together AI:</strong> $534M+</p></li><li><p><strong>Modal:</strong> ~$111M</p></li><li><p><strong>Hugging Face:</strong> ~$390M+</p></li><li><p><strong>fal:</strong> ~$500M+</p></li><li><p><strong>Fireworks AI:</strong> ~$327M+</p></li><li><p><strong>RunPod:</strong> ~$20M+</p></li><li><p><strong>Anyscale:</strong> ~$250M+<br></p></li></ul><p>Capital helps, but capital is not a strategy.</p><p>It buys you time to fix pricing, improve mix, and productize reliability. If you don&#8217;t do those things, you are just purchasing a later failure date.</p><div><hr></div><h2>Implications for 2026</h2><p>What reality changed?</p><p>Inference is no longer &#8220;GPU access with a dashboard.&#8221; It is an operations-and-economics game where small mistakes compound quickly.</p><p>What choices now exist?</p><ul><li><p><strong>Path A:</strong> become a deeply integrated platform with pricing power and retention.</p></li><li><p><strong>Path B:</strong> optimize for strategic acquisition while still healthy.</p></li><li><p><strong>Path C:</strong> chase top-line growth without fixing economics and accept the likely outcome.</p></li></ul><p>Who wins?</p><p>Teams that combine technical reliability with ability to raise more. </p><p>Who loses?</p><p>Teams that confuse demand with durability.</p><p>What likely happens next if actors behave rationally?</p><p>More consolidation, fewer true independents, and a clearer split between real platforms and commoditized capacity resellers.</p>]]></content:encoded></item><item><title><![CDATA[Books I read in 2025]]></title><description><![CDATA[Challenge: One book a month for one year]]></description><link>https://faizank.substack.com/p/books-i-read-in-2025</link><guid isPermaLink="false">https://faizank.substack.com/p/books-i-read-in-2025</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Mon, 29 Dec 2025 08:32:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMO1!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46fbc5a8-2ca4-4c7f-9063-364647d12632_720x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This year, I started a challenge to finish one book a month. Because of being full-time on a startup thats constantly dying, I could not read <a href="https://docs.google.com/spreadsheets/d/1BJRpnOaCwdzyyXzR6ajzYp2B5tkWLHD04IR2KKHLHR4/edit?gid=0#gid=0">many books in 2024</a>. </p><p>Reading is something I enjoy, and I always feel like I started reading late, and have a lot to catch up on. <br><br>Therefore, one of the <a href="https://quarter--mile.com/Side-Quests">side quests</a>, I decided on last year, which seemed doable was one book a month. The rule was pretty simple I had to finish one book a month. It doesn&#8217;t matter how much I had already read before-hand, I just have to close the loop and take some notes on the book. <br><br>The first few months were easy, I had multiple books in the pipeline that were more than 50% done. So the first few months was just ticking those off. <br><br>Once my backlog cleared, things became harder around May, where I literally finished &#8220;the mom test&#8221; at 11:45pm on May,31st. The second time things came close to almost-miss was in October, reading &#8220;The will to meaning&#8221; by Viktor Frankl.<br><br>Reading non-fiction was the hardest, as I had to take a bunch of notes, and I couldn&#8217;t read them more than 20 mins at a time. This made October really rough, because, &#8220;The will to meaning&#8221; is literally a collection of lectures. I had even read 40% of it before October, finishing the rest took me almost 25 days, with full focus on the last week. I almost thought about changing the book half-way through, but could not find any other book that I could finish in time.<br><br>I generally, laded on the book by the 2nd week, but sometimes I would make up my mind in the 3rd week. <br><br><br>Fiction and sci/fi were the easiest for me to read, although I wish I had more time with some of them. Especially Ted Chaings books of short stories. This is the best pieces of content I have ever read, will definitely be reading them again. <br><br><br>Finally, one book I didn&#8217;t expect I would like was, &#8220;how to get rich&#8221; by Felix Dennis. I thought it would be a trite biography with a list of steps. But it had that dark British self-depracating humourous tone, that I just could not put the book down. The prose is also super good. Even the advice was followed up with stories of something that actually happened to Felix personally. Would highly recommend to anyone wanting to start their own business. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://faizank.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading faizan khan's blog! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p><h2><br>Books</h2><h4></h4><h4>1. The Three-Body Problem (Book 1)</h4><p>Finished: January 12, 2025<br>Liu Cixin - (10/10)</p><p>Amazing book, blown away by the storyline and the science. Captures incentives and human nature well.</p><p></p><h4>2. Solomon&#8217;s Gold &#8212; The Baroque Cycle (Book 6)</h4><p>Finished: January 20, 2025<br>Neal Stephenson - (7/10)</p><p>A bit long winded and introduction of characters not relevant to the story. Lots of MacGuffins, that were probably not required, at least as far as this book is concerned. Will have to see in the next books though. Better than volume 2, not worse than volume1. volume 1 book 1 is the best so far.</p><p></p><h4>3. The Dark Forest (The Three-Body Problem, Book 2)</h4><p>Finished: February 27, 2025<br>Liu Cixin - (8/10)</p><p>Started slow, the last 1/3rd was amazing. The science is a bit iffy though. But great application of game theory. Not sure if the author knew about the rand orgs research or not. Sad that a few well known character die. Probably the first time, I ve seen a novelist kill someone who was used as a POV person.</p><p></p><h4>4. Poor Charlie&#8217;s Almanack</h4><p>Finished: March 22, 2025<br>Charlie Munger - (8/10)</p><p>Amazing book, a bit dense, and repetition of ideas throughout the lectures. Someone who has read Influence by Cialdini will find the last half a condensed summary of the book. The Good thing is the author uses those as examples of how to apply them in practice.</p><p></p><h4>5. Finite and Infinite Games</h4><p>Finished: April 30, 2025<br>James P. Carse - (6/10)</p><p>Harder than expected. The book felt opaque until later chapters, when the idea of infinite games &#8212; especially when viewed through religion and culture &#8212; finally clicked. There&#8217;s something profound here, but it could have been much shorter. I&#8217;ll likely revisit it.</p><p></p><h4>6. The Mom Test</h4><p>Finished: May 31, 2025<br>Rob Fitzpatrick - (10/10)</p><p>Amazing book. Usually most non-fictions, I believe could be a blogpost. Not this one, this one can be 10 different blogposts. There wasn&#8217;t a single fluff in this book, every chapter was useful. I would change the ordering of the book a bit. But I think the author wanted to give the most value up-front.</p><p></p><h4>7. Randomize</h4><p>Finished: June 26, 2025<br>Andy Weir - (8/10)</p><p>A tight short story with a clever setup and satisfying math. I didn&#8217;t fully buy the ending, but the journey was fun and fast-paced.</p><p></p><h4>8. Story of Your Life and Others</h4><p>Finished: July 25, 2025<br>Ted Chiang - (10/10)</p><p>One of my fav books, especially &#8220;understand&#8221;, &#8220;story of your life&#8221;, and &#8220;hell is the absence of God&#8221;. This is right up there.</p><p></p><h4>9. Pitch Anything</h4><p>Finished: August 29, 2025<br>Oren Klaff - (7/10)</p><p>Somewhat useful, but stretched thin. The core ideas, frame control, hot vs. cold cognition, and enjoying the process, are solid, but could have been delivered in a long blog post. Worth skimming.</p><p></p><h4>10. Do Androids Dream of Electric Sheep?</h4><p>Finished: September 11, 2025<br>Philip K. Dick - (9/10)</p><p>Much better than the movie. The book&#8217;s obsession with empathy, artificial life, and moral ambiguity feels even more relevant now.</p><p></p><h4>11. Exhalation</h4><p>Finished: October 30, 2025<br>Ted Chiang - (10/10)</p><p>Amazing book loved it. Every single short story was on point. Following are notes on each.</p><ul><li><p>&#8220;The Merchant and the Alchemist&#8217;s Gate&#8221; 10/10 (great story on grief)</p></li><li><p>&#8220;Exhalation&#8221; 9/10, the science is a bit iffy but great prose.</p></li><li><p>&#8220;What&#8217;s Expected of Us&#8221; : shorter than expected, but loved the idea.</p></li><li><p>&#8220;The Lifecycle of Software Objects&#8221;, 10/10, aboslutely loved it, will revisit</p></li><li><p>&#8220;Dacey&#8217;s Patent Automatic Nanny&#8221;, 8/10, great idea, could have used some explanation.</p></li><li><p>&#8220;The Truth of Fact, the Truth of Feeling&#8221;. 10/10, again amazing story about langauge and meaning.</p></li><li><p>&#8220;The Great Silence&#8221;, 8/10, too short, but great ideas about comprehension, and what it means to be intelligent.</p></li><li><p>&#8220;Omphalos&#8221;, 7/10, one of the ones that was too loose. More a question of philosophy than anything else.</p></li><li><p>&#8220;Anxiety Is the Dizziness of Freedom&#8221; 10/10, a perfect short story, about free will, parallel universe</p></li></ul><h4></h4><h4>12. The Will to Meaning</h4><p>Finished: November 31, 2025<br>Viktor Frankl - (6/10)</p><p>Extremely dense. This reads more like a lecture series on logotherapy than a narrative book. The central idea, finding meaning even in suffering and the mundane, is important, but the delivery is heavy. I took more notes than I could reasonably synthesize.</p><p></p><h4>13. How to Get Rich</h4><p>Finished: December 2025<br>Felix Dennis - (8/10)</p><p>Far more interesting as a warning than as advice. Dennis is blunt, funny, and unapologetic about the psychological cost of wealth. It&#8217;s less a how-to and more a reminder that money solves fewer internal problems than people expect.</p><p></p><p></p><p></p><h3>Closing Thoughts</h3><p>I&#8217;m increasingly drawn to sci-fi. Themes I like, are questions of meaning, agency, and intelligence.</p><p>A few lines that jump out in this review.</p><ul><li><p>Meaning isn&#8217;t discovered once, it&#8217;s continually constructed.</p></li><li><p>Handstands on the edge of hell.</p></li></ul><p></p><p>Will I do another one this year, 100%. <br><br>Full book list <a href="https://docs.google.com/spreadsheets/d/1BJRpnOaCwdzyyXzR6ajzYp2B5tkWLHD04IR2KKHLHR4/edit?gid=0#gid=0">here</a> </p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://faizank.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading faizan khan's blog! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[App deployment Engines]]></title><description><![CDATA[A brief history]]></description><link>https://faizank.substack.com/p/app-deployment-engines</link><guid isPermaLink="false">https://faizank.substack.com/p/app-deployment-engines</guid><dc:creator><![CDATA[eff-kay]]></dc:creator><pubDate>Mon, 31 Mar 2025 22:06:06 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/d36b83af-d5d5-414d-8f32-1b7dd8db2b4d_2362x1322.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Following is a rough time-line of app-deployment engines. <br><br>1. Heroku (2007)<br>Founded in 2007 (key innovation, buildpack system). Heroku's development definitely slowed down after its acquisition in 2010. <br><br>2. Google App Engine (2008)<br>Google launched its App Engine preview in April 2008, it seems just a year after Heroku's founding. They were focused on enterprise customers. <br><br>3. Netlify (2014) <br>Git-centered workflows focused on static-site generators. It was the good old days of blogging world, where every other day there was a new framework for static site generation.<br><br>4. Vercel (2015)<br>Founded in 2015 by Guillermo Rauch (and officially launched in 2016), Vercel (originally ZEIT) , with focus specifically on frontend deployment workflows (nextjs), not that different from netlify early on. <br><br>5. <a href="http://fly.io/">Fly.io</a> (2016) <br>Took a different approach by focusing on global application deployment<br><br>6. Render (2018)<br>At a first look, just revamped heroku's experience with vercels' UI focus. <br><br>HONOURABLE mentions:<br>Pythonanywhere (2012). I remember it being big among python developers for hosting python apps. Similar to what heroku was for rails app.<br><br>Let me know if I missed anything.</p>]]></content:encoded></item></channel></rss>