<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jose Daniel Leon Ruiz</title>
    <description>The latest articles on DEV Community by Jose Daniel Leon Ruiz (@jdevleon).</description>
    <link>https://dev.to/jdevleon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4136592%2F0c0e5e02-1b52-4df2-9d9d-41229c500302.jpg</url>
      <title>DEV Community: Jose Daniel Leon Ruiz</title>
      <link>https://dev.to/jdevleon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jdevleon"/>
    <language>en</language>
    <item>
      <title>Which project ate my Claude Code quota?</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Thu, 15 Oct 2026 15:15:03 +0000</pubDate>
      <link>https://dev.to/jdevleon/which-project-ate-my-claude-code-quota-1p2a</link>
      <guid>https://dev.to/jdevleon/which-project-ate-my-claude-code-quota-1p2a</guid>
      <description>&lt;p&gt;You're on a flat plan, it's mid-afternoon, and Claude Code tells you you've hit your limit. The usage screen confirms it. What it doesn't tell you is where it went.&lt;br&gt;
If you work on one repo, that's annoying. If you work on four, or you launch subagents, it's the question that matters: which project used it?&lt;br&gt;
So I added a command to &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;Estela&lt;/a&gt;, the open-source CLI I'm building: &lt;strong&gt;estela quota&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it shows
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tokens per project for the &lt;strong&gt;current 5-hour window&lt;/strong&gt; and for &lt;strong&gt;this week&lt;/strong&gt; (Monday to today, in your time zone).&lt;/li&gt;
&lt;li&gt;Input, output, cache read and cache write as separate numbers, because they don't weigh the same.&lt;/li&gt;
&lt;li&gt;This week against the &lt;strong&gt;average of your previous 4 weeks&lt;/strong&gt; over the same stretch of days, so you can tell a heavy week from a normal one.&lt;/li&gt;
&lt;li&gt;Claude Code and Codex shown separately: they draw on different quotas.
There's also a &lt;strong&gt;--json&lt;/strong&gt; flag for scripts, and the same breakdown is a card in the Summary tab of the local dashboard (&lt;strong&gt;estela web&lt;/strong&gt;).
## What it refuses to do
It never tells you how much you have left.
Neither Anthropic nor OpenAI publish their plans' limits, so any "X tokens left" or "you'll run out on Thursday" would be a made-up number. On top of that, anything you use on claude.ai or on another machine counts against the same quota but never touches this disk.
The 5-hour window is labeled as an estimate for the same reason: how its start gets rounded isn't public.
I'd rather show real consumption with an honest caveat than a precise-looking countdown that's wrong.
## Where the numbers come from
Claude Code already writes every session to &lt;strong&gt;~/.claude/projects/&lt;/strong&gt; as JSONL, and Codex to &lt;strong&gt;~/.codex/sessions/&lt;/strong&gt;. Estela reads those files, dedupes repeated turns (Claude Code can write the same turn several times), and maps each session to a project by its working directory. Nothing leaves your machine.
Copilot is left out of this view: its local logs don't record reliable token counts.
## Try it
&lt;strong&gt;npx estela setup&lt;/strong&gt;, then &lt;strong&gt;estela quota&lt;/strong&gt;.
It's free, MIT, zero runtime dependencies. If you've ever burned through a limit and couldn't tell why, I'd like to hear what ate it. And if you find a case where the numbers look wrong, an issue on &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; helps a lot.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Your AI cost dashboard tells you how much. Not why.</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Tue, 13 Oct 2026 20:51:13 +0000</pubDate>
      <link>https://dev.to/jdevleon/your-ai-cost-dashboard-tells-you-how-much-not-why-1hof</link>
      <guid>https://dev.to/jdevleon/your-ai-cost-dashboard-tells-you-how-much-not-why-1hof</guid>
      <description>&lt;p&gt;A cost dashboard tells you how much you spent. It almost never tells you why.&lt;br&gt;
$340 in exploration — an agent re-reading the same three files across five failed attempts before it finds the right approach — looks identical, on most dashboards, to $340 that shipped a feature. Same currency, same token count, completely different story.&lt;br&gt;
A breakdown of Anthropic's enterprise analytics on Finout put it well: the console can tell you how much a workspace spent, but &lt;a href="https://www.finout.io/blog/anthropics-enterprise-analytics" rel="noopener noreferrer"&gt;"what it can't tell you is which human beings caused it"&lt;/a&gt; — or, I'd add, what kind of work caused it. Someone asked for exactly this gap to be closed in a &lt;a href="https://dev.to/pederaa/how-to-track-claude-code-usage-in-2026-built-in-commands-ccusage-and-desktop-dashboards-compared-1kk1"&gt;dev.to comment&lt;/a&gt;: "I want cost by workflow shape: exploration, implementation, review, failed attempts, and rework."&lt;br&gt;
That's a harder thing to build than it sounds.&lt;br&gt;
To classify a session by workflow shape you'd need to correlate agent logs (which you have) with what actually reached a commit (which lives somewhere else entirely — git, not the session file). And even then the signal is messy: not every expensive exploration is waste. Sometimes five failed attempts are what make the sixth one land in two minutes instead of twenty. A shape-based view that treats all "exploration" cost as bad would just train people to stop exploring, which is worse.&lt;br&gt;
Where this is actually useful, I think, is pattern-spotting over weeks, not judging a single session. A project where exploration cost keeps climbing relative to shipped cost is telling you something — maybe the codebase got harder to navigate, maybe the task descriptions got vaguer. A project where it stays flat is probably fine. You only notice either way if cost is tagged with some notion of what the work was, not just a daily total.&lt;br&gt;
It's a line we're exploring for &lt;a href="https://github.com/jdleonruiz/estela-cli?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-workflow-shape" rel="noopener noreferrer"&gt;Estela&lt;/a&gt;, the open-source CLI we're building that already splits AI cost and hours by project from your local Claude Code and Codex logs. Linking cost to commits to tell apart exploration-that-paid-off from exploration-that-didn't is the next question on the list, not one it answers today.&lt;br&gt;
If your dashboard showed cost by workflow shape instead of by day, would you actually change anything?&lt;/p&gt;

</description>
      <category>claude</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why Your AI Cost Dashboard Never Matches Your Invoice</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Thu, 08 Oct 2026 22:56:55 +0000</pubDate>
      <link>https://dev.to/jdevleon/why-your-ai-cost-dashboard-never-matches-your-invoice-4eba</link>
      <guid>https://dev.to/jdevleon/why-your-ai-cost-dashboard-never-matches-your-invoice-4eba</guid>
      <description>&lt;p&gt;If you've ever looked at a token counter after a long session with Claude Code, Codex, or Copilot and tried to reconcile it with your actual bill, you've probably hit a wall. Here's why that number is structurally unreliable, not just imprecise.&lt;br&gt;
&lt;strong&gt;1. Most dashboards show list-price tokens, not what you paid.&lt;/strong&gt;&lt;br&gt;
Anthropic's own docs are explicit about it: spend figures in the Claude Code console "are estimates for analytics purposes" (&lt;a href="https://code.claude.com/docs/en/analytics?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/analytics?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate&lt;/a&gt;). If you're on a flat-rate plan like Max or Copilot Business, there's no per-request price at all — you're paying for a quota, and the tool still shows you an API-equivalent cost that has nothing to do with your invoice.&lt;br&gt;
&lt;strong&gt;2. Cache pricing moves 60-75% between model launches, and nothing recalculates your old numbers.&lt;/strong&gt;&lt;br&gt;
Teams that set quarterly token budgets are already redoing that math by hand after this quarter's model releases changed cache pricing — it's a live complaint on LinkedIn right now, not a hypothetical.&lt;br&gt;
&lt;strong&gt;3. Flat-rate limits track what's reserved, not what's used.&lt;/strong&gt;&lt;br&gt;
Developers have reported burning through a full Claude Max quota in about an hour of work instead of lasting a full day (&lt;a href="https://www.devclass.com/ai-ml/2026/04/01/anthropic-admits-claude-code-users-hitting-usage-limits-way-faster-than-expected/?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate" rel="noopener noreferrer"&gt;https://www.devclass.com/ai-ml/2026/04/01/anthropic-admits-claude-code-users-hitting-usage-limits-way-faster-than-expected/?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate&lt;/a&gt;), and some found their own console analytics blank when they went looking for an explanation (&lt;a href="https://www.theregister.com/2026/01/05/claude_devs_usage_limits/?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate" rel="noopener noreferrer"&gt;https://www.theregister.com/2026/01/05/claude_devs_usage_limits/?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate&lt;/a&gt;). There's no visibility into which project or session actually consumed the quota.&lt;br&gt;
&lt;strong&gt;4. None of the usage dashboards know about your git history.&lt;/strong&gt;&lt;br&gt;
A GitHub Discussions thread on Copilot usage metrics puts it plainly: "I need project-level attribution to charge development costs to the correct application" (&lt;a href="https://github.com/orgs/community/discussions/207634" rel="noopener noreferrer"&gt;https://github.com/orgs/community/discussions/207634&lt;/a&gt;). An open ccusage issue asks for the same thing (&lt;a href="https://github.com/ryoppippi/ccusage/issues/281" rel="noopener noreferrer"&gt;https://github.com/ryoppippi/ccusage/issues/281&lt;/a&gt;). Vendors meter by workspace or seat. Nobody meters by project or client, because that mapping only lives in your repo.&lt;br&gt;
Put together, these four gaps mean the number on your screen and the number on your invoice are measuring different things on purpose, not by mistake.&lt;br&gt;
We ran into this building Estela (&lt;a href="https://github.com/jdleonruiz/estela-cli?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate" rel="noopener noreferrer"&gt;https://github.com/jdleonruiz/estela-cli?utm_source=devto&amp;amp;utm_medium=post&amp;amp;utm_campaign=cost-estimate&lt;/a&gt;), an open-source CLI that reconstructs hours and AI cost per project and client from your local agent logs and git history instead of trusting any single vendor's dashboard. It doesn't solve the pricing-page problem — nothing can, short of vendors publishing real per-request invoices — but it gives you your own numbers to check against theirs.&lt;br&gt;
Have you found a reliable way to reconcile what a tool shows you against what you actually get billed?&lt;/p&gt;

</description>
      <category>claude</category>
      <category>showdev</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Three coding agents, three log formats, three ways to get your hours wrong</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Thu, 01 Oct 2026 16:16:45 +0000</pubDate>
      <link>https://dev.to/jdevleon/three-coding-agents-three-log-formats-three-ways-to-get-your-hours-wrong-4m0m</link>
      <guid>https://dev.to/jdevleon/three-coding-agents-three-log-formats-three-ways-to-get-your-hours-wrong-4m0m</guid>
      <description>&lt;p&gt;Claude Code, Codex and GitHub Copilot all keep a local record of what you did with them. If you bill by the hour, or just want to know what a feature really cost, that record is gold: every turn has a timestamp, and most have a model and token counts.&lt;br&gt;
I've spent the last months turning those files into timesheets for &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;Estela&lt;/a&gt;, an open-source CLI. The hard part wasn't the reporting. It was that each agent stores its history in a different shape, and each shape has a way to quietly give you the wrong number.&lt;br&gt;
Here's what I found, agent by agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code: the same turn, up to five times
&lt;/h2&gt;

&lt;p&gt;Sessions live in &lt;strong&gt;~/.claude/projects/&lt;/strong&gt;, one JSONL file per session. Each line is an event, and assistant turns carry a usage block with input, output and cache tokens.&lt;br&gt;
The trap: a single assistant turn can appear in several rows (I've seen up to five) with identical usage. The file is a stream of updates, not a list of unique turns. Sum usage per row and your cost comes out about &lt;strong&gt;2.9x&lt;/strong&gt; too high on real sessions.&lt;br&gt;
The fix is boring: dedupe by &lt;strong&gt;message.id&lt;/strong&gt; before summing anything. Then, for time, group turns into work blocks: consecutive turns close together belong to the same stretch of work; a long gap starts a new one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex: running totals and cache in the wrong place
&lt;/h2&gt;

&lt;p&gt;Codex writes to &lt;strong&gt;~/.codex/sessions/&lt;/strong&gt;. Token usage arrives in token_count events, and each one carries two values: &lt;strong&gt;last_token_usage&lt;/strong&gt; (this call) and &lt;strong&gt;total_token_usage&lt;/strong&gt; (the session so far).&lt;br&gt;
Trap one: sum the totals and you count every earlier call again on each event. On a real 68-event session that multiplied cost by &lt;strong&gt;6&lt;/strong&gt;. Summing the "last" values matched the final total exactly, which is a nice self-check to keep in your tests.&lt;br&gt;
Trap two is subtler. Codex reports cached tokens inside input_tokens. Anthropic does the opposite and reports cache reads separately. If your code assumes one convention and reads the other, the cached part is billed at full input price and again at the cache price. On real data that turned &lt;strong&gt;$2.17 into $10.03&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Copilot: a log you have to replay
&lt;/h2&gt;

&lt;p&gt;Copilot in VS Code keeps chats per workspace, under &lt;strong&gt;workspaceStorage//chatSessions&lt;/strong&gt;. Older files are plain JSON. Newer ones are JSONL, and they don't contain the chat at all. They contain the changes that built it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kind 0: the initial state&lt;/li&gt;
&lt;li&gt;kind 1: set a value at a path&lt;/li&gt;
&lt;li&gt;kind 2: append to an array (optionally truncating first)&lt;/li&gt;
&lt;li&gt;kind 3: delete
Read only the first line and you get an empty chat. You have to replay every change in order to reach the final state, and only then look at the requests.
Once replayed, time is the easy part: each request has a start timestamp and a &lt;strong&gt;completedAt&lt;/strong&gt;. In agent mode that span can be several minutes of real work that no timer would have caught.
Two decisions I made for Copilot:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inline completions leave nothing on disk.&lt;/strong&gt; That time can only come from commits, so it's labeled estimated, never measured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost stays empty.&lt;/strong&gt; Copilot is a flat subscription. Multiplying tokens by API prices would produce a number nobody paid. An honest blank beats a precise-looking guess.
## The rule that ties it together
Across all three, the principle I ended up with is: &lt;strong&gt;never mix measured and estimated without a label.&lt;/strong&gt; Hours rebuilt from session timestamps are measured. Hours inferred from commits alone (hand-written code, or tools that leave no log) are estimates, and should err on the short side because someone is paying for them.
Same with money. On a flat plan, the real AI cost of a project is your subscription split by how much each project used, not tokens at list price.
## If you're parsing these files yourself&lt;/li&gt;
&lt;li&gt;Claude Code: dedupe by message.id.&lt;/li&gt;
&lt;li&gt;Codex: sum last_token_usage, never the totals; subtract cached tokens from input.&lt;/li&gt;
&lt;li&gt;Copilot: replay the JSONL change log before reading anything.&lt;/li&gt;
&lt;li&gt;Write a test that compares your sum against the agent's own final total when it has one.
Or skip all of it: Estela does this locally, no account, zero dependencies, MIT.
&lt;strong&gt;npx estela setup&lt;/strong&gt;
Code: &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;https://github.com/jdleonruiz/estela-cli&lt;/a&gt;
Gemini CLI is the next agent I'd like to support, and there's an open issue for it. If you know how it stores sessions, a comment there would help a lot. And if you've hit other traps in these logs, I'd love to hear them.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>showdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Hourly billing isn't dead if you can prove the hours</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Tue, 29 Sep 2026 16:00:57 +0000</pubDate>
      <link>https://dev.to/jdevleon/hourly-billing-isnt-dead-if-you-can-prove-the-hours-18nl</link>
      <guid>https://dev.to/jdevleon/hourly-billing-isnt-dead-if-you-can-prove-the-hours-18nl</guid>
      <description>&lt;p&gt;There's a good debate going on about how freelancers should price work now that an AI agent does part of it. Mark Fulton's &lt;a href="https://dev.to/markfulton/freelance-developer-rates-in-2026-how-to-price-work-an-ai-agent-can-half-do-14fc"&gt;Freelance Developer Rates in 2026&lt;/a&gt; makes the case for moving away from hourly billing, and a lot of it is right: you shouldn't invoice hours you no longer spend, and review and judgment are where the value is now.&lt;/p&gt;

&lt;p&gt;But I think hourly billing is getting blamed for a different problem. The problem isn't the unit. It's that almost nobody actually knows their hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  The timer was always the weak part
&lt;/h2&gt;

&lt;p&gt;I bill clients by the hour. For years my "time tracking" was a timer I forgot to start, followed by a Friday afternoon reconstructing the week from memory and git log. Everyone I know who bills hourly does some version of this. The numbers that end up on the invoice are, charitably, estimates.&lt;/p&gt;

&lt;p&gt;That was already shaky before AI. With an agent in the loop it gets worse, because the work doesn't look like typing anymore. It's writing a prompt, reading what comes back, running it, pushing back, reviewing a diff. None of that shows up as keystrokes, and it's exactly the "review and judgment" part everyone agrees is valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent is already keeping the log
&lt;/h2&gt;

&lt;p&gt;Here's the part that surprised me: the agent is a better timekeeper than I ever was.&lt;/p&gt;

&lt;p&gt;Claude Code writes every session to ~/.claude/projects/. Codex writes to ~/.codex/sessions/. Each turn has a timestamp, the model, and the exact token counts. Your git history says what shipped and when. Put those together and you can rebuild where the time went, per project, without anyone starting a timer.&lt;/p&gt;

&lt;p&gt;So instead of "stop billing hours", the option I'd add is: &lt;strong&gt;bill hours you can prove.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What "provable" means in practice
&lt;/h2&gt;

&lt;p&gt;When I started turning those logs into timesheets, three things turned out to matter more than I expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Keep measured and estimated apart.&lt;/strong&gt; Time rebuilt from agent sessions is measured: it has timestamps. Time inferred from commits alone (code written by hand, or with a tool that doesn't leave session logs) is an estimate. Those two should never be added into one number without a label. A client can accept an estimate; what breaks trust is finding out later that a "measured" number was a guess. And when you estimate, err on the short side, because someone is paying for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI cost is a real line item, and it's easy to get wrong.&lt;/strong&gt; If you're on a flat subscription, your real cost per project isn't the sum of tokens at list price, it's the fee split by how much each project used. And the raw logs have traps. In Claude Code transcripts the same turn can appear up to five times with identical usage, so summing rows inflates cost about 2.9x. In Codex, each event carries both a per-call and a running total, and summing the running totals gave me 6x on a real session. Codex also counts cache inside the input tokens, the opposite of Anthropic's format: not subtracting it turned $2.17 into $10.03. If you're going to pass AI cost through to a client, or just decide whether a project is profitable, those multipliers matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Let the client see the evidence.&lt;/strong&gt; "I worked 42 hours" invites a negotiation. "Here are the 42 hours, and each block links to the commits it produced" mostly doesn't. The most useful thing I built was a read-only view I can send a client, where every number drills down to the work behind it.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, hourly or value-based?
&lt;/h2&gt;

&lt;p&gt;Honestly, both, depending on the client. Fixed-scope and outcome pricing are great when the scope is clear. But a lot of real client work is open-ended maintenance, "can you also look at…" requests, and retainers, and for those hours are still the fairest unit anyone has found. What changed is that we can finally measure them instead of reconstructing them on Friday.&lt;/p&gt;

&lt;p&gt;And even if you move to value pricing, you still want the numbers. Knowing that a project took 30 measured hours and $40 of AI is how you find out whether your fixed price was a good idea.&lt;/p&gt;

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

&lt;p&gt;I turned this into an open-source CLI called &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;Estela&lt;/a&gt;. It reads your Claude Code, Codex and GitHub Copilot sessions plus your git history, and rebuilds your hours and AI cost per project and client. It runs entirely on your machine: no account, zero runtime dependencies, MIT licensed, and it never stores the content of your prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npx estela setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It marks measured vs estimated hours, splits a flat subscription across projects, can either absorb the AI cost or pass it through to the client's report, and publishes a read-only panel you can share. Code and docs: &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;https://github.com/jdleonruiz/estela-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you bill by the hour, I'd really like to know how you handle this today, and whether "measured vs estimated" is how you'd want to show time to a client.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>showdev</category>
      <category>freelancing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Our MCP server had been live for weeks. Nobody could see what it did.</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Thu, 24 Sep 2026 14:08:30 +0000</pubDate>
      <link>https://dev.to/jdevleon/our-mcp-server-had-been-live-for-weeks-nobody-could-see-what-it-did-323d</link>
      <guid>https://dev.to/jdevleon/our-mcp-server-had-been-live-for-weeks-nobody-could-see-what-it-did-323d</guid>
      <description>&lt;p&gt;CaptureOneAI's MCP server had been running for weeks with zero signups coming through it. The cause was dumb in hindsight: the server required an API key for everything, including initialize and tools/list, the methods a client uses to ask what are you and what can you do. Neither reads data or spends quota.&lt;br&gt;
Effect: no MCP directory indexing it, since most of them probe by listing. No agent deciding whether it's worth connecting. No developer evaluating it. A catalog you have to register for before you can read it isn't a catalog.&lt;br&gt;
The fix: a whitelist of description-only methods now answers without a key. tools/call still requires one, so nothing billable is exposed, and the check runs over every message in a batch, so you can't smuggle a tools/call in behind a tools/list. Verified locally: initialize without a key returns 200 and responds, tools/list without a key returns 200 and lists the six tools, tools/call without a key returns 401, and a batch of tools/list plus tools/call without a key also returns 401.&lt;br&gt;
Then we published to the official MCP registry, the one backed by Anthropic, GitHub, PulseMCP and Microsoft, that feeds downstream directories and aggregators. For a remote server there's no package to publish, just metadata plus proof of domain ownership, which meant a namespace matching our domain in reverse and a DNS TXT record before the registry would accept it.&lt;br&gt;
Two papercuts worth remembering for next time. The tool description silently has a 100 character limit the JSON schema doesn't declare (ours was 217, trimmed to 94), and the MCP server's container image doesn't ship curl, so its deploy health check needed to probe from the host instead of inside the container like the other services.&lt;br&gt;
Published: com.captureoneai/web-perception 1.0.0, status active.&lt;br&gt;
captureoneai.com&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>api</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>My AI coding agent already logs my hours. I turned that into a time and AI-cost tracker</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Wed, 23 Sep 2026 14:00:55 +0000</pubDate>
      <link>https://dev.to/jdevleon/my-ai-coding-agent-already-logs-my-hours-i-turned-that-into-a-time-and-ai-cost-tracker-2hd7</link>
      <guid>https://dev.to/jdevleon/my-ai-coding-agent-already-logs-my-hours-i-turned-that-into-a-time-and-ai-cost-tracker-2hd7</guid>
      <description>&lt;p&gt;If you code with Claude Code, you probably can't answer two simple questions: how many hours did the last feature take, and how much did the AI cost for it?&lt;br&gt;
Time trackers don't help. A stopwatch you have to remember to start always fails, and nobody wants to install something that watches their terminal.&lt;br&gt;
So I built Estela, an open-source CLI that answers both questions from files that already exist on your disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: read what's already written
&lt;/h2&gt;

&lt;p&gt;Two artifacts already record almost everything you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code session files.&lt;/strong&gt; Claude Code saves every session locally, with the model and exact token counts. Estela reads when, how much and with which model. It never stores the content of your prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your git history.&lt;/strong&gt; Estela reads it with git log and matches commits to sessions by timestamp, author and branch. No hooks installed, nothing added to your commit messages. Husky and lefthook stay untouched.
## Measured vs. estimated, never mixed
Not every hour comes from an AI session. If you coded by hand, or with an agent Estela can't read yet (Codex, Cursor, Copilot, Gemini CLI, Aider), your commits are still a trail. Estela infers time from them and labels it as &lt;strong&gt;estimated&lt;/strong&gt;. Hours from Claude Code sessions are labeled &lt;strong&gt;measured&lt;/strong&gt;.
That distinction matters more than it looks: a report is only useful if you know which numbers are real and which are guesses.
## The real cost of AI is not the sum of tokens
If you're on a flat subscription, adding up token prices gives you a number you never paid. Estela prorates your actual subscription across what you consumed, and counts cache separately, because cache is usually the biggest chunk of the bill.
The result: effort per feature, in human hours and in AI money, attributed to the same piece of work.
## A dashboard your client can actually use
Instead of attaching a PDF timesheet, you share a read-only link. Every number drills down to the commits behind it.
And no vanity metrics: no lines of code, no commit counts, no productivity scores. Effort per feature, rewrites, pace and unmerged work.
## Try it
It runs fully local, with no account and no card. The code is open source (MIT) and has zero dependencies. Requires Node 22.5+.
&lt;strong&gt;npx estela setup&lt;/strong&gt;
Then &lt;strong&gt;npx estela web&lt;/strong&gt; opens the dashboard. If you're already in Claude Code, there's also a plugin, and /estela:demo fills a dashboard with fake data so you can see what it does before letting it near your history.
Sample dashboard: &lt;a href="https://getestela.dev/demo" rel="noopener noreferrer"&gt;https://getestela.dev/demo&lt;/a&gt;
Code: &lt;a href="https://github.com/jdleonruiz/estela-cli" rel="noopener noreferrer"&gt;https://github.com/jdleonruiz/estela-cli&lt;/a&gt;
## What I'd love feedback on
Today Estela only reads Claude Code sessions. Which agent should it support next? And if you bill clients for AI-assisted work: how do you handle the AI cost today?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>showdev</category>
    </item>
    <item>
      <title>We killed the screenshot-and-paste habit (one permalink at a time)</title>
      <dc:creator>Jose Daniel Leon Ruiz</dc:creator>
      <pubDate>Tue, 22 Sep 2026 21:20:55 +0000</pubDate>
      <link>https://dev.to/jdevleon/we-killed-the-screenshot-and-paste-habit-one-permalink-at-a-time-52jk</link>
      <guid>https://dev.to/jdevleon/we-killed-the-screenshot-and-paste-habit-one-permalink-at-a-time-52jk</guid>
      <description>&lt;p&gt;&lt;strong&gt;The most annoying part of demoing an AI tool used to be this:&lt;/strong&gt; you get a great answer, you want to show someone, and your only move is... a screenshot. Cropped weird. Text half cut off. Pasted into a Slack thread to die.&lt;br&gt;
Not anymore. Every answer in CaptureOneAI's playground now gets its own shareable permalink — click one button and you've got a clean, public link to that exact result. No screenshot, no paste, no "wait let me resend that."&lt;br&gt;
It sounds small. It isn't. It's the difference between telling a teammate "trust me, it found this" and just... showing them.&lt;br&gt;
Under the hood: a new database model for shared answers, a dedicated route to serve them, and yes — they're in the sitemap too, because a good answer deserves to be found.&lt;br&gt;
Try it at captureoneai.com — ask something, hit share, send the link.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>saas</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
