<?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: Tarkan Bulut</title>
    <description>The latest articles on DEV Community by Tarkan Bulut (@bulutarkan).</description>
    <link>https://dev.to/bulutarkan</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%2F4174043%2Fdaab27df-d166-4186-9c10-642e77e83e0e.jpg</url>
      <title>DEV Community: Tarkan Bulut</title>
      <link>https://dev.to/bulutarkan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bulutarkan"/>
    <language>en</language>
    <item>
      <title>I Work in Marketing. Here's Why I Started Building My Own Software.</title>
      <dc:creator>Tarkan Bulut</dc:creator>
      <pubDate>Sat, 10 Oct 2026 11:27:46 +0000</pubDate>
      <link>https://dev.to/bulutarkan/i-work-in-marketing-heres-why-i-started-building-my-own-software-4g0p</link>
      <guid>https://dev.to/bulutarkan/i-work-in-marketing-heres-why-i-started-building-my-own-software-4g0p</guid>
      <description>&lt;p&gt;I didn't start learning software development because I wanted to change careers.&lt;/p&gt;

&lt;p&gt;I started because I was tired of solving the same problem in five different tabs.&lt;/p&gt;

&lt;p&gt;My day job is in performance marketing. Campaigns, lead quality, conversion tracking, CRM workflows, reporting, and the conversations that eventually turn an inquiry into a customer. From the outside, that sounds like a collection of marketing tools. In practice, it's a collection of systems that rarely agree on what happened.&lt;/p&gt;

&lt;p&gt;And at some point, I stopped asking which tool we should buy next and started asking whether I could build the missing piece myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The campaign wasn't the whole story
&lt;/h2&gt;

&lt;p&gt;Imagine this fairly ordinary journey:&lt;/p&gt;

&lt;p&gt;Someone clicks an ad. They fill out a form. The lead enters a CRM. A salesperson follows up. The customer asks questions on WhatsApp. Weeks later, a deal might close.&lt;/p&gt;

&lt;p&gt;Each system can tell you something about that journey. None of them necessarily tells you the whole story.&lt;/p&gt;

&lt;p&gt;An advertising dashboard knows what a lead cost. A CRM knows who owns the lead and which stage they're in. A messaging system holds much of the actual conversation. A spreadsheet might be where someone finally tries to connect the dots.&lt;/p&gt;

&lt;p&gt;You can run a successful campaign and still have no easy answer to a basic question: &lt;strong&gt;Did the people we reached become good opportunities?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question sent me further into software than any programming tutorial did.&lt;/p&gt;

&lt;h2&gt;
  
  
  I wanted fewer handoffs, not another dashboard
&lt;/h2&gt;

&lt;p&gt;At first, the fixes were small.&lt;/p&gt;

&lt;p&gt;A report that pulled the same numbers together without copying them by hand. A CRM rule that moved a record when the right conditions were met. A script that flagged something a human should check instead of waiting for someone to notice it.&lt;/p&gt;

&lt;p&gt;Then the questions got more interesting.&lt;/p&gt;

&lt;p&gt;Could we see what was happening across sales conversations without opening every individual chat? Could an internal tool give people the context they needed without giving everyone access to everything? Could we make the customer experience less dependent on someone remembering which system to update?&lt;/p&gt;

&lt;p&gt;Those questions led me into APIs, data models, web interfaces, permissions, and eventually mobile apps.&lt;/p&gt;

&lt;p&gt;I didn't approach them like a software engineer designing a grand architecture. I approached them like a person trying to get through Tuesday without losing track of a customer.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;A technically impressive system isn't necessarily useful. A useful system takes one painful piece of work and makes it boring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Marketing turned out to be a surprisingly good place to learn engineering
&lt;/h2&gt;

&lt;p&gt;Marketing teaches you to think in sequences.&lt;/p&gt;

&lt;p&gt;An impression becomes a click. A click becomes a form submission. A submission becomes a conversation. A conversation might become revenue.&lt;/p&gt;

&lt;p&gt;Software makes you ask what happens between those steps.&lt;/p&gt;

&lt;p&gt;What if the webhook is delivered twice? What if the CRM owner changes? What if the messaging service disconnects? What if a date is saved in one time zone and displayed in another? What if the dashboard says "success" but the underlying operation never completed?&lt;/p&gt;

&lt;p&gt;These aren't abstract edge cases when real people are relying on the system. They're the difference between a workflow that works in a demo and one that survives a normal workday.&lt;/p&gt;

&lt;p&gt;I started paying more attention to error states, retries, logs, and permissions than to how impressive a feature looked on a screenshot.&lt;/p&gt;

&lt;p&gt;Maybe that's the biggest shift: marketing asks whether a process converts. Engineering asks whether it behaves correctly even when the happy path breaks. You need both.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI made building faster, but it didn't make judgment optional
&lt;/h2&gt;

&lt;p&gt;AI coding tools changed how quickly I could move from an idea to something testable.&lt;/p&gt;

&lt;p&gt;I could describe a workflow, inspect a first implementation, see where it broke, and iterate without spending weeks getting comfortable with every library involved.&lt;/p&gt;

&lt;p&gt;That speed is real. So is the temptation to confuse speed with reliability.&lt;/p&gt;

&lt;p&gt;An agent can generate a plausible integration that handles the main use case and quietly ignores duplicate events. It can write a dashboard that looks polished while the underlying metrics are defined inconsistently. It can automate a browser without knowing whether the last click really saved anything.&lt;/p&gt;

&lt;p&gt;So I developed a different habit: ask what can go wrong before asking what else we can add.&lt;/p&gt;

&lt;p&gt;I want to know what the tool is allowed to touch, what happens when it fails, whether we can verify the result, and how to reverse a change.&lt;/p&gt;

&lt;p&gt;AI can help me write and understand code. It cannot take responsibility for the business process on the other end of that code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The most valuable automation is often invisible
&lt;/h2&gt;

&lt;p&gt;There's a certain satisfaction in building something flashy. I get that.&lt;/p&gt;

&lt;p&gt;But the automation I'm happiest with is usually the one nobody talks about after it's deployed.&lt;/p&gt;

&lt;p&gt;A record reaches the right person. A status stays accurate. A notification appears only when someone needs to act. A report answers the same question every Monday without anyone rebuilding it from scratch.&lt;/p&gt;

&lt;p&gt;No one opens a meeting by celebrating the absence of a broken workflow.&lt;/p&gt;

&lt;p&gt;That's probably a sign it worked.&lt;/p&gt;

&lt;p&gt;It also changed how I think about buying software. I still use plenty of existing products, and building everything yourself would be a terrible use of time. The goal isn't to replace every subscription with a custom application.&lt;/p&gt;

&lt;p&gt;The goal is to recognize the gaps that matter enough to fix.&lt;/p&gt;

&lt;p&gt;Sometimes that means configuring a tool properly. Sometimes it means a simple automation. Occasionally it means writing actual software.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell someone starting from a non-technical role
&lt;/h2&gt;

&lt;p&gt;Don't start with "I want to learn to code."&lt;/p&gt;

&lt;p&gt;Start with a recurring problem you understand unusually well.&lt;/p&gt;

&lt;p&gt;Write down what triggers it, which systems are involved, what the correct result looks like, and how you would know something went wrong. Try to make one part of it easier. Measure whether that actually saved time or improved a decision.&lt;/p&gt;

&lt;p&gt;Only then decide whether you need an API, a script, a database, or a whole application.&lt;/p&gt;

&lt;p&gt;You also don't have to become the person who builds everything alone. Knowing enough to frame a problem clearly, evaluate a technical solution, and work intelligently with developers is already a powerful skill.&lt;/p&gt;

&lt;p&gt;For me, learning to build has made me a better marketer because I understand more of the machinery behind the numbers. Working in marketing has made me a more practical builder because I'm constantly reminded that a feature is only valuable when it solves somebody's problem.&lt;/p&gt;

&lt;p&gt;I still work in marketing. I also build software.&lt;/p&gt;

&lt;p&gt;These no longer feel like separate parts of my career.&lt;/p&gt;

</description>
      <category>career</category>
      <category>automation</category>
      <category>marketing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Let ChatGPT Work on My Mac. The Hard Part Was Saying No</title>
      <dc:creator>Tarkan Bulut</dc:creator>
      <pubDate>Fri, 09 Oct 2026 18:51:36 +0000</pubDate>
      <link>https://dev.to/bulutarkan/i-let-chatgpt-work-on-my-mac-the-hard-part-was-saying-no-1126</link>
      <guid>https://dev.to/bulutarkan/i-let-chatgpt-work-on-my-mac-the-hard-part-was-saying-no-1126</guid>
      <description>&lt;p&gt;ChatGPT can explain almost any routine computer task. Letting it &lt;em&gt;perform&lt;/em&gt; that task introduces a more interesting question: who decides which actions are allowed?&lt;/p&gt;

&lt;p&gt;I build &lt;a href="https://github.com/bulutarkan/mac-mcp" rel="noopener noreferrer"&gt;Mac MCP&lt;/a&gt;, an open-source local execution layer for macOS. It gives MCP-compatible AI clients access to browser automation, files, shell commands, and native apps. I originally wanted less copying and pasting between a conversation and my desktop. Instead, I found myself spending a lot of time designing what happens when an agent asks for something it shouldn't be able to do.&lt;/p&gt;

&lt;p&gt;This is a practitioner's account of architectural trade-offs, not a formal security audit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the conversation separate from execution
&lt;/h2&gt;

&lt;p&gt;A model is useful for interpreting intent: “Check my repository and tell me what changed.” The local service is responsible for actual operations: reading Git status, locating files, calling browser tools, and returning evidence.&lt;/p&gt;

&lt;p&gt;Those two layers have different responsibilities. The model should be allowed to propose a sequence of steps. It should &lt;strong&gt;not&lt;/strong&gt; be the authority that expands its own permissions.&lt;/p&gt;

&lt;p&gt;This separation also means the execution layer isn't tied to a single AI model or subscription. Mac MCP exposes a native MCP interface, with a smaller REST/OpenAPI compatibility surface for clients that need it. A ChatGPT panel is optional; it doesn't change the server's permission model for other clients.&lt;/p&gt;

&lt;p&gt;That's a product decision as much as a technical one. I can change the conversation interface without rebuilding the local boundary that protects the machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  A harmless-sounding instruction can cross a boundary
&lt;/h2&gt;

&lt;p&gt;Imagine asking: “Check whether my development environment is healthy.”&lt;/p&gt;

&lt;p&gt;Reading recent logs is reasonable. Running a status command may also make sense. Deleting a runtime directory or uploading your private environment file does not.&lt;/p&gt;

&lt;p&gt;All four operations might be expressible with a powerful shell tool. That is why a tool name alone makes a poor security policy.&lt;/p&gt;

&lt;p&gt;Mac MCP uses capability profiles and explicit boundaries around sensitive operations. Its secure bootstrap also fails closed when important settings are missing. For a public endpoint, authentication is required; local transport by itself is not a same-user sandbox.&lt;/p&gt;

&lt;p&gt;I want an agent to explain which operation would help, not infer that because the user's goal is benign, every possible means of achieving it is authorized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Permission and approval are different questions
&lt;/h2&gt;

&lt;p&gt;There are two decisions worth separating:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;May this client perform this category of operation at all?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If it may, does this particular risky action require a one-time human confirmation?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A blocked capability should remain blocked even when an approval interface is present.&lt;/p&gt;

&lt;p&gt;The optional Mac MCP server approval layer can ask for &lt;strong&gt;Allow Once&lt;/strong&gt; or &lt;strong&gt;Block&lt;/strong&gt; on qualifying high-risk actions. The decision is scoped to the specific operation. It is not a lifetime credential that the agent can casually reuse for another task.&lt;/p&gt;

&lt;p&gt;That distinction prevents an unfortunate pattern: an agent performs a small, approved change, and later interprets the user's earlier click as blanket trust.&lt;/p&gt;

&lt;p&gt;Of course, too many approval prompts create fatigue. The answer can't simply be “ask before everything.” Good tools need useful read-only operations and clear risk categories so routine inspection doesn't feel like a security ceremony.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't sacrifice the user's desktop to make the demo look alive
&lt;/h2&gt;

&lt;p&gt;The machine has another scarce resource: the owner's focus.&lt;/p&gt;

&lt;p&gt;An AI agent that opens a new Safari tab in the foreground every few seconds may complete its task and still be an awful assistant. In Mac MCP, ordinary browser operations can target existing, real Safari or Chrome tabs in the background. The user can keep typing in another window.&lt;/p&gt;

&lt;p&gt;This is not the same as promising that every macOS interaction can be done invisibly. Some native UI fallbacks are foreground-only. Those behaviors need explicit gating, and the tool should fail rather than silently stealing focus when it cannot satisfy a background-only request.&lt;/p&gt;

&lt;p&gt;In a product, &lt;em&gt;not interrupting the user&lt;/em&gt; is a feature you have to engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  An outcome should be observed, not imagined
&lt;/h2&gt;

&lt;p&gt;I also learned to distrust confident completion messages.&lt;/p&gt;

&lt;p&gt;Suppose an agent clicks &lt;strong&gt;Submit&lt;/strong&gt; on a web form. The tab closes before any confirmation arrives. The model could say “Done.” It could also automatically retry. Neither is necessarily correct.&lt;/p&gt;

&lt;p&gt;The useful response is to distinguish what was attempted, what was observed, and what is still unknown. Replaying an uncertain write might create a duplicate.&lt;/p&gt;

&lt;p&gt;The same principle appears when the agent restarts its own local service. The original connection may disappear during a successful restart. That isn't proof of success or failure. The new process needs its own health check before the assistant can report a completed recovery.&lt;/p&gt;

&lt;p&gt;A good execution layer returns enough structured evidence for the conversation layer to be truthful.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would test before trusting the system
&lt;/h2&gt;

&lt;p&gt;I'd test a read-only client requesting a destructive write, an unavailable approval service, a browser tab disappearing during a mutation, and a server restart that drops the caller's connection.&lt;/p&gt;

&lt;p&gt;I'd also check that a client cannot turn on foreground control by slipping an optimistic parameter into a tool request. These are ordinary integration tests with uncomfortable scenarios, not exotic attacks.&lt;/p&gt;

&lt;p&gt;The goal is not to market a “perfectly safe agent.” It is to make the limits inspectable and the failures explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I keep building it
&lt;/h2&gt;

&lt;p&gt;A useful desktop agent should feel less like a robot operating your mouse and more like a well-behaved collaborator. It needs tools, but the boundaries around those tools determine whether I'd actually trust it with my daily work.&lt;/p&gt;

&lt;p&gt;The most interesting line of code in an agent project is sometimes the one that says &lt;strong&gt;no&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bulutarkan/mac-mcp" rel="noopener noreferrer"&gt;Mac MCP is available on GitHub&lt;/a&gt; under the MIT license. I'd welcome feedback on where you draw the line between strict local control and convenient autonomy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I'm the Mac MCP maintainer. I used AI assistance to draft and edit this article; the engineering decisions and views described here are mine.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Two AI Agents, One Browser: The Race Condition Behind Computer Use</title>
      <dc:creator>Tarkan Bulut</dc:creator>
      <pubDate>Fri, 09 Oct 2026 18:39:30 +0000</pubDate>
      <link>https://dev.to/bulutarkan/two-ai-agents-one-browser-the-race-condition-behind-computer-use-447j</link>
      <guid>https://dev.to/bulutarkan/two-ai-agents-one-browser-the-race-condition-behind-computer-use-447j</guid>
      <description>&lt;p&gt;The first version of a desktop AI demo is deceptively simple: find a tab, find a button, click it. It looks convincing right up until a second agent starts working in the same browser.&lt;/p&gt;

&lt;p&gt;I'm building &lt;a href="https://github.com/bulutarkan/mac-mcp" rel="noopener noreferrer"&gt;Mac MCP&lt;/a&gt;, an open-source local control layer that lets MCP-compatible AI clients work with Safari, Chrome, files, and native macOS apps. Adding a second worker changed my idea of what “correct browser automation” means.&lt;/p&gt;

&lt;p&gt;This post is about the engineering problem behind that change. The examples are simplified to explain the failure modes; they aren't benchmark results.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tab number is not an identity
&lt;/h2&gt;

&lt;p&gt;Imagine two agents sharing Safari.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent A opens a product documentation page and decides to click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Agent B opens a dashboard for an unrelated task.&lt;/li&gt;
&lt;li&gt;Agent A returns and says, “Click the button in tab 3.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That third tab might no longer be the documentation page. Agent B could have inserted a new tab, or someone could have moved one manually.&lt;/p&gt;

&lt;p&gt;The mistake isn't that the model was careless. &lt;strong&gt;An array position was used as if it were a durable resource identifier.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An agent needs an address for the &lt;em&gt;same&lt;/em&gt; resource after the browser changes. In Mac MCP, browser operations use a stable tab handle. The local service resolves the handle to the underlying native browser tab, rather than trusting its current position.&lt;/p&gt;

&lt;p&gt;The failure case matters as much as the happy path. If the tab has closed, the operation must not silently continue in whichever tab is now selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ownership is different from observation
&lt;/h2&gt;

&lt;p&gt;Stable handles solve one problem, but they don't resolve concurrent writes.&lt;/p&gt;

&lt;p&gt;Suppose Agent A and Agent B both observe the same form. A fills the shipping fields while B is about to click the button that advances to the next step. Both plans were reasonable when they were created. The second action can invalidate the first agent's state.&lt;/p&gt;

&lt;p&gt;The implementation needs explicit coordination for operations targeting the same browser resource. Independent tabs can often be handled concurrently; operations against one tab may need to be serialized.&lt;/p&gt;

&lt;p&gt;This isn't the same as locking the entire browser. A global lock can make multi-agent work needlessly slow. The right unit of coordination is closer to the resource being mutated.&lt;/p&gt;

&lt;p&gt;Prompts like “don't interfere with the other agent” help the model reason about a task, but they are not concurrency controls. A model cannot guarantee another process won't click at the same moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foreground focus is shared state too
&lt;/h2&gt;

&lt;p&gt;There's another resource desktop automation often forgets: &lt;strong&gt;the human's attention&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Traditional GUI automation frequently activates the browser, switches tabs, and brings the window to the front. When two agents do that, your desktop can feel like a tug-of-war. Each tool call might succeed technically while the overall product is miserable to use.&lt;/p&gt;

&lt;p&gt;Mac MCP's ordinary Safari and Chrome browser work is designed to target background tabs without switching the user's active tab. That doesn't mean a headless browser hidden in a container; these are real tabs in the user's browsers. Foreground actions are treated separately and remain capability-gated.&lt;/p&gt;

&lt;p&gt;The distinction is not cosmetic. A background-safe tool should fail when it cannot preserve that promise, rather than surprise the user by grabbing focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  A successful click is not a successful task
&lt;/h2&gt;

&lt;p&gt;Now consider a more consequential example.&lt;/p&gt;

&lt;p&gt;An agent clicks &lt;strong&gt;Submit&lt;/strong&gt;. The request begins. Before the page shows a confirmation, the tab closes. The next tool result says the target disappeared.&lt;/p&gt;

&lt;p&gt;Did the remote server accept the submission?&lt;/p&gt;

&lt;p&gt;We don't know. Automatically clicking Submit again may duplicate a comment, send the same message twice, or create a second record.&lt;/p&gt;

&lt;p&gt;I try to keep three different states separate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Action attempted:&lt;/strong&gt; the browser interaction was initiated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outcome observed:&lt;/strong&gt; the page or another reliable source confirmed what changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outcome uncertain:&lt;/strong&gt; an interruption prevented verification.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A read can often be repeated safely. A write with an uncertain outcome needs a different recovery policy.&lt;/p&gt;

&lt;p&gt;This is why browser automation should return structured progress and meaningful errors, rather than treating every tool exception as a reason to retry the entire sequence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the interruptions, not only the demo
&lt;/h2&gt;

&lt;p&gt;The most useful tests for this kind of tool are deliberately awkward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open, close, and reorder tabs during an agent action.&lt;/li&gt;
&lt;li&gt;Run two workers against different tabs, then against the same tab.&lt;/li&gt;
&lt;li&gt;Remove the target tab after a click but before confirmation.&lt;/li&gt;
&lt;li&gt;Ensure a background action never switches the visible tab as an undocumented fallback.&lt;/li&gt;
&lt;li&gt;Check that a failed workflow reports which actions finished and which didn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the system only works when the browser stays perfectly still, it hasn't solved desktop automation yet.&lt;/p&gt;

&lt;p&gt;The exact implementation is browser-dependent, and Mac MCP is not a general security proof. Its &lt;a href="https://github.com/bulutarkan/mac-mcp" rel="noopener noreferrer"&gt;public repository&lt;/a&gt; contains the source, documentation, and tests for the mechanisms discussed here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lesson I kept
&lt;/h2&gt;

&lt;p&gt;The difficult part of putting agents on a desktop isn't teaching them where to click. It's making resource identity, ownership, user attention, and uncertain outcomes explicit.&lt;/p&gt;

&lt;p&gt;When those guarantees live in the tool layer, the agent can spend more effort understanding the task and less time recovering from a browser that moved underneath it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I maintain Mac MCP. AI assistance was used to draft and edit this article; the engineering choices and opinions are mine.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
  </channel>
</rss>
