<?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: Mikołaj Badyl</title>
    <description>The latest articles on DEV Community by Mikołaj Badyl (@mbadyl).</description>
    <link>https://dev.to/mbadyl</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%2F3760351%2Fbeab2201-e5f7-469f-b59e-6c3f3da781e4.jpeg</url>
      <title>DEV Community: Mikołaj Badyl</title>
      <link>https://dev.to/mbadyl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mbadyl"/>
    <language>en</language>
    <item>
      <title>Run Coding Agents on a Server, Check from Your Phone</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Thu, 03 Sep 2026 19:08:04 +0000</pubDate>
      <link>https://dev.to/mbadyl/run-coding-agents-on-a-server-check-from-your-phone-20dk</link>
      <guid>https://dev.to/mbadyl/run-coding-agents-on-a-server-check-from-your-phone-20dk</guid>
      <description>&lt;h1&gt;
  
  
  Where to run the agent
&lt;/h1&gt;

&lt;p&gt;A coding agent like Claude Code or OpenCode needs a machine that stays on all the time. You do not need a powerful or expensive computer. The agent itself is light because the heavy work happens over an API. A small cloud server with 2 CPU cores and 4 GB of memory costs about 5 USD per month. You can also use a used mini PC, a Raspberry Pi, or even an old laptop.&lt;/p&gt;

&lt;p&gt;Pick a Linux system you know. Ubuntu 24.04 LTS is a good choice because it is stable and well supported. Install Python, Git, and the agent software. The agent will ask for an API key. To get the key, open a browser on your laptop, log in to the agent’s website, and copy the key. Then paste it into the terminal on the server.&lt;/p&gt;

&lt;p&gt;Start the agent once to check it works. Run a simple command like &lt;code&gt;./agent --version&lt;/code&gt;. The agent should print its version number. Then close the SSH session. The agent should keep running. If it stops, you need a way to keep it alive. A tool like &lt;code&gt;systemd&lt;/code&gt; or &lt;code&gt;tmux&lt;/code&gt; can help. For example, create a &lt;code&gt;systemd&lt;/code&gt; service file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Coding Agent&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;agentuser&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/agentuser/agent&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/python3 /home/agentuser/agent/agent.py&lt;/span&gt;
&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file as &lt;code&gt;/etc/systemd/system/agent.service&lt;/code&gt;. Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;agent
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent will start automatically when the server boots. It will also restart if it crashes.&lt;/p&gt;

&lt;h1&gt;
  
  
  The phone problem
&lt;/h1&gt;

&lt;p&gt;A phone is not a laptop. It has limits that make SSH hard to use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The screen locks after a few minutes. When the screen locks, Android may freeze or kill background apps.&lt;/li&gt;
&lt;li&gt;The network changes often. It switches from wifi to mobile data, or from one wifi network to another. Each switch can break the connection.&lt;/li&gt;
&lt;li&gt;The app freezes when it goes to the background. Android does this to save battery. A plain SSH client loses the session when this happens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The usual fix is &lt;code&gt;tmux&lt;/code&gt;. Install it on the server. Start a &lt;code&gt;tmux&lt;/code&gt; session. Run the agent inside it. If the connection drops, &lt;code&gt;tmux&lt;/code&gt; keeps the process alive. When you reconnect, &lt;code&gt;tmux&lt;/code&gt; attaches you back. But &lt;code&gt;tmux&lt;/code&gt; has problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You must install it on every server you use. If you forget, the session dies.&lt;/li&gt;
&lt;li&gt;You must remember to start a session. If you run the agent without &lt;code&gt;tmux&lt;/code&gt;, it stops when the connection drops.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tmux&lt;/code&gt; has its own commands. You must learn them to use it well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keep the session alive without tmux
&lt;/h2&gt;

&lt;p&gt;A small helper program can do what &lt;code&gt;tmux&lt;/code&gt; does, but without setup. The helper is called &lt;code&gt;termphin-agent&lt;/code&gt;. It is a Rust program, about 490 KB for Linux arm64 and 540 KB for Linux x86_64. You upload it to the server over SSH. It runs in the background and keeps the shell alive.&lt;/p&gt;

&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You start an SSH session from your phone.&lt;/li&gt;
&lt;li&gt;The app uploads the helper to the server. It puts the helper in &lt;code&gt;~/.termphin/agent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The helper starts a new shell. The shell runs inside the helper.&lt;/li&gt;
&lt;li&gt;If the connection drops, the helper holds the session. It keeps the shell alive.&lt;/li&gt;
&lt;li&gt;When you reconnect, the helper reattaches you to the same shell. The screen state, cursor position, and scrollback are all there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The helper is optional. Without it, the app works as a plain SSH client. But with it, you do not need &lt;code&gt;tmux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are failure cases. The helper can crash or be killed. If the server runs out of memory, the Linux kernel may kill the helper. If the server reboots, the helper stops. To handle these cases, the app checks if the helper is running when you reconnect. If the helper is not running, the app starts a new session.&lt;/p&gt;

&lt;h1&gt;
  
  
  What a coding agent needs from a terminal
&lt;/h1&gt;

&lt;p&gt;A coding agent shows diffs, spinners, progress bars, and full-screen text interfaces. A plain SSH client often gets these wrong. The terminal must render:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Box-drawing characters. These are used for tables, menus, and borders.&lt;/li&gt;
&lt;li&gt;Colours. These are used for syntax highlighting, diffs, and status messages.&lt;/li&gt;
&lt;li&gt;Cursor movement. This is used for spinners, progress bars, and interactive prompts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the terminal does not render these correctly, the output looks broken. For example, a diff may show as a wall of text instead of aligned lines. A spinner may jump around instead of spinning smoothly.&lt;/p&gt;

&lt;p&gt;Termphin uses a real native terminal engine. It is drawn by Flutter, not a browser. The engine is a fork of the Dart package &lt;code&gt;xterm&lt;/code&gt; version 4.0.0. It is open source under the MIT license. This means full-screen text user interface programs render correctly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Read a diff on a small screen
&lt;/h1&gt;

&lt;p&gt;A diff can be long. On a phone, you scroll. But the terminal must keep the lines aligned. If the rendering is wrong, the diff is unreadable.&lt;/p&gt;

&lt;p&gt;Here is an example of a diff that works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- old_file.txt
&lt;/span&gt;&lt;span class="gi"&gt;+++ new_file.txt
&lt;/span&gt;&lt;span class="p"&gt;@@ -1,5 +1,5 @@&lt;/span&gt;
 Line 1
&lt;span class="gd"&gt;-Line 2
&lt;/span&gt;&lt;span class="gi"&gt;+Line 2 updated
&lt;/span&gt; Line 3
 Line 4
 Line 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; signs must line up. The colours must be clear. The font must be readable at small sizes.&lt;/p&gt;

&lt;p&gt;To make diffs readable on a phone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick a font like &lt;code&gt;Fira Code&lt;/code&gt; or &lt;code&gt;JetBrains Mono&lt;/code&gt;. These fonts have clear shapes and good spacing.&lt;/li&gt;
&lt;li&gt;Adjust the line height. A value of 1.2 to 1.4 works well.&lt;/li&gt;
&lt;li&gt;Adjust the padding. A value of 4 to 8 pixels keeps the text away from the edges.&lt;/li&gt;
&lt;li&gt;Use a colour scheme that works in daylight and at night. For example, &lt;code&gt;Solarized Dark&lt;/code&gt; or &lt;code&gt;Gruvbox&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the diff is still hard to read, zoom in. The app lets you pinch to zoom. You can also change the font size in the settings.&lt;/p&gt;

&lt;h1&gt;
  
  
  Answer an agent prompt that needs a key press
&lt;/h1&gt;

&lt;p&gt;Some agents ask for a key press to continue. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The agent is ready. Press Enter to proceed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a phone, you do not have a physical keyboard. A toolbar with special keys helps. The toolbar has keys like Esc, Tab, Ctrl, and the arrow keys. You can tap these keys instead of typing them.&lt;/p&gt;

&lt;p&gt;The toolbar is customizable. You can save different layouts for different tasks. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A layout for coding agents. It has Esc, Tab, Ctrl, and the arrow keys.&lt;/li&gt;
&lt;li&gt;A layout for plain SSH. It has Page Up, Page Down, and function keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To create a layout:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the toolbar settings.&lt;/li&gt;
&lt;li&gt;Tap the &lt;code&gt;+&lt;/code&gt; button to add a new layout.&lt;/li&gt;
&lt;li&gt;Drag keys from the palette to the toolbar.&lt;/li&gt;
&lt;li&gt;Save the layout.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The toolbar can float or dock. In portrait mode, it floats. In landscape mode, it docks to the side.&lt;/p&gt;

&lt;h1&gt;
  
  
  Send a file from the phone into the agent
&lt;/h1&gt;

&lt;p&gt;An agent may ask for a file. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Upload the config file to /home/user/config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a phone, you pick the file from the file browser. The app uploads it to the server and inserts the path into the prompt.&lt;/p&gt;

&lt;p&gt;The file browser is built in. It works like a local file manager. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Walk the server’s filesystem.&lt;/li&gt;
&lt;li&gt;Preview images, text files, and code.&lt;/li&gt;
&lt;li&gt;Open files in a syntax-highlighted editor.&lt;/li&gt;
&lt;li&gt;Upload files from your phone to the server.&lt;/li&gt;
&lt;li&gt;Download files from the server to your phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To upload a file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the file browser from the app.&lt;/li&gt;
&lt;li&gt;Navigate to the folder where you want to upload the file.&lt;/li&gt;
&lt;li&gt;Tap the &lt;code&gt;+&lt;/code&gt; button and select &lt;code&gt;Upload&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Pick a file from your phone.&lt;/li&gt;
&lt;li&gt;The app uploads the file and shows the path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The editor supports syntax highlighting for many languages. It also has line numbers and basic formatting. You can edit a file and save it back to the server.&lt;/p&gt;

&lt;h1&gt;
  
  
  Run the same saved command on several machines
&lt;/h1&gt;

&lt;p&gt;You may run the same agent on several servers. Instead of typing the command each time, save it as a snippet. A snippet is a saved command with a name. You can run it on any machine with one tap.&lt;/p&gt;

&lt;p&gt;For example, save a snippet called &lt;code&gt;start_agent&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/agent &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./agent.py &lt;span class="nt"&gt;--config&lt;/span&gt; config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the snippet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the snippets menu.&lt;/li&gt;
&lt;li&gt;Tap the snippet name.&lt;/li&gt;
&lt;li&gt;The app pastes the command into the terminal and runs it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The app remembers the run history. It shows the exit code and the time. If the command fails, you can see why.&lt;/p&gt;

&lt;p&gt;You can also edit or delete snippets. For example, change the config file path or add a new flag.&lt;/p&gt;

&lt;h1&gt;
  
  
  Reach a dev server the agent started through a tunnel
&lt;/h1&gt;

&lt;p&gt;An agent may start a dev server on a random port. For example, a web server on port 3000. To reach it from your phone, set up a tunnel. The tunnel forwards a local port on your phone to the server’s port.&lt;/p&gt;

&lt;p&gt;For example, forward port 8080 on your phone to port 3000 on the server:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the profile for the server.&lt;/li&gt;
&lt;li&gt;Go to the &lt;code&gt;Tunnels&lt;/code&gt; section.&lt;/li&gt;
&lt;li&gt;Tap &lt;code&gt;Add Tunnel&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;Local Port&lt;/code&gt; to 8080 and &lt;code&gt;Remote Port&lt;/code&gt; to 3000.&lt;/li&gt;
&lt;li&gt;Save the profile.&lt;/li&gt;
&lt;li&gt;Connect to the server. The tunnel starts automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now open a browser on your phone and go to &lt;code&gt;http://localhost:8080&lt;/code&gt;. You should see the dev server.&lt;/p&gt;

&lt;p&gt;You can also set up tunnels on the fly. For example, if the agent starts a server on port 4000, create a new tunnel without editing the profile.&lt;/p&gt;

&lt;h1&gt;
  
  
  Safety rules for letting an agent run while nobody is watching
&lt;/h1&gt;

&lt;p&gt;An agent runs code. It can make mistakes. Set limits to reduce risks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a dedicated user account. Do not run the agent as root. Create a user like &lt;code&gt;agentuser&lt;/code&gt; and run the agent under that account.&lt;/li&gt;
&lt;li&gt;Set a memory limit. For example, 2 GB. Use &lt;code&gt;systemd&lt;/code&gt; or &lt;code&gt;cgroups&lt;/code&gt; to enforce the limit.&lt;/li&gt;
&lt;li&gt;Set a CPU limit. For example, 50% of one core. This prevents the agent from using all CPU.&lt;/li&gt;
&lt;li&gt;Use a firewall. Only allow connections from your IP. For example, use &lt;code&gt;ufw&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow from your.ip.address to any port 22
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check the logs often. The app can show the last lines of the session. You can also log the session to a file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;script &lt;span class="nt"&gt;-f&lt;/span&gt; /home/agentuser/session.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the agent inside &lt;code&gt;script&lt;/code&gt;. The log file will record everything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use SSH keys instead of passwords. The app stores keys in an encrypted vault on your phone. The vault is protected by a PIN or fingerprint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify host keys. The app checks the server’s host key before connecting. It fails closed if the key does not match. You can pin the key in the settings.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  One honest option among others
&lt;/h1&gt;

&lt;p&gt;I built Termphin, an SSH client for Android, to solve these problems. It is a native app, not a WebView or a browser wrapper. The terminal engine is a fork of the Dart package &lt;code&gt;xterm&lt;/code&gt; version 4.0.0. It is open source under the MIT license. The Android app itself is not open source.&lt;/p&gt;

&lt;p&gt;Termphin keeps sessions alive without &lt;code&gt;tmux&lt;/code&gt;. A small helper agent runs on the server and holds the session. If the connection drops, the helper keeps the shell alive. When you reconnect, the helper reattaches you exactly where you left off. The helper is optional. Without it, the app works as a plain SSH client.&lt;/p&gt;

&lt;p&gt;The terminal renders coding agents correctly. It handles diffs, spinners, and full-screen text interfaces. You can adjust the font, size, line height, padding, and colour scheme. The app has eight colour schemes and supports light and dark themes.&lt;/p&gt;

&lt;p&gt;The app has a built-in SFTP file browser. You can walk the server’s filesystem, preview files, and edit them in a syntax-highlighted editor. You can upload files from your phone to the server and download files from the server to your phone.&lt;/p&gt;

&lt;p&gt;You can save commands as snippets and run them on any machine. You can set up tunnels to reach dev servers. The app supports jump hosts, port forwarding, and keyboard-interactive auth for 2FA.&lt;/p&gt;

&lt;p&gt;The app is free on Android today. There are no ads and no in-app purchases in this release. The iOS, Windows, macOS, and Linux clients are in the works but not released yet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Running a coding agent on a server and checking it from a phone is possible. The hard part is the phone. The session must survive a locked screen, a network switch, or the app going to the background. The terminal must render diffs, spinners, and full-screen interfaces correctly. The app must let you send files, run saved commands, and reach dev servers through tunnels.&lt;/p&gt;

&lt;p&gt;With the right setup, you can start a long job and check on it from anywhere. The agent stays alive, the terminal works, and the phone does not get in the way.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>android</category>
      <category>coding</category>
      <category>ai</category>
    </item>
    <item>
      <title>Generating OpenAPI specs without writing a single line of YAML</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Wed, 25 Feb 2026 16:20:55 +0000</pubDate>
      <link>https://dev.to/mbadyl/generating-openapi-specs-without-writing-a-single-line-of-yaml-3oe5</link>
      <guid>https://dev.to/mbadyl/generating-openapi-specs-without-writing-a-single-line-of-yaml-3oe5</guid>
      <description>&lt;p&gt;If you've ever tried to write an OpenAPI spec by hand, you know how painful it is. Hundreds of lines of YAML, manual endpoint definitions, request/response schemas - and if your API changes, you have to update it all again.&lt;/p&gt;

&lt;p&gt;I ran into this problem while building Octrafic. The tool requires an OpenAPI spec to understand your API structure - and not everyone has one. So I built a scanner that generates it automatically from your source code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsfr7cdgcwm3mft1g3ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsfr7cdgcwm3mft1g3ef.png" alt=" " width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The scanner uses a pipeline called OOPS that works in four stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Framework detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It starts by reading your root config files - &lt;code&gt;go.mod&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt; and so on. From that it figures out your language and web framework without touching the rest of your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Route discovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using heuristics specific to the detected framework, it finds exactly which files contain your routing logic and endpoint definitions. It skips everything irrelevant - &lt;code&gt;node_modules&lt;/code&gt;, test directories, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Parallel endpoint extraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of dumping your entire codebase into the LLM context, it isolates each routing file and queries the AI in parallel. This keeps token usage low and extraction fast. It pulls out methods, paths, summaries, and request/response payloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Spec generation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything gets aggregated and formatted into a valid OpenAPI 3.1 YAML file, ready to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;One command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic scan &lt;span class="nt"&gt;-p&lt;/span&gt; ./my-backend-project &lt;span class="nt"&gt;-o&lt;/span&gt; api-spec.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the scan finishes, you can immediately start testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; http://localhost:8080 &lt;span class="nt"&gt;-s&lt;/span&gt; api-spec.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CI/CD support
&lt;/h2&gt;

&lt;p&gt;The scanner runs completely non-interactively, so you can wire it into your pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCTRAFIC_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;claude
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCTRAFIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_key_here
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCTRAFIC_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;claude-haiku-4.5
octrafic scan &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; spec.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;Octrafic lets you test APIs using plain English instead of writing test scripts. But it requires an OpenAPI spec to understand your API structure - without one, it can't work.&lt;/p&gt;

&lt;p&gt;The scanner removes that barrier. You point it at your project, get a spec, and go straight to testing - without writing a single line of YAML.&lt;/p&gt;




&lt;p&gt;It's open-source, still early, feedback welcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Octrafic/octrafic-cli" rel="noopener noreferrer"&gt;github.com/Octrafic/octrafic-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://docs.octrafic.com" rel="noopener noreferrer"&gt;docs.octrafic.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>api</category>
    </item>
    <item>
      <title>Stop writing API test scripts. Use plain English instead.</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Tue, 24 Feb 2026 16:13:00 +0000</pubDate>
      <link>https://dev.to/mbadyl/stop-writing-api-test-scripts-use-plain-english-instead-532d</link>
      <guid>https://dev.to/mbadyl/stop-writing-api-test-scripts-use-plain-english-instead-532d</guid>
      <description>&lt;p&gt;Writing API tests is tedious. You either click through Postman manually, write JavaScript test scripts, or wrestle with curl flags you forget every time.&lt;/p&gt;

&lt;p&gt;I built Octrafic to fix that - you describe what you want tested in plain English, and the AI handles the rest. This is a quick guide on how to actually use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Single binary, no runtime dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux/macOS&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://octrafic.com/install.sh | bash

&lt;span class="c"&gt;# Homebrew&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;octrafic/tap/octrafic

&lt;span class="c"&gt;# Windows&lt;/span&gt;
iex &lt;span class="o"&gt;(&lt;/span&gt;iwr &lt;span class="nt"&gt;-useb&lt;/span&gt; https://octrafic.com/install.ps1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set up your AI provider
&lt;/h2&gt;

&lt;p&gt;Octrafic supports Claude, OpenAI, OpenRouter, Gemini, Ollama, and llama.cpp. You bring your own API key - nothing goes through my servers.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;octrafic&lt;/code&gt; for the first time and it'll walk you through the setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4epbmy35m7wbuni0onq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb4epbmy35m7wbuni0onq.png" alt="Octrafic onboarding" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to run everything locally without any API key, Ollama works great:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull qwen2.5:7b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then point Octrafic at it during setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Load your API
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; openapi.json &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"My API"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; - your API base URL&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt; - path to your OpenAPI/Swagger spec&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt; - project name&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Start testing
&lt;/h2&gt;

&lt;p&gt;Once you're in the TUI, just describe what you want tested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test the login endpoint with valid credentials
test the login endpoint with a wrong password
test creating a new user and check the response structure
run edge cases on the /users endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI figures out the right HTTP method, URL, headers, and payload based on your spec. It executes the request and shows you the response with a pass/fail result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ls8v8rimbt8riouw26s.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ls8v8rimbt8riouw26s.gif" alt="Octrafic gif" width="760" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;Pass auth via CLI flags when starting a session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bearer token&lt;/span&gt;
octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; spec.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auth&lt;/span&gt; bearer &lt;span class="nt"&gt;--token&lt;/span&gt; &lt;span class="s2"&gt;"your-token-here"&lt;/span&gt;

&lt;span class="c"&gt;# API key&lt;/span&gt;
octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; spec.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auth&lt;/span&gt; apikey &lt;span class="nt"&gt;--key&lt;/span&gt; X-API-Key &lt;span class="nt"&gt;--value&lt;/span&gt; &lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;

&lt;span class="c"&gt;# Basic auth&lt;/span&gt;
octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; spec.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auth&lt;/span&gt; basic &lt;span class="nt"&gt;--user&lt;/span&gt; admin &lt;span class="nt"&gt;--pass&lt;/span&gt; secret123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use environment variables if you don't want credentials in your shell history or project files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCTRAFIC_AUTH_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bearer
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OCTRAFIC_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-token-here
octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; spec.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One important thing - your actual tokens and passwords are never sent to the AI. The AI only knows the auth type and header names. Your credentials stay on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export your tests
&lt;/h2&gt;

&lt;p&gt;After running tests interactively, you can ask the AI to export them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export these tests to postman
export tests as a shell script
export to pytest and name it test_users_api.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also export a test plan before executing it, useful if you just want to generate tests and run them later.&lt;/p&gt;

&lt;p&gt;Files are saved to &lt;code&gt;~/Documents/octrafic/tests/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run tests in CI/CD
&lt;/h2&gt;

&lt;p&gt;For pipelines, use the &lt;code&gt;octrafic test&lt;/code&gt; subcommand - no TUI, no prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--path&lt;/span&gt; tests/api-tests.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auth&lt;/span&gt; bearer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--token&lt;/span&gt; &lt;span class="nv"&gt;$API_TOKEN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or generate and run tests from a prompt directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--spec&lt;/span&gt; openapi.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"test all user endpoints"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exits with &lt;code&gt;0&lt;/code&gt; if all tests pass, &lt;code&gt;1&lt;/code&gt; if anything fails.&lt;/p&gt;

&lt;p&gt;GitHub Actions example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run API tests&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;octrafic test \&lt;/span&gt;
      &lt;span class="s"&gt;--url ${{ secrets.API_URL }} \&lt;/span&gt;
      &lt;span class="s"&gt;--path tests/api-tests.json \&lt;/span&gt;
      &lt;span class="s"&gt;--auth bearer \&lt;/span&gt;
      &lt;span class="s"&gt;--token ${{ secrets.API_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Save your project
&lt;/h2&gt;

&lt;p&gt;By default, new sessions are temporary. Use &lt;code&gt;/save&lt;/code&gt; to persist your project, or watch for the temp indicator in the status bar.&lt;/p&gt;




&lt;p&gt;That's the basics. It's open-source and still early, so if something doesn't work or you have ideas, open an issue.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Octrafic/octrafic-cli" rel="noopener noreferrer"&gt;github.com/Octrafic/octrafic-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://docs.octrafic.com" rel="noopener noreferrer"&gt;docs.octrafic.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I added CI/CD support to my natural language API testing CLI</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Fri, 20 Feb 2026 20:03:43 +0000</pubDate>
      <link>https://dev.to/mbadyl/i-added-cicd-support-to-my-natural-language-api-testing-cli-4imn</link>
      <guid>https://dev.to/mbadyl/i-added-cicd-support-to-my-natural-language-api-testing-cli-4imn</guid>
      <description>&lt;p&gt;Today I shipped v0.4.0 of Octrafic. Here's what changed and why.&lt;/p&gt;

&lt;p&gt;If you haven't seen it before - Octrafic is a CLI tool that lets you test APIs using plain English instead of writing test scripts. &lt;a href="https://dev.to/mbadyl/i-built-an-ai-cli-that-lets-you-chat-with-your-apis-5fig"&gt;First post here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with the previous version
&lt;/h2&gt;

&lt;p&gt;Octrafic worked well interactively. You'd open the TUI, describe what you want tested, get results. Fine for day-to-day use.&lt;/p&gt;

&lt;p&gt;But if you wanted to wire it into a CI/CD pipeline, it just didn't work. The TUI would block, waiting for input that was never coming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headless mode
&lt;/h2&gt;

&lt;p&gt;The main addition in v0.4.0 is the new &lt;code&gt;octrafic test&lt;/code&gt; subcommand. It runs non-interactively - no TUI, no prompts.&lt;/p&gt;

&lt;p&gt;You can either run an existing test file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--path&lt;/span&gt; tests/api-tests.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or generate and run tests on the fly from a prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--spec&lt;/span&gt; openapi.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"test all user endpoints"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exits with &lt;code&gt;0&lt;/code&gt; if all tests pass, &lt;code&gt;1&lt;/code&gt; if anything fails. Easy to plug into GitHub Actions or any other pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Export to Postman, curl, pytest
&lt;/h2&gt;

&lt;p&gt;Once you've run your tests interactively, you can ask the AI to export them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export these tests to postman
export tests as a shell script
export to pytest and name it test_users_api.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exported files include auth configuration too, so they work out of the box. Useful if you want to run them outside of Octrafic or commit them to your repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  /save command and temp project indicator
&lt;/h2&gt;

&lt;p&gt;Small thing, but it was causing real confusion - you'd close the session and lose everything because you didn't realize the project wasn't saved. There's now a clear indicator in the UI and a &lt;code&gt;/save&lt;/code&gt; command to make it explicit.&lt;/p&gt;




&lt;p&gt;Still a solo project, still early days. But it's getting more useful with every release.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Octrafic/octrafic-cli" rel="noopener noreferrer"&gt;github.com/Octrafic/octrafic-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;a href="https://octrafic.com" rel="noopener noreferrer"&gt;octrafic.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://docs.octrafic.com" rel="noopener noreferrer"&gt;docs.octrafic.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full release notes: &lt;a href="https://docs.octrafic.com/releases/v0.4.0.html" rel="noopener noreferrer"&gt;docs.octrafic.com/releases/v0.4.0.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>api</category>
    </item>
    <item>
      <title>API Testing Tools in 2026: Why I Built My Own (After Comparing All the Popular Ones)</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Tue, 17 Feb 2026 21:47:45 +0000</pubDate>
      <link>https://dev.to/mbadyl/api-testing-tools-in-2026-why-i-built-my-own-after-comparing-all-the-popular-ones-3jhn</link>
      <guid>https://dev.to/mbadyl/api-testing-tools-in-2026-why-i-built-my-own-after-comparing-all-the-popular-ones-3jhn</guid>
      <description>&lt;p&gt;After years of using Postman for nearly every project, I started noticing the friction. The mandatory login, the Electron window eating my RAM, the team plan that suddenly costs way more than it used to. So I started exploring alternatives - and I genuinely tried all the popular ones. Some were great, some surprised me, and a few solved problems I didn't even know I had.&lt;/p&gt;

&lt;p&gt;But none of them solved the problem I cared about most: making API testing feel like a natural part of the development loop rather than a separate ritual you have to context-switch into. That frustration eventually led me to build &lt;a href="https://octrafic.com" rel="noopener noreferrer"&gt;Octrafic&lt;/a&gt;. Before I get to that, let me give you an honest rundown of what's out there.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Landscape: An Honest Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Postman
&lt;/h3&gt;

&lt;p&gt;Postman is the undisputed industry standard, and for good reason. The ecosystem is mature - collections, environments, team workspaces, mock servers, monitors, documentation generation. If your company is onboarding a team of 20 engineers onto a shared API workflow, Postman is probably still the answer.&lt;/p&gt;

&lt;p&gt;The problem is that Postman has been aggressively moving upmarket. The free tier keeps shrinking, the desktop app requires you to be signed in, and it's noticeably resource-heavy for what is fundamentally an HTTP client. If you're a solo developer or a small startup, you're paying enterprise prices for features you'll never touch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Enterprise teams with a real budget and a need for collaboration features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Insomnia
&lt;/h3&gt;

&lt;p&gt;Insomnia was my go-to replacement for a while. It's genuinely lighter than Postman, has a clean UI that stays out of your way, and its GraphQL support is excellent - auto-completion from your schema, query builders, the works.&lt;/p&gt;

&lt;p&gt;The anxiety around Insomnia is mostly about ownership. Kong acquired it a few years back, and since then there have been some controversial moves around syncing and account requirements. The community forked it into Insomnium as a response. If you're okay with the uncertainty, it's a solid tool. If you want something more stable long-term, that uncertainty is a real factor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Solo developers, especially those working with GraphQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thunder Client
&lt;/h3&gt;

&lt;p&gt;Thunder Client is a VS Code extension, which is either its biggest strength or a dealbreaker depending on your workflow. If you live in VS Code, and a lot of developers do, having your HTTP client as a sidebar panel is genuinely ergonomic. No context switching, no separate window, requests sit right next to your code.&lt;/p&gt;

&lt;p&gt;The tradeoff is that you're in VS Code for everything. Advanced scripting, pre-request flows, CI/CD integration - Thunder Client handles the basics well but starts to feel limited for anything complex. It also means you're tied to the VS Code ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Developers who use VS Code as their primary environment and mostly need quick endpoint validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hoppscotch
&lt;/h3&gt;

&lt;p&gt;Hoppscotch is impressive as a piece of software. It's fully open-source, runs in the browser, has a modern UI, and you can self-host the entire thing. There's no installation, which makes it great for quickly sharing a request with a teammate or testing something on a machine you don't control.&lt;/p&gt;

&lt;p&gt;The limitation is that "runs in the browser" is both its superpower and its constraint. Offline capability is limited, and anything involving local environments or internal APIs requires some extra setup (their self-hosted agent). For pure open-source enthusiasm and accessibility, it's hard to beat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Quick ad-hoc tests, teams that want a self-hostable open-source option, situations where installation isn't possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bruno
&lt;/h3&gt;

&lt;p&gt;Bruno is the tool that's gotten the most traction among developers frustrated with Postman's direction. Its core idea is elegant: API collections are stored as plain text files on your filesystem, which means they live in your Git repo alongside your code. No cloud sync required, no proprietary format.&lt;/p&gt;

&lt;p&gt;It's offline-first by design, the UI is clean, and the philosophy resonates with developers who care about owning their data. The main caveat is that it's a newer tool - the ecosystem is smaller, some edge cases feel rough, and advanced scripting is still maturing. But the trajectory is good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams that want their API collections version-controlled in Git, developers who want to avoid cloud lock-in.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Gap I Kept Hitting
&lt;/h2&gt;

&lt;p&gt;After going through all of these, I had a clear picture of the tradeoffs. But I kept running into the same wall, regardless of which tool I was using.&lt;/p&gt;

&lt;p&gt;Manual GUI testing is fine when you're exploring a new API. But when you're deep in development - building a feature, refactoring an endpoint, dealing with a regression - the workflow becomes repetitive and tedious. Click, fill in params, click send, check response, repeat. Writing actual test scripts requires learning each tool's specific scripting API, which is its own investment.&lt;/p&gt;

&lt;p&gt;More fundamentally: &lt;strong&gt;automation felt like an afterthought in all of these tools.&lt;/strong&gt; The core experience is built around clicking through a GUI, and scripting/CI integration is layered on top. What I wanted was the inverse - a tool where automation and repeatability are the primary experience, and the interface facilitates that rather than fighting it.&lt;/p&gt;

&lt;p&gt;I also noticed that nobody was taking AI seriously in this space. Not in a meaningful way, anyway. There were some autocomplete features here and there, but nothing that actually changed the testing workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built Octrafic
&lt;/h2&gt;

&lt;p&gt;So I built &lt;a href="https://octrafic.com" rel="noopener noreferrer"&gt;Octrafic&lt;/a&gt; - an AI-powered CLI tool for API testing, written in Go, fully open-source.&lt;/p&gt;

&lt;p&gt;The core idea is simple: instead of clicking through a GUI or writing test scripts in a proprietary DSL, you describe what you want to test in plain English and the AI agent handles the execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start an interactive session against your API&lt;/span&gt;
octrafic &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;--spec&lt;/span&gt; path/to/spec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just describe what you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Check if the /users endpoint returns paginated results with proper metadata
&amp;gt; Test that creating a user with a duplicate email returns a 409 conflict
&amp;gt; Verify that the authentication token expires after the documented TTL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent figures out what requests to make, runs them against your real endpoints, validates the responses, and tells you what it found. No test script to write. No learning a new assertion syntax.&lt;/p&gt;

&lt;p&gt;If you have an OpenAPI spec, you can import it and Octrafic immediately understands your full API surface - endpoints, parameters, schemas, expected responses. This makes testing substantially more precise since the AI has context about what your API is actually supposed to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;octrafic &lt;span class="nt"&gt;--spec&lt;/span&gt; ./openapi.yaml &lt;span class="nt"&gt;--url&lt;/span&gt; https://api.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things I want to be upfront about: Octrafic requires your own LLM API key (OpenAI, Anthropic, or any OpenAI-compatible provider including local models via Ollama). The AI-powered workflow is powerful but different from traditional testing - it's better suited to exploratory and regression testing than to pixel-perfect assertion-based test suites. It's also a young project. Version 0.3.3 is out, and I'm actively building in public.&lt;/p&gt;




&lt;h2&gt;
  
  
  Side-by-Side Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;th&gt;Standout Feature&lt;/th&gt;
&lt;th&gt;AI-Powered&lt;/th&gt;
&lt;th&gt;Open Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Postman&lt;/td&gt;
&lt;td&gt;GUI Desktop&lt;/td&gt;
&lt;td&gt;Free / Paid plans&lt;/td&gt;
&lt;td&gt;Team collaboration, full ecosystem&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insomnia&lt;/td&gt;
&lt;td&gt;GUI Desktop&lt;/td&gt;
&lt;td&gt;Free / Paid plans&lt;/td&gt;
&lt;td&gt;GraphQL support, clean UI&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (forked)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thunder Client&lt;/td&gt;
&lt;td&gt;VS Code Extension&lt;/td&gt;
&lt;td&gt;Free / Paid plans&lt;/td&gt;
&lt;td&gt;IDE integration, zero setup&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hoppscotch&lt;/td&gt;
&lt;td&gt;Web / Self-hosted&lt;/td&gt;
&lt;td&gt;Free / Paid plans&lt;/td&gt;
&lt;td&gt;No install, self-hostable&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bruno&lt;/td&gt;
&lt;td&gt;GUI Desktop&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Git-friendly collections as files&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Octrafic&lt;/td&gt;
&lt;td&gt;CLI&lt;/td&gt;
&lt;td&gt;Free (bring your own LLM key)&lt;/td&gt;
&lt;td&gt;Natural language testing, CLI-first&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (MIT)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Where This Leaves Us
&lt;/h2&gt;

&lt;p&gt;Every tool in this list has a legitimate use case. Postman makes sense for large engineering teams who need shared workspaces and are willing to pay for it. Thunder Client is the obvious choice if you're in VS Code all day and just need fast endpoint validation. Bruno is compelling for teams who want their API collections to live in Git like everything else.&lt;/p&gt;

&lt;p&gt;I built Octrafic because I believe the future of API testing is conversational and automation-first. Describing what you want to verify and having an AI agent execute it is a fundamentally different experience than clicking through a GUI - and it fits better into how development actually flows when you're deep in a feature.&lt;/p&gt;

&lt;p&gt;If that sounds useful, the project is open-source on GitHub and I'd genuinely appreciate feedback from people trying it on real APIs. And if you're happy with one of the other tools, that's completely valid - I still think Bruno and Hoppscotch are excellent.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/octrafic/octrafic-cli" rel="noopener noreferrer"&gt;Octrafic on GitHub&lt;/a&gt; · &lt;a href="https://docs.octrafic.com" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; · &lt;a href="https://octrafic.com" rel="noopener noreferrer"&gt;octrafic.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>devtools</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>I Built an AI CLI That Lets You Chat With Your APIs</title>
      <dc:creator>Mikołaj Badyl</dc:creator>
      <pubDate>Wed, 11 Feb 2026 00:10:35 +0000</pubDate>
      <link>https://dev.to/mbadyl/i-built-an-ai-cli-that-lets-you-chat-with-your-apis-5fig</link>
      <guid>https://dev.to/mbadyl/i-built-an-ai-cli-that-lets-you-chat-with-your-apis-5fig</guid>
      <description>&lt;p&gt;Tired of writing Postman test scripts? I built Octrafic - a CLI tool where you describe API tests in plain English and AI executes them. It's open-source, runs locally, and supports multiple LLM providers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50f1qvdxr2dcrjcpm512.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F50f1qvdxr2dcrjcpm512.gif" alt=" " width="720" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;API testing sucks. You're either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicking through Postman manually (doesn't scale)&lt;/li&gt;
&lt;li&gt;Writing JavaScript test scripts (tedious boilerplate)&lt;/li&gt;
&lt;li&gt;Using curl and forgetting the syntax every time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something faster: load your API spec, describe what you want tested, get results. The AI figures out the right HTTP requests, payloads, and validations.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Install (single binary, no dependencies)&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;&lt;span class="c"&gt;# Linux/macOS&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://octrafic.com/install.sh | bash

&lt;span class="c"&gt;# Homebrew&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;octrafic/tap/octrafic

&lt;span class="c"&gt;# Windows&lt;/span&gt;
iex &lt;span class="o"&gt;(&lt;/span&gt;iwr &lt;span class="nt"&gt;-useb&lt;/span&gt; https://octrafic.com/install.ps1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Configure your AI provider&lt;/strong&gt;&lt;br&gt;
Octrafic supports Claude, OpenAI, OpenRouter, Ollama, or llama.cpp. You bring your own API key - nothing goes through my servers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run&lt;/span&gt;
octrafic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Load your API&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;octrafic &lt;span class="nt"&gt;-u&lt;/span&gt; https://api.example.com &lt;span class="nt"&gt;-s&lt;/span&gt; openapi.json &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"My API"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Start testing&lt;/strong&gt;&lt;br&gt;
The AI understands your API structure and generates appropriate requests based on natural language:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flenl0q7q6z0psyagpzcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flenl0q7q6z0psyagpzcv.png" alt=" " width="792" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Stack
&lt;/h2&gt;

&lt;p&gt;Go - Single binary distribution across Linux, macOS, Windows. No runtime dependencies.&lt;/p&gt;

&lt;p&gt;Bubble Tea - Terminal UI framework for interactive chat interface. Arrow key navigation, command history, proper scrolling.&lt;/p&gt;

&lt;p&gt;Multi-LLM Support - Built adapters for Claude, OpenAI, OpenRouter, Ollama, and llama.cpp. Switch providers without changing your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Use Cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;API Exploration&lt;/strong&gt; - Point it at an unfamiliar API and ask questions. &lt;code&gt;What does this endpoint do?&lt;/code&gt;&lt;br&gt;
&lt;code&gt;What parameters does it accept?&lt;/code&gt;&lt;br&gt;
Faster than reading docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Testing&lt;/strong&gt; - &lt;code&gt;Test this endpoint with edge cases&lt;/code&gt; generates multiple requests with boundary conditions, missing fields, invalid data types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manual Testing Alternative&lt;/strong&gt; - Instead of clicking through Postman, describe what you want tested. The AI executes and shows results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local Models&lt;/strong&gt; - Privacy-focused? Run Ollama or llama.cpp locally. Your API data never leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current State
&lt;/h2&gt;

&lt;p&gt;It works. I use it daily for API testing. A few other developers are using it too.&lt;br&gt;
That said, it's alpha software. Some features are rough. But the core is solid and I'm actively fixing issues.&lt;/p&gt;

&lt;p&gt;GitHub repo: &lt;a href="https://github.com/Octrafic/octrafic-cli" rel="noopener noreferrer"&gt;https://github.com/Octrafic/octrafic-cli&lt;/a&gt;&lt;br&gt;
Website: &lt;a href="https://octrafic.com" rel="noopener noreferrer"&gt;https://octrafic.com&lt;/a&gt;&lt;br&gt;
Try it. Open issues for bugs. PR's welcome if you want to contribute.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
