spasm-myelixlabs

spasm-myelixlabs

Hey everyone,

We’re a tiny dev team, and we wanted to share something we’ve been building and dogfooding internally for months: Synapse MCP. It’s an open-spec Model Context Protocol (MCP) server that sits between your local codebase and AI agents (Claude Code, Cursor, Windsurf, or custom agent scripts).

After using it every day on our own code, the efficiency gains have been huge. But saving context tokens was never our main goal—that’s just a byproduct. The real reason we built Synapse comes down to a simple philosophy: LLMs shouldn’t guess your code structure; they should make decisions based on compiler-grade facts.

The Core Problem: LLM Guesswork

Most AI agent workflows force the LLM into a game of probabilistic guessing. When you ask an agent to refactor a feature, it runs a few regex commands (grep/ripgrep) or pulls in fuzzy cloud vector embeddings, grabs matching text strings, and then guesses how the rest of the system connects.

In Elixir (and software engineering in general), guessing fails:

  1. Unqualified Imports & Aliases: If Module A explicitly calls Accounts.User.get_by_id(1), text search finds it. But if Module B uses import Accounts.User and calls get_by_id(1), regex search misses it completely. The LLM assumes Module A is the only callsite, refactors it, and silently breaks Module B.
  2. Polymorphic Dispatches & Behaviours: Text search can’t trace an Elixir @behaviour or dynamic module dispatch back to its underlying implementations. The agent just guesses where the contract is implemented.
  3. Test Fixture Noise: Grepping for a core function often dumps 200 lines of mock factories into the context window for every 1 line of production code. The model guesses based on test setup rather than production callers.

Ground Truth Over Probabilistic Search

Instead of treating your codebase like unstructured text, Synapse parses your code into a local AST graph using Sourceror (SynapseCore.Chunker.ElixirChunker and ElixirCompressor). It gives the LLM deterministic cross-references (xref) and concrete execution guarantees:

  • Exact Caller/Callee Trees: The LLM gets true callsites, alias resolutions, and module dependencies in sub-milliseconds—zero guessing required.
  • In-Memory Shadow Graph (dry_run: true): When using the synapse_modify_files tool with dry_run: true, Synapse routes to SynapseCore.ShadowGraph.simulate/2. It executes proposed edits against an in-memory AST diff, checking function arities across all indexed callers and running local linters (Credo). If an edit breaks a downstream caller’s signature, Synapse automatically rolls back before anything touches your filesystem.
  • Stack Trace Resolution (synapse_debug_trace): Agents can feed raw Erlang/Elixir stack frames directly into the synapse_debug_trace tool, which maps them straight back to exact AST chunk IDs in one turn.
  • Persistent Node Knowledge Caching: When an agent analyses a complex module, Synapse attaches that structural insight directly to the AST node in a local database. Future agent sessions read that node context instantly without re-discovering the module from scratch.

Why 100% Elixir? (No Python, No PyTorch)

The current AI ecosystem is bogged down with massive Python runtimes, C++ vector database binaries, and heavy math dependencies. We wanted to prove you can build zero-dependency, ultra-fast AI tooling purely on the BEAM.

Here is how we structured the OTP architecture under the hood:

  • 12 Microsecond Lookups via ETS: The entire graph lives in memory across 12 named ETS tables (:synapse_chunks, :synapse_edges, :synapse_symbols, etc.). Reads bypass GenServer message queues and hit public tables directly with read_concurrency: true, resolving graph queries in microsecond bursts.
  • Per-Repo Indexer + Singleton Stores: We split process responsibilities cleanly. A per-repo SynapseCore.Indexer GenServer manages Git deltas, file events, and concurrent indexing phases. However, final state mutations are strictly serialised through global singleton GenServers (SynapseCore.Store.ETS and SynapseCore.Store.SQLiteWriter). This guarantees lock-free state consistency without race conditions during concurrent agent edits.
  • Native OS File Watching & Mailbox Draining: SynapseCore.Indexer spawns an asynchronous watcher using Erlang’s file_system wrapper, hooking natively into OS file events (like macfsevents). We handle event debouncing via zero-latency mailbox drains in handle_info({:file_event, _watcher, {path, _events}}, state), updating the local ETS index in ~2ms.

BEAM War Story:

We initially tried storing our BM25F inverse document frequency (IDF) maps in :persistent_term to squeeze out maximum read speed. It worked great until we indexed a massive monorepo—the IDF map hit 100MB and hard-crashed the VM with literal_alloc: Cannot allocate N bytes of memory. :persistent_term uses the BEAM’s literal allocator, which isn’t built for dynamic high-volume maps. We migrated back to standard ETS tables with read_concurrency: true and got the exact same read performance with zero crash risk.

Hints at What We’re Building Next

Having dogfooded this for months, we are fully doubling down on the “100% Elixir AI” stack. No Python wrappers, no heavy math dependencies—just pure BEAM concurrency, OTP supervision, and raw performance. We’re currently building some much bigger Elixir-native AI infrastructure pieces that sit directly on top of this engine.

:purple_heart: Free Pro Access for Elixir Devs

We normally charge $19/mo for Synapse Pro (which unlocks the Shadow Graph safe writes, stack trace resolution, and persistent node memory). But because this community built the runtime that made Synapse possible, we’re giving Synapse Pro completely free for a year to all Elixir developers.

We’re a small team building out in the open, and we would love your raw feedback, architectural critiques, or feature requests!

Engineering Deep Dives from our Blog:

Links: synapse-mcp.dev

Give it a spin with your favourite LLM; you don’t need the latest and greatest. Synapse has your lower-level LLMs coding just as well as the latest models. Let us know what you think.

Showing Posts 1 to 10

spasm-myelixlabs

spasm-myelixlabs OP

Synapse MCP is 100% FREE. You do NOT need a Pro license or a credit card to install and run it and it will be free forever.

We think about the two tiers like this:

  • Core / Free Version: Designed for interactive co-pilot workflows. Gives your agent full AST visibility, microsecond ETS lookups, and exact dependency graphs so it stops hallucinating code structure while you retain human-in-the-loop oversight.

  • Pro Version ($19/mo): Designed for autonomous autopilot execution. Adds safety rails when you want an agent executing multi-file refactors in the background—simulating writes in an in-memory Shadow Graph (dry_run: true), executing local linters in memory before touching disk, resolving raw stack traces, and caching AST node memory across sessions.

We are giving Synapse Pro completely free for a year to anyone in the Elixir community.

If you want to test out the full Pro features on your codebase, email us at: hello at myelixlabs.com and we’ll send over your discount code right away!

jamesaspinwall

jamesaspinwall

I tried and decided to remove the app. I did a codex astra 6 reasoning high evaluation on my code base.

I recommend removing Synapse from your default coding workflow. It has useful capabilities, but this installation adds more verification and troubleshooting than demonstrated value over ElixirLS, source inspection, and Tidewave.

I ran 76 recorded MCP probes against your installed server and checked results against current source. Its index reported fully ready and matched the repository’s current commit.

The full evaluation (asset/docs/synapse-mcp-evaluation-2026-09-29.md) contains the methodology, reproducible examples, limitations, and decision criteria.

Test Result
Nine function lookups using bare or module-qualified names None returned the target function
Same functions using name/arity, scoped to a file 9/9 correct
Seven full-sentence semantic searches Expected implementation file found in 0/7
Short keyword versions Expected file found in 4/7
Hybrid context search Expected file found in 5/7
Six regex searches 6/6 matched direct source searches
Three source-reading tests 3/3 matched source
Function outlines Returned either just the module declaration or the entire file
Dedicated caller analysis, test mapping, repository overview Required Pro

For retrieval, “found” means the expected file appeared among the first five results—not necessarily that the question was answered.

Claude’s assessment needs one substantial correction: Synapse can find Elixir functions. carry_out/4 works; bare carry_out fails. Its index contains the functions, but ordinary query forms and ranking are unreliable.

Several problems go beyond that syntax limitation:

  • Incorrect routing: a question about checking terminal input was routed to server health and marked complete.
  • Broken recovery guidance: Synapse generated a regex retry containing an unmatched parenthesis; following its own suggestion failed.
  • Misleading caller metadata: free context retrieval listed carry_out/4 as its own caller, although it is not recursive.
  • Unpredictable output: an outline request returned the whole 1,217-line file; another search returned 56 results despite a limit of ten.
  • Restrictive instructions: its installed skill attempts to prohibit independent source-search fallbacks. That is particularly unsuitable for your verification-focused reviews.

ElixirLS also showed limitations, including stale locations and one lookup needing an explicit position. It should still be checked against source. However, it returned the three real carry_out/4 call sites without a paid upgrade.

Paying for Pro is not justified by these results. It currently costs $19/month, but its paid graph traversal and write-safety features remain untested here. The vendor also advertises a free year of Pro for Elixir developers, which changes the cost of an optional experiment—not the observed reliability problems. Official pricing, vendor’s Elixir offer.

My recommended decision is:

  1. Disconnect Synapse from routine agent sessions and remove its mandatory-use instructions.
  2. Keep using ElixirLS, direct source checks, and Tidewave.
  3. Revisit Synapse only for a specific unmet need, with independently checked caller graphs and measured improvements on real tasks.
jamesaspinwall

jamesaspinwall

Synapse MCP on a real Elixir codebase: what worked, what didn’t, and one security concern

I tried Synapse MCP (desktop app 4.2.0, server build a96bac96, free tier, macOS) as a code-intelligence server for Claude Code and Codex on our Elixir gateway: about 1,300 files and 15,000 indexed chunks. Two independent passes, 26 of my own queries and 76 probes run by Codex, each checked against the source and ElixirLS. This is one repository and a targeted sample, not a general benchmark.

What worked well

  • Indexing and speed. Indexing was complete, with the indexed HEAD matching the checkout, and every answer came in under 1.5 s.
  • Local operation. Embeddings are computed locally. During our checks the only outside contact was the licence server, and the app is signed and notarized.
  • Regex search and file reads: correct in every case we tried (6 of 6, and 3 of 3).
  • Exact function lookup works, if you ask the right way. Queried as name/arity, with a file path and fuzzy: false, it found 9 of 9 functions. My first pass got 0 of 14 with bare names (carry_out) or qualified ones (AgentTasks.Config.load/1); that was my query form, not a missing index. The accepted forms should be documented, or bare names accepted.

What didn’t

  • Search by meaning was weak on our questions. Full-sentence queries put the right file in the top five in 0 of 7 cases in one pass, and 1 of 12 at the default cutoff in the other (6 of 12 with the cutoff lowered). Short keyword queries did better: 4 of 7. Hybrid find managed 5 of 7, sometimes below unrelated results.
  • The default router misroutes. ask_synapse sent a plain code question (“how does the executor check the terminal input is empty”) to the indexer health check, and marked it complete.
  • A generated retry crashes. A question containing a parenthesis produced a suggested regex retry that failed with “unmatched closing parenthesis”.
  • Outlines and limits are unreliable. An outline returned either only the module line or the whole 1,200-line file. A symbol search with limit: 10 returned 56 results.
  • Caller metadata is noisy. The callers listed for a private function were right (all three) but also included the module and the function itself, which never calls itself. Full caller and callee traversal, change review and test mapping are Pro features, so we didn’t test them.
  • “Tokens saved” is claimed even on empty results (500 per miss). Treat those counters as estimates.
  • The instructions to agents are too strong. They tell agents never to use grep or read files, only Synapse. Given the results above, that would make source-grounded code reviews worse. It should be optional guidance.

A security concern

I found a problem with how the local HTTP server can be reached, and reported it privately to the developer. Until it is addressed, I’d suggest not leaving the HTTP server running while you browse the web.

Where we landed

Its exact lookup, regex and file reads mostly duplicate what ElixirLS and plain source reading already give us. The parts that would add value (natural-language discovery, graph analysis) were weak or behind the paywall on this codebase, so we removed it for now. I’d happily retest once:

  • bare function names are accepted;
  • routing and outlines are fixed;
  • the security issue is resolved.

The Elixir-native, local-first approach is appealing, and the developer’s offer of a free Pro year to Elixir developers makes a retest easy.

spasm-myelixlabs

spasm-myelixlabs OP

@jamesaspinwall Thanks for the review — it’s genuinely useful, even where I can’t immediately reproduce the specific issues. To help with that, could you share more detail on the exact queries/steps that produced the problems you saw - possible to do it on a public repo?. It also looks like you let the LLM dictate the ‘tests’, and LLMs do have a habit of confidently making things up and not following instructions.

I take all feedback, though, because it is the only way we can genuinely improve a product we have spent 100s of hours building to make our lives better. I don’t make up the claims; I have tested them quite extensively. I also use the product daily, so I’m a little biased.

The ask_synapse method and what it actually does:

1. Route classification (Router)

It takes a free-form query string and runs it through a deterministic pipeline:

  • Lexical matching against a capability graph (stop-word stripped, entity extracted)
  • Regex extraction of qualified module/function names directly from prose (e.g. Parser.parse/2 in the query → auto-fills symbol input without a separate lookup)
  • Optional vector similarity as a tiebreaker
  • Returns one of four decisions: :execute, :missing_inputs, :clarify, or :no_safe_route

2. Input completeness gating (Planner)

Before telling the agent to go ahead, it checks whether all required inputs for the resolved tool are present. If not, it returns completion_state: "clarification_required" with a description of what’s missing — rather than letting the downstream tool fail with an opaque error.

3. Structured next_tool_calls

Every response tells the agent exactly what to call next — not just the answer, but the continuation. This is what makes it the policy layer: agents follow the returned plan rather than deciding themselves which granular tool to reach for.

It does more around safety, but no need to go into this.

What it is not

It’s not an LLM call. It’s not a fuzzy-search wrapper. It’s a bounded, deterministic router with confidence scores and margin tracking — designed to be fast, inspectable, and testable without any AI inference happening inside it.

What we find, and it happened today in our stand up in a show and tell with Claude Code, is that I watched Claude Code make up a bunch of nonsense about Synapse. I asked the LLM whether it had read the capability manifest for Synapse. It said it hadn’t, then backtracked. Re-ran the tests to find it worked. This is actually something we battle with. Hence the need for skills and rules in coding agents.

The point and reasoning of ask_synapse is to explain Synapse to the LLM via responses if it didn’t bother to check the MCP specification for tool calls or the capability manifest.

This has genuinely been a challenge. We write skills and rules, and depending on the tools that you use, they entirely determine the experience you have with Synapse.

I can categorically say to you that if you ask your agent to “read the capability manifest of Synapse before it starts its analysis”, you will get quite a different result.

Is this an excuse - no - but it is a real problem we have, and I am sure any MCP tool provider has the same issue. It’s one of the reasons we are building Myelix Agents, which, as of this evening, is starting to show some real promise, and I would love for you to use and abuse that tool too, because it truly is unique toolkit and is entirely written in Elixir/Pheonix, and it solves problems I have daily.

With that said I do want to get to the bottom of your security issue if you email hello at myelixlabs.com with the details, we will fix it. I would also urge you to test out the Pro version; it genuinely is very useful, and like I said, it’s free for a year. I’ll send you the code when you send me your security findings.

I am keen to reproduce your issues, and if there’s anything to fix, we will fix it.

Thanks in advance.

Please also note that in our experience with Synapse, you really don’t need to use the latest and highest reasoning on a model to get accurate answers. It’s not the reasoning level or the sophistication. It’s the quality of the context that improves the coding decisions made.

One final note on the instructions. LLMs are trained to use grep, sed and read_files. They will always use those tools. The instructions say to use synapse first before defaulting back to grep, et al.

jamesaspinwall

jamesaspinwall

Thanks for the detailed reply, and for taking the feedback in good spirit. Some of your points don’t match what your server and skill actually returned, so here is the evidence.

“The LLM dictated the tests.” An agent wrote the queries, but the results aren’t its opinions. They are the raw JSON-RPC responses from your server, logged and checked against the source and ElixirLS. The expected files were recorded before any query ran. Where an LLM did over-claim (Claude’s first pass on bare function names), I caught it and corrected it in the post myself.

The router. I accept that it’s deterministic, which is why this result matters. Asked “How does the agent task executor check that the terminal input box is empty before typing?”, ask_synapse returned:

"confidence": 0.3476,
"intent": {"tool": "synapse_indexer_control", "action": "health"},
"completion_state": "complete",
"agent_instruction": "Answer from the completed result."

json

Copy

At 0.35 confidence it returned neither :clarify nor :no_safe_route. It ran a health check and told the agent to answer the code question from that. It was deterministic, but it was wrong, and it said it was complete.

Reading the capability manifest. Fair point: we didn’t call it. But these results came from direct calls to your server with no agent involved, so reading the manifest wouldn’t change them:

  • The semantic query “Where is the commit outcome checked (e.g. :unknown)?” suggested the regex retry :unknown)?, which failed with -32603, “unmatched closing parenthesis”.
  • A symbol search with limit: 10 returned 56 results.
  • Empty results reported tokens_saved: 500.
  • read_files with format: "outline" returned only the module line. Following your server’s own guidance (“Pass max_tokens: 16000 for more detail”) returned the whole 1,217-line file, 54 KB of JSON.

Also, the default entry point exists, as you say, to explain Synapse to an agent that didn’t read the manifest. So it shouldn’t depend on the agent having read it.

The instructions. You say they tell the agent to use Synapse first and then fall back to grep. The installed skill says something else: “shell is NEVER permitted”, and shell tools “are strictly prohibited unless ask_synapse explicitly reports zero safe routes and the diagnostic ladder is exhausted”, which is a six-step ladder. That amounts to exclusive use. It is also what makes a misroute expensive, because the agent is told to keep working through Synapse after Synapse has failed.

Model level. I didn’t raise it, and nothing in the review depends on it.

Reproduction. I don’t have time to evaluate on a public repo. My interest is narrow: a faster, more reliable development cycle on my own code. Most of the items above don’t depend on my codebase, so the same requests should reproduce on any Elixir project.

Value. At $19 a month, $228 a year, I expected the free tier to wow me into upgrading. Instead, the parts that worked (exact lookup, regex, file reads) duplicate what ElixirLS and plain source reading already give me. The parts that would justify the price (natural-language discovery and routing) were the weakest.

I’d be glad to look again once bare function names work, the router respects its own confidence, outlines return signatures, and the skill makes Synapse optional rather than exclusive.

spasm-myelixlabs

spasm-myelixlabs OP

This is detailed feedback, and thanks for taking the time. It’s specific enough to reproduce. Thanks for the detailed write-up — this is exactly the kind of report that’s useful.

I’ve been able to reproduce some of the issues directly against the source: the router’s no_safe_route threshold is genuinely too permissive, and the suggested_retry regex is built from raw query tokens without escaping. I’m looking into the other items. I’m writing tests to lock down each item. Will follow up tomorrow, as it’s getting late for me.

nathanl

nathanl

This whole thread smells like robots

spasm-myelixlabs

spasm-myelixlabs OP

well not from me… im busy fixing some of the items raised - which are genuine. I think ive made the router a lot better. Testing it. Took a lot longer to fix than i anticipated

spasm-myelixlabs

spasm-myelixlabs OP

@jamesaspinwall the reproducible examples and the distinction between your own query-form issues and genuine bugs made it genuinely useful, thanks for that. I dont agree about your LLM giving advice to the forum but thats my opinion.

So I have been busy over the last 48 hours.

Here is what we updated:

The router. The misrouting you hit — a plain code question going to the health check and being marked complete — is fixed.

When the router isn’t confident enough to commit to an action it now asks for clarification rather than guessing.

The fix went deeper than a single rule: the confidence predicates were rewritten to use generalised vocabulary families rather than exact phrases, so routing holds across natural paraphrases of the same intent, not just the forms the corpus was written in.

We stress-tested it with 100 test groups covering capability questions, graph traversal, repo management, change review, search, and adversarial edge cases — 9.58/10 across 1,000 individual assertions. We also tested it across multiple codebases: synapse-mcp itself, an Elixir other elixir (56k chunks), python project (83k chucks), and the Linux kernel at 273k chunks — different languages, sizes, and indexing states. The stress suite is now part of the repo so regressions are caught automatically.

The broken regex suggestion and outline returning the whole file — both fixed.

The limit: 10 returning 56 results — fixed.

The tokens_saved: 500 on empty results — fixed.
It now returns 0 rather than claiming a saving that didn’t happen.

The skill instructions. “Shell is NEVER permitted” is gone — shell tools are now an explicit fallback once the diagnostic ladder is exhausted. You were right that the old wording made a misroute expensive. Fixed.

The CORS issue. Unlikely, but a malicious script, if it knew about Synapse running locally, could have gained access to code snippets. We’ve restricted the origin header to loopback addresses only, so a page on an arbitrary domain gets a narrow fallback rather than a free pass to read parts of what’s in Synapse. Fixed.

Bare function names — as you noted yourself, this was an LLM query issue, not a missing index. The functions were there; the agent was asking the wrong way. We’ve improved the documentation and the recovery ladder to guide agents towards the right query form when they hit this.

We’re early, and feedback like this catches the gap between what we intended and what shipped. The whole point of this tool is that LLM agents currently guess their way through codebases — reading wrong files, grepping blindly, burning tokens on context they never needed. Getting that wrong ourselves undermines the argument, so the bugs you found mattered.

The broader goal is a serious code-intelligence layer built in a language actually suited to the problem — 100% Elixir, no Python glue, no Node dependencies, running entirely locally. Whether that resonates or not, it’s what we’re building towards.

I hope, genuinely, that this is useful to any developer, it is useful for us, its why we built in the first place. Give it a spin; it does make a difference to what comes out of the sausage machine. Try it yourself and see. It is FREE to use, and you get most of the functionality.

James, or anyone reading, if you email me (hello at myelixlabs.com), I can send you the Pro version discount code.

Thank you as always team.

v4.4.0 should have all the new code, in - current mcp servers will auto-update and you can download here

jamesaspinwall

jamesaspinwall

What is the point of having robots if you don’t let them do your work? :zany_face:

Where Next? Top

Trending in AI / LLMs Top

KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
OndrejValenta
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly) AI dream has many faces, but general...
New
preciz
I like to find performance optimizations and hidden bugs in Elixir codebases with coding agents. If I just ask them directly to find tho...
New
spasm-myelixlabs
Hey everyone, We’re a tiny dev team, and we wanted to share something we’ve been building and dogfooding internally for months: Synapse ...
New
caleb-bb
So I’ve got this RAG project called Cake that I’ve been working on a good long while. For this topic, the RAG part is less important than...
New
AstonJ
AI tools and services seem to be the new JS framework - with new ones popping up every 5 minutes - hence it might be worth posting one of...
New
nathanl
Anthropic: Launching an opt-in vulnerability-finding service for open-source software We’re launching OSS Scanner, an opt-in vulnerabil...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews