Network cables and switches glowing in a dark server room

NetEngine Is Now Open Source: Building One Desktop Console to Replace Ten Network Tools

I got tired of juggling a scanner, a terminal, PuTTY, WinSCP, Postman, and a ping window just to fix one network problem. So I built NetEngine — eight network tools in one private, local-first PyQt6 console with an AI automation layer. Here's how it works, what I learned building it, and why it's now free and open source.

Today I'm open-sourcing NetEngine — a private, local-first desktop command center for real network work. It puts a scanner, an embedded terminal, multi-tab SSH, SFTP file transfer, adapter control, a live link monitor, an API console, and an AI automation layer into one keyboard-driven app. No accounts. No cloud. No subscription. Just download it, or run it from source in about a minute.

This post is the build story: the problem that pushed me to make it, the architecture that holds eight tools together without turning into spaghetti, the hard parts, what I learned, and why I decided to give the whole thing away.

A dark, focused workstation with multiple terminal windows open
The problem NetEngine solves: too many windows, too much context-switching, for one job.

The Problem: Death by Context-Switching

If you've ever done hands-on network work — setting up a homelab, debugging a flaky connection, provisioning a fleet of machines, or just figuring out what is actually on this subnet — you know the ritual. It goes something like this:

  1. Open a scanner (or nmap in a terminal) to find live hosts.
  2. Copy an IP into PuTTY to SSH in.
  3. Open WinSCP or FileZilla in a separate window to move files to that same host.
  4. Keep a ping window running to watch if the link drops.
  5. Fire up Postman to hit an internal API on that box.
  6. Drop into PowerShell for the commands the GUI tools can't do.
  7. Dig through adapter settings buried five clicks deep in the OS to switch a static IP.

That's seven tools, each with its own window, its own connection state, its own copy-paste dance. The actual work — the thinking — gets drowned in tool management. You lose your place constantly. The IP you scanned isn't the IP your SSH client knows about. The file you want to transfer is in a session the transfer tool can't see.

The insight behind NetEngine is simple: all of these tools operate on the same context — the same hosts, the same sessions, the same network. So why are they seven separate programs that know nothing about each other? What if the scanner result flowed straight into an SSH session, and that SSH session was already wired to the file-transfer pane, and the AI assistant could see all of it?

That "what if" became NetEngine.

What NetEngine Actually Is

NetEngine is a cross-platform desktop application built in Python with PyQt6. It ships as a native build for Windows (.exe), macOS (.dmg), and Linux (.AppImage / .deb), or you can run it from source with Python 3.10+. Everything runs on your machine — it's local-first by design, with no telemetry and no account wall.

Behind one keyboard-driven sidebar are eight tools:

#ToolWhat it does
01Network ScannerLive subnet sweep — finds hosts, vendors, latency, reachability, and open ports in one focused table.
02Embedded TerminalPowerShell, CMD, WSL, or bash in the same workspace, with history and shortcuts.
03SSH SessionsMulti-tab SSH with saved profiles, persistent scrollback, and one-click reconnect.
04File TransferDual-pane SFTP browser with a live transfer queue, wired directly to your SSH sessions.
05Adapter ControlInspect interfaces and switch DHCP ↔ static with named, saved profiles.
06Live MonitorContinuous ping, packet loss, and latency you can read at a glance.
07API ConsoleProbe endpoints with methods, auth, headers, JSON bodies, and saved requests.
08AI AssistantAutomate approved tasks and explain results using Ollama, OpenAI, or Groq.

The tagline I landed on says it best: eight tools, zero context switching. Everything a network job needs, behind one sidebar.

A clean network topology diagram with nodes and connections
One console, one shared context — the scanner, the shell, SSH, and transfer all speak to the same network.

The Architecture: How Eight Tools Share One Brain

The hardest engineering problem in NetEngine isn't any single tool — a port scanner or an SFTP browser are well-trodden ground. The hard part is making eight tools coexist in one process without stepping on each other, while sharing enough state to feel like a single application.

Here's the shape of the solution.

A responsive UI over blocking work

Network work is slow and blocking by nature. A subnet sweep pings 254 hosts. An SSH handshake waits on a remote server. A file transfer streams megabytes. If any of that runs on the UI thread, PyQt6 freezes — the spinner of death.

The rule I held to everywhere: the GUI thread only paints; work happens off it. Each long-running operation — a scan, an SSH channel, a transfer job — runs on a Qt worker thread (QThread / QThreadPool) and communicates back to the UI exclusively through signals and slots. The scanner emits a hostFound signal per discovered host, and the results table appends a row. The transfer worker emits progress per chunk, and the queue's progress bar advances. Nothing blocks; the app stays buttery even during a full sweep.

The single most important lesson from building a desktop app that does real I/O: your event loop is sacred. Every blocking call you accidentally leave on it is a freeze your users will feel. Signals and slots aren't boilerplate — they're the whole discipline.

Shared session state as the backbone

The reason the tools feel connected is a shared session/context layer that sits underneath all eight panels. When the scanner finds a host, that host is a first-class object other tools can act on. When you open an SSH session, the file-transfer pane can attach to that same connection rather than reconnecting. The AI assistant reads from this shared context so it can reason about "the scan you just ran" or "the session you're in."

This is the architectural payoff of putting everything in one app: state stops being trapped inside separate programs. A scanned IP, an open SSH channel, and an SFTP browser are all views onto the same underlying connection.

A plugin-shaped tool model

Adding an eighth tool shouldn't require rewiring the other seven. Each tool is a self-contained panel that registers with the sidebar and talks to the rest of the app through the shared context and a common signal bus. That boundary is what kept the codebase from collapsing under its own weight as it grew from a scanner into a full console.

The AI Layer: Automation That Asks Permission First

The part I'm most proud of is the AI automation layer — and specifically the way it's designed to be trustworthy, not just impressive.

The assistant can take plain English — "check which hosts on this subnet have SSH open and aren't responding to ping" — and turn it into a concrete plan. But here's the key design decision: plain English becomes a reviewed action plan before anything runs. The AI never silently executes commands against your network. It proposes; you approve. AI-suggested terminal commands are inserted, not auto-run. Automation is scoped to approved tasks.

The other deliberate choice was provider independence:

  • Ollama runs models fully locally on localhost:11434 — the whole app, AI included, works with zero internet and zero data leaving your machine.
  • OpenAI and Groq plug in via API key when you want hosted horsepower — "borrowing someone else's GPUs," as I put it on the site.

That local-first default matters. Network diagnostics touch sensitive infrastructure. Sending your internal topology to a cloud model by default would be the wrong trade. With Ollama, the private path is the default path, and the cloud is opt-in.

Abstract visualization of an AI model processing a request
The AI assistant turns plain English into a reviewed plan — it proposes, you approve.

The Hard Parts (and What They Taught Me)

Every project's real lessons live in the parts that fought back. A few that stuck with me:

Threading discipline is non-negotiable. My earliest builds froze constantly because I'd sneak a blocking call onto the UI thread "just this once." The fix wasn't cleverness — it was rigor. Every I/O path gets a worker; every result comes back over a signal. Once I internalized that, whole categories of bugs disappeared.

Cross-platform is a tax you pay continuously, not once. PowerShell vs. CMD vs. WSL vs. bash. Windows adapter APIs vs. Linux ip/nmcli vs. macOS networksetup. Path separators, permission models, the way each OS reports network interfaces — they're all different. Abstracting the terminal backend and the adapter control behind a common interface, so the UI didn't care which platform it ran on, was some of the most finicky and valuable work in the project.

"Local-first" is an architecture, not a label. It's easy to say "no cloud." It's harder to mean it — to make sure the scanner, the AI, the profiles, and the saved requests all persist and function with the network unplugged. Designing for offline from day one forced cleaner boundaries everywhere.

Packaging a Python GUI is its own boss fight. Turning a PyQt6 app into a 44 MB double-clickable .exe (and a .dmg, and an .AppImage) meant wrestling with bundlers, hidden imports, and native dependencies. It's the unglamorous 20% that decides whether normal people can actually use what you built — so it's worth doing well.

Good defaults beat more features. The seven themes — Dark, Neon, Space, Liquid Glass, Light, OG Black, Retro Terminal — and the always-visible status bar (activity, current tool, live CPU/memory, clock) weren't afterthoughts. Deep work loses its place easily; the details that keep you oriented are what make a tool something you reach for instead of just have installed.

The Tech Stack, End to End

For anyone who wants to build something similar, here's the stack that made NetEngine work:

LayerChoiceWhy
LanguagePython 3.10+Fast to build, huge networking ecosystem, cross-platform.
GUI frameworkPyQt6Native performance, mature widget set, real threading via QThread.
ConcurrencyQt signals/slots + worker threadsKeeps the UI responsive over blocking network I/O.
SSH / SFTPParamiko-style SSH transportMulti-session SSH and a dual-pane transfer queue on one connection layer.
Local AIOllama (localhost:11434)Fully offline model inference, private by default.
Cloud AIOpenAI + GroqOptional hosted models via API key.
PackagingNative bundlers per-OSShips .exe, .dmg, .AppImage/.deb.
Landing siteNext.jsThe netengine.sharvik.tech marketing/download page.

Why I'm Making It Open Source

I built NetEngine to solve my own problem. But the more I used it, the more it felt like the kind of tool that shouldn't be locked up.

Network tooling is fragmented, and a lot of the good stuff is either paid, cloud-tethered, or telemetry-heavy. A private, local-first console that respects your machine and your data is something I'd want to exist whether or not I'd built it — so making it free and open source was the natural move. It means anyone can audit exactly what it does with their network (which, for a tool that touches your infrastructure, matters), extend it with tools I haven't thought of, and never worry about a login wall or a subscription showing up later.

It's on GitHub at github.com/SharvikS/NetEngine. Issues, pull requests, and new-tool ideas are all welcome.

Try It

You can grab NetEngine right now:

# any platform, Python 3.10+
git clone https://github.com/SharvikS/NetEngine.git
cd NetEngine && pip install -r requirements.txt
python main.py
  • For AI features, install Ollama for the fully-local path, or drop in an OpenAI/Groq key.

Stop switching tools. Start closing tickets. NetEngine gives you the scanner, the shell, the transfer queue, the monitor, the API console, and the AI automation layer in one private desktop console — and now, all of the source too.

→ Explore NetEngine · ⭐ Star it on GitHub

Enjoyed this post?

Subscribe to get the next one in your inbox. No spam, unsubscribe anytime.

Your email stays private. One click to unsubscribe in every email.