CLI tool
httptoolkit/httptoolkit-server avatar
httptoolkit/httptoolkit-server

httptoolkit-server, the proxy backend behind HTTP Toolkit

The backend of HTTP Toolkit

569 stars142 forksJavaScriptAGPL-3.0

At a glance

What is it?
httptoolkit-server is the Node backend for HTTP Toolkit, exposing a REST and GraphQL API that lets a web UI start a local Mockttp proxy, launch applications preconfigured for interception, and install a trusted certificate. It is normally reached through the Electron desktop app rather than used directly.
Who is it for?
httptoolkit-server suits a developer who wants HTTP Toolkit's interception machinery without the Electron desktop app, for instance to drive a proxy from a script or to embed in a test harness, and it suits a contributor who wants to add an interceptor. It does not suit someone looking for a general-purpose debugging proxy, since the API exists to serve one specific UI, and the interceptor set has to exist on both the server and the UI side.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A backend that exists to serve one web UI

httptoolkit-server is described simply as the backend for HTTP Toolkit, a cross-platform, open-source HTTP and HTTPS debugging proxy, analyzer and client. The distinction matters immediately, because most people looking at this repository are looking for the proxy itself, and the proxy is not here.

HTTP Toolkit runs everything possible inside a standard single-page web application. The README names the two things a web application cannot do. It cannot start a locally running proxy server, and here that is done with Mockttp. And it cannot launch local applications preconfigured for interception.

So this server exposes an API used by the web UI, providing those actions and some related information, with the full API details in `src/api/rest-api.ts`. The UI in question lives in a separate repository, httptoolkit-ui, and the README points out that the set of interceptors available in HTTP Toolkit depends on both the interceptors available on the server and the interceptors defined in the UI. New interceptors have to be added to both sides, which is a real constraint for anyone extending the tool.

The primary consumer is the desktop app. The README says the server is typically used by users through httptoolkit-desktop, which builds the server and the web UI into an Electron application and starts and stops the server in the background whenever that app runs. Each time the desktop app is built, a new Electron app is created containing the latest release from this repository, and the desktop app installs it automatically and updates it in the background, pulling new releases from the GitHub releases of this repository.

That auto-update path is worth noting for a self-hoster. The desktop app treats the server as a replaceable component, and the update mechanism is a pull from the GitHub releases, which means the security model of a long-running instance depends on that release feed.

The interceptors and the certificate check server

The interceptor set is the part of this project with the most visible effect on a user's machine, and it lives in `src/interceptors`.

The repository layout shows how the pieces are assembled. There is `src/` for the source, `bin/` with the `httptoolkit-server` CLI entry point, `nss/` for the NSS-related files, `overrides/`, `custom-typings/`, a `test/` directory, `pack.ts` and `prepare.ts` for packaging, `build-release.sh`, `rspack.config.js` for the bundle, `tsconfig.json` and `wallaby.js` for the test runner configuration.

The interceptor directories are the interesting part of the layout, and their names tell you what the tool does on a machine. Android is covered through `@devicefarmer/adbkit`, which is in the dependency list, and the dependency list also includes `@httptoolkit/browser-launcher`, `@httptoolkit/dbus-native` for Linux desktop integration, and `@httptoolkit/osx-find-executable` for macOS.

The certificate handling is the piece that has a dedicated file and a documented behaviour. The README states that some interceptors also use other services in the repository, giving `src/cert-check-server.ts` as the example, which automatically checks if a certificate is trusted by a browser client, and downloads or installs, depending on the client, the certificate if not.

That check-then-install flow is a deliberate design rather than a convenience. Installing a root certificate into a system trust store is the thing that makes HTTPS interception work, and doing it silently is how debugging proxies have earned their reputation. Here the server asks the client whether the certificate is already trusted, and only then proceeds, which means the install happens in a context the user is watching rather than as a side effect of starting a proxy.

The other side of that design is the security warning. The README notes that the API is very powerful because it can launch arbitrary applications on your machine, and that the API only listens on localhost and blocks CORS requests, so strictly speaking setting a token should not be necessary, but it is useful as a stronger guarantee and as defense in depth.

Running it standalone with oclif

The server is runnable standalone as a CLI using oclif, or it can be imported into other modules to be run programmatically, which is the interesting option for anyone who wants the interception machinery without the desktop app.

The build and run scripts are in the package manifest, and they are the quickest way to see how the pieces fit together.

json
    "start": "node --watch ./bin/run start",
    "test": "npm-run-all test:unit test:integration",
    "test:unit": "mocha --exit 'test/unit/*.spec.ts'",
    "test:integration": "mocha --exit 'test/integration/**/*.spec.ts'",

The start script runs the oclif entry point with node's watch mode, so the server restarts as you edit. The test scripts split the suite into unit and integration halves, both run through Mocha with the `tsx` loader registered as a node option, and the integration variant takes a `TEST_BUILT_TARBALL` environment flag so the same tests can run against a built artefact rather than the source tree.

The README's contributing steps are the shortest path to a working local setup. You clone the repository, run `npm install`, then `npm start`, and at that point a Mockttp standalone server starts on port 45456 and a GraphQL management server on 45457.

Those two ports are the whole interface surface for a local instance. The proxy is 45456 and the management GraphQL server is 45457, and the split tells you the architecture: the traffic interception path and the control API are separate services, which is what lets a UI talk to the management server without touching the proxy's own protocol.

The README then gives you three ways to use it. You can make requests to the servers by hand, use the production UI by opening `https://app.httptoolkit.tech` in a Chromium-based browser, or run a local UI by setting it up from the httptoolkit-ui repository, running `npm run start:web` there to start the UI without its own server, and opening `http://local.httptoolkit.tech:8080` in a Chromium-based browser.

The requirement for a Chromium-based browser is not incidental, since the certificate trust check depends on a browser client that can report back on trust state.

The token, the localhost bind and the exposure question

The README devotes a specific paragraph to securing the server, and it is the part most worth reading twice before you deploy anything.

If running the server in serious use, meaning self-hosting or long-term ongoing development, the recommendation is to set an `HTK_SERVER_TOKEN` environment variable with a random key, and to pass this similarly to the UI as an `authToken=<token>` URL parameter. The stated reasoning is that the API is very powerful, since it can launch arbitrary applications on your machine. The API only listens on localhost and blocks CORS requests, so strictly speaking this should not be necessary, but it is useful as a stronger guarantee and as defense in depth. This is handled automatically in the production desktop app.

That is a well-judged threat model, and it is worth understanding each layer. The localhost bind means the API is not reachable from the network by default. The CORS block means a browser page on another origin cannot drive the API. The token adds an explicit credential on top of both, so a malicious local page that somehow gets a foothold still needs the key.

What the API can do is the reason all this matters. Launching arbitrary applications on your machine with the environment preconfigured for interception means the API can start a browser pointed at a proxy, or start an application with proxy settings injected, and that is a capability worth protecting carefully. The MITM proxy itself is a local capability by design, since interception is the product, so the token is not there to stop legitimate interception, it is there to stop someone else driving your machine through the interface.

The README is also honest that this is not a hardened public service. It describes the token as belt-and-braces on top of a localhost-only API, and the desktop app wires it up automatically, which means the common path is safe by default.

One detail that is easy to miss and that matters for a self-hosted deployment: the server updates itself in the background, pulling new releases from the GitHub releases of this repository. That is convenient and it means an unattended instance changes its own code without a human decision, so an operator has to decide whether that is acceptable in their environment.

Testing it, and the Docker dependency

The test story is conventional but has a real environmental cost, and the README says so.

Both unit and integration tests run with `npm test`, or with `npm run test:unit` and `npm run test:integration` to run just one half. The integration tests assume the required applications are installed and that some Docker images are already pulled. The README points at `ci.yml` for the setup and at the build-base image in the httptoolkit/act-build-base repository as an example, and suggests that if you are not using that, you can just run the tests, look at the errors, and install whatever is missing.

That last suggestion is the honest workflow for a repository whose integration tests shell out to real applications. The point of these tests is that interception has to work against real browsers and real applications rather than mocks, and that is exactly what makes them slow and environment-dependent.

The packaging side is also worth understanding, because it explains the split between source and published artefacts. The scripts include `build:src:clean`, which removes the `lib` directory, `build:src:ts` which runs the TypeScript compiler, `build:manifest` which generates the oclif manifest, `build:bundle` which runs rspack, `build:pack` which runs the `pack.ts` script, and `build:release` which chains the manifest, bundle and pack steps. The published files are limited to `oclif.manifest.json`, `/bin`, `/lib` and `/overrides`, so the npm package does not carry the source tree, the tests or the type declarations beyond the `types` entry pointing at `lib/index.d.ts`.

The `preinstall` script runs `check-msvc-runtime`, which is the project checking for the Microsoft Visual C++ runtime before installation on Windows. That is a small detail that tells you something about the audience, since it means the server expects to be installed on a developer Windows machine and does the environment check for you.

The licence is AGPL-3.0, which is the significant constraint for anyone thinking of embedding this server. The AGPL reaches network use, so a modified version offered to users over a network carries source obligations. That is worth taking seriously before building on it, and it is the licence to read before deciding, not after.

The alternatives, and the real difference

The obvious alternatives to this repository are the other debugging proxies, and there is a real difference in what each one is.

Mitmproxy, Fiddler and Charles sit in the same functional space. Mitmproxy is a scriptable, terminal-oriented proxy, while Fiddler and Charles are GUI-driven proxies. The HTTP Toolkit family differs in where the interface lives: the bulk of the experience is a single-page web application, and this repository exists only to provide the two capabilities a browser cannot have, which is running the proxy and launching applications already pointed at it.

That difference shows up in the launch-and-intercept workflow. A plain proxy expects you to configure your application to use it, by setting an HTTP proxy environment variable or changing system settings. HTTP Toolkit can do that for you, launching a browser or an application with the proxy configured, which is what the interceptors in `src/interceptors` are for, and the Android interceptor using adbkit goes further and configures a device over ADB.

A second alternative is not a proxy at all. If your need is to script and assert on HTTP traffic rather than to watch it, a test-oriented tool is a better fit, and the distinction is one of workflow. This server exposes an API for a UI to drive. If you want to write assertions, you want a library that gives you a request client and a mocking layer, not a long-running proxy with a management GraphQL server on port 45457.

The case for this repository specifically is that you want the HTTP Toolkit experience without the Electron application around it: in CI, in a container, or driven from a script through the programmatic import path the README mentions. The case against it is that the API was designed for one client, and an interceptor that is not registered in `src/interceptors/index.ts` and mirrored in the UI will not appear.

Editorial conclusion

httptoolkit-server suits a developer who wants HTTP Toolkit's interception machinery without the Electron desktop app, for instance to drive a proxy from a script or to embed in a test harness, and it suits a contributor who wants to add an interceptor. It does not suit someone looking for a general-purpose debugging proxy, since the API exists to serve one specific UI, and the interceptor set has to exist on both the server and the UI side. Verify first that the API only binds to localhost as the documentation states, that you set `HTK_SERVER_TOKEN` if the server is anything other than a local scratch instance, because the API can launch arbitrary applications on the machine, and that the AGPL-3.0 licence fits how you intend to use it.

Frequently asked questions

What is httptoolkit-server used for?

It is the backend for HTTP Toolkit, exposing a REST and GraphQL API that the web UI uses to start a local Mockttp proxy, launch applications preconfigured for interception, and check or install the trusted certificate. It can also be run standalone as an oclif CLI or imported into other modules.

How do I run httptoolkit-server locally?

Clone the repository, run npm install and then npm start. A Mockttp standalone server starts on port 45456 and a GraphQL management server on 45457, and you can then point a Chromium-based browser at the production UI or at a locally hosted one.

How do I secure the httptoolkit-server API?

The API listens only on localhost and blocks CORS requests, but the README recommends setting an HTK_SERVER_TOKEN environment variable with a random key for self-hosting or long-term use, and passing it to the UI as an authToken=<token> URL parameter, since the API can launch arbitrary applications on your machine.

Do I need the httptoolkit UI to use httptoolkit-server?

Not strictly. The server is runnable standalone as a CLI using oclif or can be imported into other modules to be run programmatically, and you can also make requests to its servers by hand. The web UI is only the usual client for it.

How do I add a new interceptor to httptoolkit-server?

Add it under src/interceptors and register it in src/interceptors/index.ts, and also add it to the httptoolkit-ui repository, because the set of available interceptors depends on both the server and the UI.

What licence does httptoolkit-server use?

AGPL-3.0, with the LICENSE file at the top of the repository. The package is published to npm as httptoolkit-server at version 1.27.2, with the httptoolkit-server binary exposed through the bin/run entry point.

Official sources

  1. httptoolkit/httptoolkit-server on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/httptoolkit-httptoolkit-server.svg)](https://hysenlabs.com/projects/httptoolkit-httptoolkit-server)

Was this useful?