Engineering

Teaching an AI a Language It Has Never Seen: Inside Axon MCP Server

Most language models have never read a line of Axon. Without grounding they either refuse to help or invent a function that does not exist. Here is the knowledge layer that closes the gap.

Alper Üzmezler· Sep 15, 2026 · 9 min read

Ask a general-purpose language model to write you an Axon function and you get one of two answers. The honest one is a polite refusal. The dangerous one is a confident block of code calling rollupByDay() — a function that has never existed in any version of SkySpark.

This is not a failure of intelligence. It is a failure of exposure. Axon is a domain-specific language for building analytics: small, strange, and beautiful, with a folio query model and a defcomp component system that look like nothing else in a training corpus. The model has read millions of lines of Python. It has read approximately none of yours.

Axon MCP Server exists to fix that, and it fixes it the boring way: not by fine-tuning a model, but by putting the real corpus one tool call away.

The shape of the problem

A hallucinated Axon function is worse than no answer at all. In Python, a made-up method raises an AttributeError in a second. In a building analytics platform, a plausible-looking rule can pass a syntax check, deploy to a live site, and quietly produce wrong energy numbers for a month before anyone notices the baseline drifted.

So the requirement was never "make the assistant sound fluent." It was: every suggestion has to come from something that actually exists, and the assistant should be able to prove it.

What gets indexed

Axon MCP Server indexes three things and exposes all of them over the Model Context Protocol:

  • SkySpark documentation — thousands of HTML pages crawled and chunked
  • Axon functions — from synced project folders and offline library exports
  • Operator usages — real call sites, not just signatures

The headline numbers from the current release: 4,000+ documentation pages indexed in 30 to 60 seconds, queries answered in under 50 milliseconds, and a 24-hour cache so subsequent boots are instant rather than re-crawling from cold.

Sources 4,000+ docs .axon funcs Tree-sitter statement boundaries Embed LanceDB + FlexSearch MCP < 50 ms per query Index once — 30 to 60 seconds 24h cache Comments are preserved as search signal, not stripped as noise

Why the parser matters more than the embedder

It is tempting to treat indexing as a solved problem: split the file every 500 tokens, embed the chunks, move on. That works acceptably for prose and badly for code.

Split an Axon function at a fixed character count and you routinely cut a do ... end block in half. The first chunk has a condition with no body. The second has a body with no condition. Both embed into vectors that mean roughly nothing, and both will happily come back as search results.

Axon MCP Server parses with a purpose-built tree-sitter grammar instead. That buys three concrete things:

  • Chunks land on statement boundaries. A retrieved chunk is a complete thought, so the assistant reading it sees valid code.
  • defcomp cells are surfaced as the component's interface. When someone asks what a component takes and returns, that question has a structured answer rather than a guess from surrounding text.
  • Comments are preserved as search signal. The sentence explaining why a rule exists is very often the best match for a natural-language question, and a naive parser throws it away as non-code.

The embedding model gets the credit for semantic search. The grammar is what makes the thing it embeds worth searching.

Grounded, not fluent

The difference this makes is not subtle.

Ungrounded rollupByDay(points) .normalizeBy(revenue) Syntactically plausible. Neither function exists. Fails at deploy — or worse, silently returns wrong numbers. Grounded hisRollup(hisRead(pt, span), sum) // indexed usage: 14 call sites Drawn from the real corpus Every suggestion traces to indexed code. Generated functions are pre-validated before they are ever handed back.

The right-hand column is the whole product. The assistant is not being clever; it is being accountable. It found something, it can point at where it came from, and the call graph it used to get there is bidirectional — you can ask who calls a function as easily as what it calls.

The stack, briefly

TypeScript throughout, speaking the Model Context Protocol. FlexSearch for keyword retrieval, LanceDB with HuggingFace Transformers embeddings for semantic retrieval, tree-sitter for structure, Prisma over SQLite for project and index-run metadata, and OAuth 2.1 on the web endpoint.

Running it needs Node.js 20 or newer. Everything else works offline; a live SkySpark instance is optional and only unlocks execution and live-query features.

Who this is actually for

  • SkySpark developers writing HVAC, energy and sparks logic who want a pair programmer that knows the platform rather than one that pattern-matches Python at it
  • Building automation integrators consolidating knowledge that is currently spread across a dozen project folders and one senior engineer's memory
  • AI-assisted developers who need accurate context and have learned to distrust confident syntax

That last group is the honest audience. The value here is not that the assistant becomes smarter. It is that it stops being confidently wrong about a language it was never taught.


Axon MCP Server is source-available at github.com/Project-SandStar/AxonMcpServer. The project page has the full tool surface and installation guide.