/ SEO · site building
SEO for a Tiny Technical Site Is Mostly Making Things Worth Finding
For a small technical site, the useful SEO work was giving projects permanent, understandable pages with technical ideas worth finding and citing.
TL;DR
For a small technical site, the most useful SEO work I did was not squeezing more keywords into existing pages.
It was giving individual projects permanent pages, making those pages understandable without requiring a trip to GitHub, and making sure each page contributed at least one useful technical idea of its own.
The metadata, sitemap, structured data, Search Console, and machine-readable summaries still matter.
But none of them can make a page worth citing.
The page has to do that itself.
I recently spent way too much time thinking about SEO for a site that, realistically, does not have much traffic yet.
Ahlyx Labs is a small personal technical site. It has some open-source tools, security research, notes, and a few hosted utilities. There is no content team, no marketing department, and no giant backlog of keyword-targeted articles.
That made a lot of normal SEO advice feel a little backwards.
I could keep tweaking title tags forever, but eventually I had to ask a more basic question:
If somebody did find the site, is there actually anything here worth finding?
That ended up changing how I thought about the whole project.
The site had projects, but not really project pages
Originally, most of the work on Ahlyx Labs existed in two places:
- a card on the homepage
- a GitHub repository
That is fine if someone already knows what they are looking for.
It is much worse if someone arrives from a search result and has no context.
A GitHub README is usually written for someone who is already interested enough to open the repository. It might mix installation instructions, development commands, implementation details, release notes, known limitations, and project status.
A homepage card has the opposite problem.
It might have two sentences.
There was nothing in between.
So I added a /lab directory and standalone pages for seven projects:
/lab/auditmcp /lab/conveyance /lab/security-enrichment /lab/baptisia /lab/pcap-agent /lab/network-scanner /lab/hardware-dashboard
The goal was not to copy the READMEs onto the website.
I wanted each page to answer the questions I would have if I found the project without knowing me:
- What is this?
- Why does it exist?
- What is interesting about the design?
- How does it work?
- What actually works today?
- What does it deliberately not do?
- Where are the trust boundaries?
- Where do I go if I want the source?
That sounds obvious in hindsight.
My first attempt was still weird.
My first version sounded like somebody auditing my own projects
I wanted the project pages to stay accurate, so I built them from the maintained repositories and pinned technical references to specific commits.
That part was good.
The writing was not.
A lot of it sounded like this:
The maintained README reports...
The reviewed source describes...
The source documents...
It was technically cautious, but it sounded like some third party had inspected my project and written a compliance summary.
That was not the voice I wanted for the site.
I was not trying to hide where the information came from. I just realized that provenance belongs in the references, not in every sentence of the article.
The better version says something normally:
AuditMCP is a local MCP audit logging proxy...
and then links the exact source revision at the bottom.
Same evidence.
Much more natural page.
That was probably the biggest editorial improvement in the process.
A project page needs a reason to exist separately from the README
Once the writing sounded better, I ran into another problem.
The pages were accurate, but some of them were still basically nice summaries.
That is not necessarily bad.
It is just not especially linkable.
If another writer is discussing MCP auditing, why would they cite my page instead of the repository?
If someone is writing about industrial-control languages, what does my Baptisia page contribute beyond saying that the project exists?
The answer turned out to be simple:
Each page needed one useful idea of its own.
Not a made-up SEO hook.
Not a paragraph written because some keyword tool said I needed one.
An actual technical idea already present in the project that was worth explaining properly.
For AuditMCP, that became the distinction between an audit recorder and a policy gateway.
AuditMCP intentionally fails open if logging fails after startup.
That sounds strange until the role is clear.
If the component exists to observe and record activity, making the logger an availability dependency changes the system it is supposed to observe. A policy gateway might make the opposite choice because blocking is part of its job.
That distinction is more useful than another feature list.
For Conveyance, the useful idea was request-bound approval.
The project explores keeping an agent's credentials on a separate phone. The PC requests an action, the phone holds the credential, a person approves the exact request, the phone executes it, and the PC gets the result instead of the secret.
The important part is that the approval has to be bound to the payload.
Otherwise, a compromised PC could theoretically show the user one request and execute another after approval.
For Security Enrichment, the useful explanation became:
No result is not the same thing as a clean result.
A provider can time out.
A source can have no record.
One provider can flag something while another has no data.
Those are different states, so the page explains them as different states instead of flattening everything into "safe" or "malicious."
For Baptisia, the important distinction was what a compiler can enforce versus what it absolutely cannot.
A compiler can enforce structural properties such as making sure certain safety checks occur before normal control logic.
It cannot prove that a physical sensor works, that a threshold is correct, that wiring is safe, or that an industrial process is certified.
That is a much better reason for the page to exist than another installation guide.
The same idea carried over to the smaller projects.
PCAP Agent explains the boundary between local packet capture and browser-visible metadata.
Network Scanner explains why an open OT/ICS-associated port is a clue, not protocol identification or vulnerability proof.
Hardware Dashboard explains that the CPU and RAM values on the screen come from my backend host, not the visitor's computer.
That project is older and simpler, so I deliberately did not turn it into a giant essay.
Not every page needs to be the same length.
It just needs a reason to exist.
Static HTML was the easy default
Another thing I wanted was for the important content to exist directly in the page.
The site already uses mostly static HTML, so I kept going in that direction.
The project explanations are not fetched afterward from an API. They are not empty containers waiting for JavaScript to populate them.
The headings, paragraphs, tables, references, and code examples are already in the document.
That is good for accessibility and reliability, but I also like the simplicity of it for anything trying to understand the page.
There are fewer moving parts between requesting a URL and getting the explanation.
JavaScript still exists where it makes sense.
The hosted tools obviously need it.
Analytics need it.
A back button can use it.
But the explanation of what AuditMCP does does not need JavaScript to exist.
That felt like the right default.
The boring SEO work still matters
None of this means the basic SEO pieces are useless.
I still made sure the site had:
- descriptive page titles
- real meta descriptions
- one clear H1 per page
- canonical URLs
- clean
/lab/...paths - internal links
- a sitemap
robots.txt- redirects from old
/projects/...paths - Open Graph metadata
- structured data
- a Notes RSS feed
The Lab pages now have stable URLs such as:
https://ahlyxlabs.com/lab/auditmcp https://ahlyxlabs.com/lab/conveyance https://ahlyxlabs.com/lab/security-enrichment
instead of making every project live behind a homepage anchor.
That gives each explanation an address somebody can search for, link to, cite, or send directly.
I also changed the /lab page itself.
Its original H1 was:
Work with context.
I still like the phrase.
It just tells a search engine almost nothing.
It is now:
Security & software lab projects.
Less clever.
Much more useful.
Machine-readable metadata can lie while the page looks completely fine
I added structured data too.
The homepage has entities for:
Person Organization WebSite
The Lab directory uses:
CollectionPage
and individual project pages use:
WebPage SoftwareSourceCode
That gives machines a little more explicit context about what Ahlyx Labs is, what a page represents, and where the corresponding source lives.
The interesting problem was not adding the JSON-LD.
It was keeping it synchronized.
After I improved the visible page titles, some of the old WebPage.name values were still using the previous names.
Baptisia even ended up with an empty SoftwareSourceCode.description.
The browser looked fine.
The structured representation was stale.
That was a useful reminder:
Machine-readable metadata is still content.
It can drift just like visible copy can.
If the page changes, the machine-readable version needs to change too.
I added llms.txt, but I do not think it is magic
I also added:
https://ahlyxlabs.com/llms.txt
It contains a compact summary of the site, identity, project URLs, tools, API information, and some important limitations.
For example, it explicitly says that AuditMCP records activity rather than enforcing authorization and that PCAP Agent does not relay raw packet payloads.
I like having it.
It is a convenient machine-readable index for systems that choose to look at it.
I do not know whether it will ever materially affect discovery.
That distinction matters.
There is a lot of discussion around "agent SEO," "GEO," and whatever acronym comes next. I am interested in it, but I do not want to pretend an llms.txt file is a secret ranking switch.
My current approach is much less exciting:
Make the normal website easy to understand first.
Then add machine-friendly summaries where they are cheap and honest.
The repository, the browser, and the search index were three different realities
One of the more useful things I learned was that I was constantly looking at three different versions of the site.
There was the repository.
There was the deployed site.
And there was the version search engines currently knew about.
Those were not always the same.
At one point, public search results were still showing an older version of Ahlyx Labs even though the new Lab pages had already been deployed.
That is obvious if you think about how crawling works.
It is also extremely easy to forget while actively changing a site.
A deployment being live does not mean a search engine has seen it.
A search engine knowing a URL exists does not mean it has the newest version.
And the source code being correct does not guarantee the rendered page actually looks correct.
I ended up checking all three.
I think that model is more useful than treating "the website" as one thing.
Source review and browser review catch different classes of mistakes
I had one model reviewing the repository and another actually inspecting the deployed preview in a browser.
That sounds a little excessive for a tiny personal site.
They caught completely different problems.
Source review was good at finding things like stale canonical URLs, inconsistent JSON-LD, missing descriptions, outdated /projects links, sitemap mismatches, and wording that no longer agreed with the implementation.
Browser review found different problems:
- About and Contact headings that were slightly misaligned
- paired project/tool actions that did not share a baseline
- a Lab directory with too much empty space
- code examples that technically existed but looked terrible at the available width
The funniest example was Baptisia.
I added a real .ba source fragment to make the page more useful.
The HTML accidentally contained literal:
\n
characters instead of actual newlines.
A source check could tell me the text was there.
The browser made it immediately obvious that it looked awful.
Security Enrichment had a similar problem for a different reason. The curl command was simply too long for the available width.
The right fix was not changing every <pre> block on the site.
I reformatted that command normally:
curl 'https://api.ahlyxlabs.com/api/v1/url' \
-H 'Content-Type: application/json' \
--data '{"url":"https://example.com","submit_urlscan":false}'
and added an opt-in wrapping style only for code blocks that actually needed it.
That is not really an SEO lesson.
It is just a good reminder that eventually somebody has to look at the thing.
Apparently that somebody can now also be an AI with a browser.
Automated audits are useful when they find contradictions
Another lesson was learning not to obey every warning an SEO tool produced.
One audit complained that labels in the "On this page" navigation did not exactly match the H2 headings.
For example:
Limits
linked to:
Trust boundaries and limits
That is fine.
A table of contents can use shorter labels.
Another warning complained that the project pages shared the same social-card image.
Unique images might be nice eventually.
They were not something I was going to block the project over.
There were also suggestions to add benchmarks such as packet throughput or BLE latency.
Those would be useful if I had actually measured them under a documented setup.
Adding numbers because numbers look authoritative would be worse than leaving them out.
The audits became much more valuable when they caught contradictions.
The homepage originally described Baptisia as:
A safety-enforcing DSL for ICS/OT systems
while the project page carefully explained that a compiler cannot make a real industrial system safe.
That deserved fixing.
PCAP Agent originally said:
real-time browser analysis
which was vague enough to sound like the browser itself might be capturing packets.
The newer description is:
Local packet capture with real-time browser-based network metadata analysis.
That is more precise.
I came away caring less about whether an audit was happy and more about whether the site agreed with itself.
Consistency mattered more than chasing a score.
Search Console was less dramatic than I expected
Once the pages were deployed, I submitted the sitemap in Google Search Console.
At that point, it discovered all 19 URLs in the sitemap.
That was reassuring.
It did not mean all 19 pages suddenly appeared in search.
For the pages I cared about most, I used URL Inspection and the live URL test.
That helped separate the version Google had previously crawled from what was actually deployed now.
Then I requested indexing for the important pages.
I did not keep submitting the same URL over and over.
At that point the pages were crawlable, internally linked, and present in the sitemap.
There was not much else to force.
The rest mostly requires time.
Questions I kept asking while doing this
Why make a project page if the repository already has a README?
A README is for someone already interested enough to open the repository. A project page is for a reader arriving without context, and it needs to contribute a useful idea of its own instead of being a nicer summary.
Does static HTML automatically rank better?
No. I like important content existing directly in the document because it reduces dependencies and makes the page straightforward to access and understand. That is a simpler default, not a ranking claim.
Is llms.txt actually useful for discovery?
It is a convenient, inexpensive machine-readable index for systems that choose to use it. I do not know whether it will materially affect discovery, and I do not treat it like a ranking switch.
How do I know when to stop doing SEO work?
Once the basic technical pieces are correct, another useful project, note, research writeup, or explanation is probably more valuable than endlessly adjusting metadata.
Why can the repository, deployed site, and search result disagree?
They are separate states: source code, the rendered deployment, and what a crawler has seen and indexed. A live deployment does not mean a search engine has seen its newest version.
There is a point where SEO turns into avoiding the real work
I now have:
- crawlable pages
- useful titles
- canonical URLs
- internal linking
- structured data
- a current sitemap
- Search Console
- project explanations
- source references
- a machine-readable site summary
- notes and research with permanent URLs
I can probably find another 30 metadata tweaks if I look hard enough.
I do not think that is what the site needs.
It needs more things worth finding.
A new tool gives me a project page.
A weird infrastructure problem gives me a note.
A security finding gives me a research writeup.
An interesting engineering tradeoff gives me something somebody else might actually cite.
Those pages can then link to each other naturally because the work actually relates.
That seems like a much healthier long-term strategy than manufacturing articles around keywords I do not care about.
I still want search traffic.
I would like Ahlyx Labs to appear when somebody searches for something I have actually worked on.
But the question I care about more now is:
If this page appeared in a search result, would clicking it be worth the reader's time?
For AuditMCP, I want the answer to come from the explanation of why an audit logger might intentionally fail open.
For Conveyance, from the explanation of why moving credential possession to another device changes the trust boundary.
For Baptisia, from separating compiler-enforced structure from real-world industrial safety.
For the email note, from actually going through the mess of getting SPF, DKIM, DMARC, Cloudflare Email Routing, SMTP2GO, Gmail, and Thunderbird to cooperate.
Those are real things I learned while building.
Search engines and agents discovering them would be great.
But first there has to be something there worth discovering.