<?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: Attri</title>
    <description>The latest articles on DEV Community by Attri (@attriofficial2026).</description>
    <link>https://dev.to/attriofficial2026</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%2F3843496%2F666d5b9a-c181-4781-9b13-9bf779f725ee.jpeg</url>
      <title>DEV Community: Attri</title>
      <link>https://dev.to/attriofficial2026</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/attriofficial2026"/>
    <language>en</language>
    <item>
      <title>Building a Ledger for AI Agents: OpenLedger's 15 MCP Tools, Immutable Transactions, and Why the Audit Log Lives in the Same DB Transaction as the Write</title>
      <dc:creator>Attri</dc:creator>
      <pubDate>Mon, 07 Sep 2026 03:04:00 +0000</pubDate>
      <link>https://dev.to/attriofficial2026/building-a-ledger-for-ai-agents-openledgers-15-mcp-tools-immutable-transactions-and-why-the-4kbf</link>
      <guid>https://dev.to/attriofficial2026/building-a-ledger-for-ai-agents-openledgers-15-mcp-tools-immutable-transactions-and-why-the-4kbf</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Today Attri is open-sourcing OpenLedger — a local-first, double-entry accounting system with an MCP server on top. Python 3.11+, SQLite, aiosqlite. 15 tools exposed over MCP. Immutable transactions. Corrections via contra posting. Every mutation writes an audit-log row in the same DB transaction as the mutation itself. Apache 2.0.&lt;/p&gt;

&lt;p&gt;Below: the architecture, the four invariants we enforce in code, the MCP tool surface, a working walk-through, and the tradeoffs we deliberately made (single-currency v1, no ORM, no admin UI).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Attri-Inc/open-ledger" rel="noopener noreferrer"&gt;https://github.com/Attri-Inc/open-ledger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this exists&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you've ever tried to put an AI agent on a financial workflow, you know the shape of the problem. The agent works fine. The agent gets fast. And then someone with an auditor hat on shows up and asks "prove what the agent actually did."&lt;/p&gt;

&lt;p&gt;The audit trail in most accounting stacks lives in a different system from the write. Datadog. Splunk. A Postgres logs table nobody reads. When the write succeeds and the log fails — or vice versa — you have a gap that a real auditor will find in five minutes.&lt;/p&gt;

&lt;p&gt;OpenLedger's whole design is organized around one guarantee: you cannot have a successful mutation without a matching audit-log row, because both live inside the same SQL transaction. Either both commit or both roll back. There is no other outcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture at a glance&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
┌─────────────────────────────────────┐

│          SQLite ledger              │

│  accounts · transactions ·          │

│  entry_lines · audit_log · settings │

└──────────────────┬──────────────────┘

                   │

                   ▼

         MCP server (stdio / SSE :8791)

         15 tools — reads + safe writes

                   │

                   ▼

         Claude Desktop, Claude Code,

         agent frameworks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layering:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/

├── domain/          # pure constants + typed errors (no I/O)

├── infrastructure/  # DB connection, Unit of Work, id/clock helpers

├── repositories/    # protocols.py — narrow Reader/Writer contracts

│                    # sqlite.py    — the only code that writes SQL

├── services/        # accounts · ledger · reports · audit · query

├── serialization.py # response/error envelope helpers

├── container.py     # composition root

└── mcp_server.py    # thin MCP transport adapter

run_mcp.py           # stdio entry point
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four invariants (enforced, not documented)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Double-entry, atomic, at the write path&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every transaction has ≥ 2 entry lines. sum(debits) == sum(credits). Enforced inside a single DB transaction. If the balance check fails, the whole insert rolls back. There is no "post now, validate later" mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integer minor units (cents). No floats.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every amount is an integer. 25000 is $250.00. 500 is $5.00. If you've ever debugged floating-point rounding in a general ledger, you know why this matters. Decimal types are fine in principle; integer minor units are unarguable in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immutability. Corrections via contra posting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transactions and entry lines are never updated or deleted. If a transaction is wrong, you post a contra transaction that reverses it. reverse_transaction(txn_id) is the tool. UPDATE and DELETE on transactions or entry_lines do not exist in the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Audit log in the same DB transaction as the mutation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;unit_of_work&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_transaction&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;  &lt;span class="c1"&gt;# mutation
&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;audit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;             &lt;span class="c1"&gt;# audit-log row
&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;unit_of_work&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;         &lt;span class="c1"&gt;# both or neither
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Either both writes commit, or both roll back. The audit log cannot lag behind reality. The mutation cannot slip past the audit trail. This is the SOX-grade guarantee.&lt;/p&gt;

&lt;p&gt;The MCP tool surface (15 tools)&lt;/p&gt;

&lt;p&gt;• Accounts: list_accounts, get_account, get_balance, get_account_ledger, create_account&lt;/p&gt;

&lt;p&gt;• Journal: get_transaction, search_transactions, post_transaction, transfer_funds, reverse_transaction&lt;/p&gt;

&lt;p&gt;• Reports: get_trial_balance, get_profit_loss, get_balance_sheet&lt;/p&gt;

&lt;p&gt;• Audit: get_audit_log&lt;/p&gt;

&lt;p&gt;• Escape hatch: run_query (SQL SELECT only) — for questions we didn't anticipate&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Walk-through: from clone to your first query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Attri-Inc/open-ledger

&lt;span class="nb"&gt;cd &lt;/span&gt;open-ledger

python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate

pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

python scripts/seed.py          &lt;span class="c"&gt;# bootstrap fresh dev DB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect it to Claude Desktop / Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python run_mcp.py               &lt;span class="c"&gt;# stdio transport (default)&lt;/span&gt;

&lt;span class="c"&gt;# for Claude Code:&lt;/span&gt;

claude mcp add openledger &lt;span class="nt"&gt;-s&lt;/span&gt; user &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;

  /absolute/path/to/open-ledger/.venv/bin/python &lt;span class="se"&gt;\&lt;/span&gt;

  /absolute/path/to/open-ledger/run_mcp.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once connected, ask Claude questions in plain English:&lt;/p&gt;

&lt;p&gt;• "How much cash do we have right now?"&lt;/p&gt;

&lt;p&gt;• "Show me the P&amp;amp;L for January."&lt;/p&gt;

&lt;p&gt;• "Are the books balanced?"&lt;/p&gt;

&lt;p&gt;• "Post a $250 cash sale for today."&lt;/p&gt;

&lt;p&gt;• "Move $500 from Wallet A to Wallet B."&lt;/p&gt;

&lt;p&gt;• "What was reversed recently, and why?"&lt;/p&gt;

&lt;p&gt;Design decisions worth naming (and defending)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why not an ORM?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Considered SQLAlchemy. Passed. Two reasons: (1) The invariants (debits == credits, atomic audit-log write) are enforced inside a single SQL transaction that's much easier to reason about without an ORM's implicit session semantics. (2) Swapping SQLite for Postgres should be a repository-file change, not a full ORM migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why SQLite, not Postgres from day one?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SQLite is embedded, zero-config, most-deployed database in history. For a single-tenant, single-node ledger — which is the shape of most finance-team-owned deployments — it is not a compromise. It is the right choice. The repository layer is designed so that swapping in Postgres touches two files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Apache 2.0, not MIT or AGPL?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• AGPL scares enterprise legal reviewers. Makes commercial embedding legally fraught.&lt;/p&gt;

&lt;p&gt;• MIT is fine but weaker on patent grants.&lt;/p&gt;

&lt;p&gt;• Apache 2.0 gives enterprise-legal acceptance without the AGPL copyleft trap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why MCP, given how young the spec is?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP is early. Anthropic-originated. There is real risk. We bet on it anyway because it's the first serious attempt at a standard for how an agent talks to a system it doesn't own. If MCP turns out to be a dead-end in 18 months, the ledger and its business rules survive; the MCP server is a ~100-line adapter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's not in v1 (deliberately)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• Multi-currency. Single-currency only for now.&lt;/p&gt;

&lt;p&gt;• Postgres backend. SQLite is day-one; Postgres is roadmap.&lt;/p&gt;

&lt;p&gt;• Admin UI. Everything is MCP or SQL.&lt;/p&gt;

&lt;p&gt;• Document ingestion pipeline. Bring your own invoice-parsing / OCR / receipt-extraction.&lt;/p&gt;

&lt;p&gt;• Tax / GAAP / IFRS modules. Not core. Layer on top.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Four commands to a running ledger. Two commands to connect it to Claude. Ten seconds to your first "how much cash do we have?" question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/Attri-Inc/open-ledger" rel="noopener noreferrer"&gt;https://github.com/Attri-Inc/open-ledger&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you build something interesting on top of it, please share. If you find a bug, please file. If the invariants feel wrong, please argue with us in an issue — we'd rather have that conversation now than after ten teams have built on top of a bad primitive.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>We Built an Open-Source CRM for AI Agents — Here's Why</title>
      <dc:creator>Attri</dc:creator>
      <pubDate>Thu, 26 Mar 2026 16:20:33 +0000</pubDate>
      <link>https://dev.to/attriofficial2026/we-built-an-open-source-crm-for-ai-agents-heres-why-3ffg</link>
      <guid>https://dev.to/attriofficial2026/we-built-an-open-source-crm-for-ai-agents-heres-why-3ffg</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;We Built an Open-Source CRM for AI Agents — Here’s Why&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Traditional CRMs were designed for humans clicking buttons. With 6,400+ MCP servers and AI agents entering every enterprise workflow, it’s time for infrastructure that’s built for them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you’re building AI agents that interact with business data, you’ve probably hit the same wall we did.&lt;/p&gt;

&lt;p&gt;Your agent can call APIs, generate text, and reason over documents — but where does it store what it knows? Where does it persist contacts, deals, interactions, and the evidence behind every claim? How does it handle conflicting information without silently overwriting the truth?&lt;/p&gt;

&lt;p&gt;Most teams wire up a vector database and call it memory. That works for semantic search. It doesn’t work when you need to know the exact deal value, who the decision maker is, and which email confirmed it — with a full audit trail.&lt;/p&gt;

&lt;p&gt;We needed something better. So we built it and open-sourced it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open Tooling CRM: The Technical Case&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Tooling CRM is a headless, local-first CRM designed for AI agents as the primary users. No UI. No cloud dependencies. Just a SQLite-backed data layer with two clean interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;REST API — 29 endpoints. Standard HTTP/JSON with consistent pagination, filtering, idempotency keys, and Zod validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MCP Server — 27 tools purpose-built for Claude Desktop, Claude Code, and any MCP-compatible client. Entities, relationships, artifacts, observations, briefs, conflicts, graph traversal, FTS, import/export.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Evidence Chain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The core differentiator is the memory layer. Instead of flat fields that get overwritten, Open Tooling CRM implements a four-level evidence chain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifacts (raw evidence: emails, transcripts, documents)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;↓ extraction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Observations (typed claims with lifecycle: current → superseded / retracted)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;↓ derivation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Briefs (summaries that cite observations — always regeneratable)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;↓ detection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Conflicts (when observations disagree — never silently resolved)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every observation links to its source artifact. Every brief cites its observations. Every conflict references the disagreeing claims. Progressive retrieval means agents start with the brief and drill down to raw evidence when needed.&lt;/p&gt;

&lt;p&gt;This isn’t academic — it’s practical. When your agent says “budget is $250K,” you can trace that through the observation to the artifact (the email from the prospect’s CFO on March 3rd). When the budget changes, the old observation is superseded, not deleted. The audit trail is preserved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Agent Client → MCP Tools → OpenCRM Core → SQLite&lt;/p&gt;

&lt;p&gt;Agent Client → REST API  → OpenCRM Core → SQLite&lt;/p&gt;

&lt;p&gt;Both interfaces share the same core. All writes produce immutable events in an append-only ledger. Data model: typed entities with JSON properties, directed relationships, field-level provenance, FTS index, and the full memory layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Tools at a Glance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Entities: create_entity, update_entity, get_entity, search_entities, archive_entity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Relationships: link_entities, unlink_entities, list_relationships, traverse_graph&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory: ingest_artifact, add_observation, list_observations, supersede_observation, retract_observation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Briefs: create_brief, get_brief, list_briefs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conflicts: create_conflict, get_conflict, list_conflicts, resolve_conflict&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data: export_data, import_data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Headless?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No bundled UI is a deliberate architectural choice. CRMs that couple their data layer to a rigid frontend create lock-in by design. Open Tooling inverts this: the API is the product.&lt;/p&gt;

&lt;p&gt;Three ways to use it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Agent-only. Connect the MCP server to Claude Desktop. Your CRM interface is natural language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vibe-code a frontend. Tell Claude or Cursor: “Build me a React dashboard for my deals pipeline using the Open Tooling CRM API at localhost:8787.” The API is conventional enough that any code-gen tool can scaffold a working UI in minutes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate into your stack. It’s a REST API — connect it to anything.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part of a Bigger Vision&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Tooling CRM is the first module in Open Tooling — an open-source family of AI-native SaaS tools. The same architecture (headless, local-first, evidence-based, MCP-native) applies across verticals like HR, Finance, Project Management, Procurement, and beyond.&lt;/p&gt;

&lt;p&gt;We also ship a Claude plugin marketplace (Attri-Inc/open-tooling-plugins). Install it and Claude gets the knowledge layer to use Open Tooling CRM optimally — the right ingestion patterns, the evidence chain, progressive retrieval, conflict resolution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Start&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/Attri-Inc/open-tooling.git" rel="noopener noreferrer"&gt;https://github.com/Attri-Inc/open-tooling.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;cd open-tooling/crm&lt;/p&gt;

&lt;p&gt;npm install &amp;amp;&amp;amp; cp .env.example .env&lt;/p&gt;

&lt;p&gt;npm run dev    # REST API at localhost:8787&lt;/p&gt;

&lt;p&gt;npm run seed   # Sample data&lt;/p&gt;

&lt;p&gt;npm run mcp    # MCP server (stdio)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use It with Claude (Zero Config)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the MCP config to Claude Desktop or Claude Code. 27 tools, full evidence chain, natural language CRM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Cowork Plugin:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One-click install via our plugin marketplace. Gives Claude the knowledge layer for optimal usage — ingestion patterns, evidence chain workflow, progressive retrieval, conflict resolution.&lt;/p&gt;

&lt;p&gt;Cowork setup: Customize → Add plugin → Add marketplace → Attri-Inc/open-tooling-plugins → Sync.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[GIF: Claude Cowork plugin install — showing the marketplace setup flow]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⭐ GITHUB: github.com/Attri-Inc/open-tooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 PLUGIN MARKETPLACE: github.com/Attri-Inc/open-tooling-plugins&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache 2.0 licensed. Contributions welcome.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on Attri AI Substack [link].&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built by Attri AI. We build AI-native tools for enterprises.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>webdev</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
