macless-haystack and the case for running your own FindMy endpoint
Create your own AirTag with OpenHaystack, but without the need to own an Apple device
At a glance
- What is it?
- macless-haystack bundles OpenHaystack, several firmware forks and a Python report fetcher into one Docker setup so you can run a FindMy network without owning a Mac. It is a legitimate privacy project, and it asks you to hand your Apple ID password and an SMS code to a container chain that talks to a third-party Anisette server, which is the trade you have to weigh before installing it.
- Who is it for?
- Adopt macless-haystack if your goal is to own the whole path from tag advertisement to location report, and you are prepared to give an Anisette container your Apple ID password and an SMS two-factor code. Do not adopt it to track anyone but yourself, and do not expose port 6176 to a network you do not control, because the endpoint announces itself over plain HTTP.
- 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?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What macless-haystack removes from the OpenHaystack setup
The original OpenHaystack project, from the seemoo-lab group, is a privacy research effort into Apple's FindMy network. Its cost of entry is what this repository attacks. Running it means having a Mac, or provisioning a virtual Mac, plus a mail plug-in to intercept the report-fetching email flow, plus a checkout of the upstream project and its own dependencies. Three separate pieces of friction before you have seen a single dot on a map.
macless-haystack's stated goal is to unify the surrounding projects into something you can install and set up easily, and to run a FindMy network with no real or virtual Mac at all. The README also notes that you do not have to install the mail plug-in or OpenHaystack itself, which are the two steps the upstream documentation treats as mandatory. What you get instead is a single Docker image on Docker Hub as `christld/macless-haystack`, an Android application, and firmware for two hardware families.
The audience is narrow and self-selecting. It is people who already own OpenHaystack-compatible tags and want the location reports to land on infrastructure they control, plus people who want to read the protocol rather than take Apple's word for where their tag's data goes. It is not a consumer tracker app. If you only want to find your own keys, Apple's own tooling already does that, and macless-haystack is a much larger commitment for a much different reason.
The chain: keypair, tag firmware, Python endpoint, Anisette, frontend
Understanding the pieces explains most of the setup steps, so it is worth naming what each one does.
The keypair comes first. `generate_keys.py`, which you download from the repository's releases, produces a private key that the tag uses to derive its advertisement key and a public key that the report infrastructure uses to decrypt what the tag broadcasts. The README notes that the script needs the `cryptography` package, and that after generation the Base64-encoded advertisement key is what you actually flash. For most setups that single value is the only thing you take out of the file.
The tag firmware is the second piece, available for ESP32 and for NRF5x, with instructions in `firmware/ESP32/README.md` and `firmware/nrf5x/README.md`. The README states that in general any OpenHaystack-compatible device or its firmware also works, and gives the ST17H66 as an example, which means the hardware requirement is softer than the project name suggests.
The endpoint is a Python web server, inherited from Biemster's FindMy work and adapted here to output a JSON array for the ESP32 firmware and a JSON file for import into the Android app. The Android client is the Dart part of the repository, and it is the only mobile client: the README describes the upstream OpenHaystack code as stripped down to the Android application and ESP32 firmware, because this technique has no iOS path. The front end can be the project's GitHub Pages deployment, your own copy of that web server, or the Android app.
Anisette is the piece people miss. It sits beside the endpoint as a separate container and is what makes talking to Apple's authentication possible without a Mac. Two containers, two ports, and one shared Docker network.
Generating the keypair and flashing ESP32 or NRF5x firmware
The hardware half of the setup is short. Go to the repository's releases, download `generate_keys.py` and the firmware zip for your device, then run the key generator, which needs the `cryptography` package:
pip install cryptographyUnzip the firmware and flash it to the tag, following the instructions for your family. The README's own note is the important part for anyone reusing existing hardware: the generator writes a `.keys` file, and typically the only value you need from it is the Base64-encoded advertisement key.
That single value is the entire interface between the keypair and the device. It is also the part that goes wrong most often, because a tag flashed with a key that does not match the one registered in the endpoint will broadcast happily and never appear on a map. The failure mode is silent in the worst way: the tag looks powered, the server looks healthy, and the report never comes. If you flash more than one tag, generate keys for each and keep the files apart.
The firmware itself is not all from one place, and the battery behaviour reflects that. The ESP32 firmware is described as OpenHaystack's combined with the FindYou project plus power optimisations, with the battery optimisation work credited to positive-security's find-you fork. The NRF5x firmware is the alternative credited to acalatrava's OpenHaystack-Firmware project. The top-level `.gitmodules` file is how those upstream pieces are pulled in, so a fork or a rebase of this repository is where that credit has to be maintained.
Bringing up the endpoint and Anisette in Docker
The server half is four commands. Create a network so the two containers can talk to each other, start Anisette, start the endpoint interactively so it can ask for your credentials, then restart it in the background:
docker network create mh-network
docker run -d --restart always --name anisette -p 6969:6969 --volume anisette-v3_data:/home/Alcoholic/.config/anisette-v3 --network mh-network dadoum/anisette-v3-server
docker run -it --restart unless-stopped --name macless-haystack -p 6176:6176 --volume mh_data:/app/endpoint/data --network mh-network christld/macless-haystack
docker restart macless-haystackPort 6969 belongs to Anisette and 6176 to the endpoint. The third command runs with `-it` on purpose: on first start the endpoint asks for your Apple ID, your password and your two-factor code, and it will not finish initialising until you supply them. The README gives you the success signal to look for, which is a line reading `serving at port 6176 over HTTP`. If you do not see that line, the setup is not done, and the interactive run is where the error will be.
The fourth command exists because the first run was interactive. Once the data volume at `/app/endpoint/data` has your account stored, restarting takes it out of the foreground and into the background, and `--restart unless-stopped` means it comes back on reboot.
For the front end, the README gives three choices: install the Android application, browse to the project's GitHub Pages deployment, or host that web server yourself. Either way you import the `PREFIX_devices.json` file into the client, and if the front end is not on the same machine as the endpoint you have to set the endpoint URL in the settings. The FAQ has a section on using SSL when the endpoint runs on a different machine than the UI, and that is the one to read before you do this across two hosts.
Your Apple ID password, an SMS code, and a plain HTTP endpoint
This is the part of the project that deserves the most scrutiny, and the README is upfront about the mechanics. You type your Apple ID, your password and a two-factor code into an interactive container. The prerequisite list is explicit that the Apple ID must have two-factor enabled and that only SMS or text message as a second factor is supported, which rules out the more private authenticator-app path. A separate container, the Anisette server, is the component that performs the Apple-side authentication, and it is a third-party image rather than code in this repository.
The consequence is that the security of your Apple account now depends on a chain you assembled yourself: this project's Python endpoint, the Anisette image from Docker Hub, and Apple's own servers. AGPL-3.0 governs the code in this repository and its derivatives. It does not govern what Anisette does with a credential, and it is worth being clear that the licence is not a security control here.
The second exposure is the transport. The success message the README tells you to look for ends with `over HTTP`, so the endpoint on port 6176 is not encrypted by default. On a home server on a trusted LAN that is a defensible default, and the FAQ's SSL section exists for the split-host case. Publishing that port to the internet without a reverse proxy terminating TLS would put your location history and your device list in the clear.
The last thing to weigh is the disclaimer. The README states that the repository is for research purposes only, that use is your responsibility, and that by using any of the files you agree to use them at your own risk. Projects that carry that language are telling you something real about the legal position of tracking hardware you may not own.
macless-haystack against a stock OpenHaystack install, and against not doing this at all
Two comparisons matter, and the second one is the more honest.
Against upstream OpenHaystack, the difference is packaging. Upstream wants a Mac or a virtual Mac, a mail plug-in to catch the report email, and a manual build of each component. This project ships a Docker image, a key generator that emits firmware-ready output, a prebuilt Android client, firmware for two hardware families with battery optimisations folded in, and a web front end you can open in a browser. The capability is equivalent; the setup cost is a fraction. What you give up is proximity to the research code, because the upstream source is now several forks deep and `.gitmodules` decides how much of it you actually see.
Against not doing it at all: if you want to see where your own keys and tags are, the FindMy app on your phone already answers that, with Apple's infrastructure doing the work and no credentials typed into a container. The reason to accept macless-haystack's terms is not convenience. It is that the report path runs where you can inspect it, that the data lands in a file you own, and that you can read the protocol instead of trusting a black box. That is a privacy argument, and it only holds if you are the tag's owner. The same pipeline pointed at someone else's tag is a different activity with different consequences, and the README's research-only language is not a technical obstacle to it.
AGPL-3.0, eight months since the last tag, and no changelog in the tree
The licence is the GNU Affero General Public License version 3, with the text in the `LICENSE` file at the repository root. That is the strongest copyleft variant and the one with the clause that matters most for this project: if you modify the software and let others interact with it over a network, you owe those users the corresponding source of your version. For a self-hosted service that is a live obligation, not paperwork, and it is a poor fit for a team that intends to keep modifications private. This is a reading of the licence terms rather than legal advice.
The maintenance picture is quiet rather than closed. The repository is not archived, and the last push was on 2026-03-15, the same day as release v2.7.2. Before that, v2.7.0 landed on 2025-07-25 and v2.6.1 on 2025-03-09, so the gap between the last two tags is close to eight months and the gap before that was four. A `version` file sits at the top level of the tree, but there is no `CHANGELOG.md` among the top-level entries, so what changed in any given release has to be read from the GitHub release notes rather than from the repository.
Contributing has one instruction that catches people out: the README asks you to fork from the dev branch rather than main, and to open an issue before any major change. Given a project that stitches together four upstream efforts, that policy is the mechanism that keeps the credits accurate, and it is worth respecting if you plan to send a patch.
Editorial conclusion
Adopt macless-haystack if your goal is to own the whole path from tag advertisement to location report, and you are prepared to give an Anisette container your Apple ID password and an SMS two-factor code. Do not adopt it to track anyone but yourself, and do not expose port 6176 to a network you do not control, because the endpoint announces itself over plain HTTP. Verify first by generating a keypair with generate_keys.py, confirming the .keys file contains the Base64 advertisement key for your tag, and reading FAQ.md on SSL before you put the frontend on a different machine from the endpoint.
Frequently asked questions
What does macless-haystack actually replace?
It replaces the Mac requirement, the mail plug-in and the manual OpenHaystack install. The stated goal is to run a FindMy network without owning a real Mac or a virtual Mac, by unifying OpenHaystack, Biemster's FindMy web server, and firmware forks into one Docker setup with a mobile client.
What are the prerequisites for macless-haystack?
The README lists Docker, Python3 with pip3, and an Apple ID with two-factor authentication enabled, where only an SMS or text message as the second factor is supported. You also need an OpenHaystack-compatible tag and either the ESP32 or the NRF5x firmware.
How do I generate keys and flash the firmware?
Download generate_keys.py and the firmware zip for your device from the repository releases, install the cryptography package with pip install cryptography, then run the generator and flash the firmware following the ESP32 or NRF5x instructions. The README notes that the Base64-encoded advertisement key in the generated .keys file is typically the only value you need.
Which ports does macless-haystack use?
The Anisette server container maps port 6969 and the macless-haystack endpoint maps port 6176, both on the mh-network Docker network. The README's success signal is a line reading serving at port 6176 over HTTP, which also tells you the endpoint is not encrypted by default.
Can I use macless-haystack from an iPhone?
No iOS client is included. The README describes the upstream code as stripped down to the Android application and ESP32 firmware, and lists the front end options as the Android app, the project's GitHub Pages deployment, or a web server you host yourself, with PREFIX_devices.json imported into the client.
What licence is macless-haystack under?
It is licensed under the GNU Affero General Public License version 3, with the text in the LICENSE file at the repository root. The README also carries a disclaimer that the code is for research and education, and that using it is at your own risk.
Official sources
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.
[](https://hysenlabs.com/projects/dchristl-macless-haystack)