Even though I am someone who tends to be the guy telling people at work to use caution in how they use AI, I still don’t believe that AI will go away or that we can just ignore it or block it. So I keep working with AI (nee Super Intelligence) in increasing ways, coming up with ways that I can use it to create things that are safe and useful. I think this will help me to better control for risks, even as I push into more and more capabilities.
A few weeks ago I was in a data center in Atlanta. It was the middle of the night during a marathon troubleshooting call, and I just wanted to verify that the MAC address I was seeing was what I expected it to be. I went to Google and searched for “mac address lookup” like I had so many times before and chose the first listing. Instead of looking up a MAC address, I ended up getting a cookie consent dialog that I had to dismiss before I could enter the MAC address. Then, between the MAC address search box and the result, there were ads filling up the screen. Going back to search and trying other sites, even ones I had used many times before, I still had ads and annoyances.
With how simple of a task this is, I thought it should be possible to host a MAC address lookup site for close to free, regardless of how much it is used (although maybe not free to buy your way to the top of the search engine rankings). So I decided to try my hand at it. I built one, and now it is at mac.jasontally.com. No need to go searching for something. I can just type it in and use it.

This allowed me to try a few patterns I had not tried before.
A static database: using the user’s compute to do the query
One of the big costs and risks of running a website is the server that hosts the code and the database server that it runs on. In order to keep costs and risks low, I decided to use a set of JavaScript based libraries called hyparquet that allow you to create and query Parquet files. Parquet is a column store file format that is just the right thing to pre-index some data so that it can be efficiently queried and stored. Column stores store data in ways that can be very space efficient if there is data that repeats the same value in the same column, essentially storing the same data only a single time. For example, the IEEE registry data and lineage data used in this project is 22.14 MiB, and that same data converted into Parquet is 5.88 MiB. A massive savings. High cardinality data will tend to compress less well, and low cardinality data will compress better. Generally it does not compress as well as a pure compression algorithm, but it still helps download speeds for the data. In addition to speed benefits, Parquet can be made to pre-sort one or more columns. This makes it efficient to search with methods like a binary search that require the data to be pre-sorted to avoid having to scan every single value.
In this project, hyparquet has both Parquet file creation and query libraries (that also support Snappy compression out of the box). Because of that, I can have an npm build step that builds the static assets for the site and also uses hyparquet-writer to convert the source IEEE MAC address registry data and MAC address lineage data into a Parquet file. I then host all of that on a static hosting service (Cloudflare Workers Assets in this case) that doesn’t have a per-request cost, so there is no cost to me on a per-request basis. The hyparquet parser engine and the Parquet data can all be loaded into the visitor’s browser, and the MAC address query runs locally in their browser. This also has the benefit of a server never processing the MAC address lookup, so if someone has concerns about data processing privacy, it happens on their computer.
Sharding data to improve performance
Even with the data stored in Parquet with Snappy compression (which gets it down to 3.12 MiB), it still takes quite a while to load in a browser. So by default, instead of loading the entire file, the registry is sharded by the first byte (two hex characters) of the MAC address. This splits the registry into up to 256 different files and reduces the amount of data that needs to be downloaded before a query can be completed. There are also hints in the shards if a MAC address has lineage data, so that we don’t have to download and query the lineage data if the MAC address doesn’t have lineage. If the search is more freeform, such as data about a vendor or other aspects, we can still download the full 3.12 MiB data set. This pattern has proved to be useful in other projects to speed up the user experience.
Automated data refresh
The MAC address registry is relatively static, with only a small percent of the data changing frequently, but there are still new prefixes almost every day. So I have a GitHub Action that runs daily to check the source data. If the source data has changed, it commits a change to the repo, which then triggers Cloudflare Workers Builds to rebuild the site.
Prerendered pages with SPA fallback
The IEEE registry currently has fewer than 100,000 prefixes, and the static asset hosting service I am using allows up to 100,000 static files without cost. So I have the project pre-build a page for each prefix. If you load the page with just a partial prefix like https://mac.jasontally.com/001B21, it will load that page instantly and then lazy load the rest of the application. If you attempt to load a URL that does not have a pre-rendered page, the application takes advantage of the Cloudflare Workers Assets SPA fallback feature to load the root page instead. That page then loads the path of the URL into the search box automatically and runs a search for you, in the most efficient way, in your own browser. There are also static pages generated for each vendor, region, country, year, recent changes, and a few others so that they can be discovered easily.
An MCP server
After building the site, I wanted to make it easier for AI agents and similar tools to access the information. I tried several explorations with purely static files that did not work out, because most agents would not load a URL that the requester hadn’t put into the chat box. Because of that, I came up with a way to run an MCP server against the data in a way that I think is somewhat unique. While it isn’t purely static, it still has the benefit that there isn’t a per-request cost. So you can point Claude or similar at https://mac.jasontally.com/mcp and ask it to tell you the country, vendor, or registry of a MAC address, and it will give you that and a link to more information at mac.jasontally.com.
In the future, I hope to talk more about the pattern I used to create this MCP server with no request cost and the mashup of a couple of unique Cloudflare capabilities that make it possible.
In addition to the unique aspects of how this app is built, it also has some capabilities that would be useful for users that I don’t see in other apps. For example, you can paste output from a CLI command, and it will extract any MAC addresses and perform lookups on them. If you look up a single MAC address, you will get that MAC address reformatted into all of the common notations. All of those notations can be used in the search box and are discovered in multiline output, so you can do multiple lookups at the same time. It also stores historical lookups in private browser storage so that you can refer to them quickly.
Internationalization (i18n)
I wanted people to be able to use the application in the language they are comfortable with, so I added internationalization (i18n) to the project. Translating the application into other languages is not something I could have done on my own, so this wouldn’t be possible without Gemini 3.1 Pro to do the translating for me.
Even with a model as capable as Gemini 3.1 Pro, I still want to use caution and verify the results. I am sure there are places where the wording is awkward or just wrong. If you read and write a language other than English, could you try out the application in your language and make sure it is usable? If something doesn’t read right, let me know so that I can fix it.
What other applications that you use commonly have annoyed you with cookie popups and advertisements that you think the world can do without?