Running an MCP Server Without Keeping the Desktop App Open

2026-08-29·9 min read
Quick Answer: Your MCP client launches the connector itself. In the Claude Desktop config you give the path to the LocalSynapse executable with the argument mcp, and Claude Desktop starts that as its own process over stdio when it starts, and ends it when it exits. You never open the desktop window, and closing the window does not affect the agent. This was not always true — before 2.18.0 the connector was a child of the app window, so keeping an agent working meant leaving a full desktop app resident, which on our own machine sat at roughly 1.9 GB doing nothing.

If you have wired a local search tool into an AI client, you may have hit this: the agent works, but only while a desktop window sits open in the background. Close the window and the agent loses its memory. Leave it open and you are donating a couple of gigabytes of RAM to a window you are not looking at.

That was true of LocalSynapse until 2.18.0. This post is about why it happens, what changed, and how to verify the arrangement on your own machine.

Why the connector ends up trapped inside the app

MCP servers usually communicate over stdio — standard input and output. The client launches the server as a child process and they talk through that pipe. No network port, no daemon, no listener to secure. It is a good design: the lifetime of the server is exactly the lifetime of the conversation that needs it.

The trap appears when a product has both a desktop UI and an MCP server, and the easiest way to start the server is from inside the already-running application. That works immediately, and it quietly inherits one property nobody chose: the connector is now a child of the window. Close the window, the child dies, the agent goes blind.

Users then discover the workaround before the developer does — leave the app running, minimised, forever. And that is where the cost lands. On our own machine, an idle desktop instance that had loaded the semantic model sat at roughly 1.9 GB of working set with nothing to do. On a laptop that is not just memory; it is a process that keeps waking the disk and drawing power for a window nobody has looked at since morning.

What changed

From 2.18.0 the connector is launched by your MCP client, not by the app. The client reads its config, starts the LocalSynapse executable with the mcp argument as a process of its own, and speaks stdio to it. The desktop window is no longer part of the chain.

Concretely, the process model went from this:

Claude Desktop
  └─ (nothing — unless you remember to open the app)

LocalSynapse.exe            ← desktop window, must stay open
  └─ connector               ← dies when the window closes

to this:

Claude Desktop
  └─ LocalSynapse.exe mcp    ← started by Claude, its own process
                                exits when Claude exits

LocalSynapse.exe            ← optional. Open it if you want the UI.
                                Closing it changes nothing for Claude.

The configuration

On Windows, in %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "localsynapse": {
      "command": "C:\\Program Files\\LocalSynapse\\LocalSynapse.exe",
      "args": ["mcp"]
    }
  }
}

On macOS, in ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "localsynapse": {
      "command": "/Applications/LocalSynapse.app/Contents/MacOS/LocalSynapse",
      "args": ["mcp"]
    }
  }
}

Two details are worth stating because they are the usual causes of a config that looks right and does nothing. The backslashes in the Windows path are doubled, because JSON treats a single backslash as an escape character. And Claude Desktop reads this file at startup only — quit it completely, from the tray as well, and reopen it. A window close is not a quit.

Verifying it, rather than hoping

Three checks, in increasing order of usefulness.

The process list. With your client open and the desktop window closed, you should still see a LocalSynapse process, and its parent should be the client. That single observation is the whole claim of this post.

The tool list. Ask the agent what tools it has available. LocalSynapse currently exposes nine, and if the agent can name them the handshake completed.

An actual search. The definitive check, because it exercises the index and not just the connection. Ask something that requires reading your files, then ask which tool was called and what it returned. This last step matters more than it sounds — an agent that cannot find your files will often answer anyway, from general knowledge, in a tone indistinguishable from having looked.

What a response actually contains

Since 2.19.0 a search result is not a list of file teasers. It is a set of documents with passages under them, plus a statement of how the query was interpreted. Trimmed to its shape:

{
  "query": "contract review comments",
  "purpose": "answer",
  "documents": [
    {
      "fileId": "…",
      "path": "…/2026/agreements/supply-draft-v8.docx",
      "displayName": null,
      "modifiedAt": "2026-07-28",
      "rankingScore": 0.1101,
      "passages": [
        { "at": "chunk 0 chars 0-600", "text": "…" },
        { "at": "chunk 3 chars 0-600", "text": "…" }
      ],
      "noPassageReason": null
    }
  ],
  "request": {
    "asked": "contract review comments",
    "readAs": {
      "terms": { "used": ["contract", "review", "comments"], "dropped": [] },
      "matchExpression": "…",
      "scope": { "kind": "all", "time": "all", "location": "all" },
      "unit": { "purpose": "answer", "purposeDeclared": true }
    },
    "notConstrained": [
      { "axis": "kind", "options": [
          { "value": "document", "count": 11 },
          { "value": "email", "count": 9 } ],
        "howToConstrain": "…" }
    ],
    "conflict": null
  },
  "basis": {
    "mode": "Smart",
    "documentsFound": 20,
    "documentsReturned": 20,
    "ranking": { "howToRead": "…" }
  }
}

The parts worth pointing at:

Two clients at once

A reasonable worry with a per-client process is what happens when you run two. Claude Desktop in one window, another agent elsewhere, both pointed at the same index.

Search is unaffected: each client gets its own connector process and full search including semantic results. Indexing is not duplicated. Exactly one process maintains the index at a time, elected among whichever processes are running, with the desktop app taking that role when it is open. So the second client is a reader, not a second indexer, and your files are never processed twice.

The cost to be aware of is memory: the semantic model is loaded per process that needs it, so two connectors doing semantic search will hold it twice. That is also why the model is released as soon as there is nothing left to index rather than held indefinitely.

If you are on an older build

If closing the app window still cuts off your agent, you are on something older than 2.18.0 and updating is the fix. It is worth checking rather than assuming, because the failure is quiet: the agent does not announce that it lost a tool. It simply starts answering from general knowledge, which reads exactly like an answer until you check it against your files.

Try LocalSynapse Free

Search inside files, 100% offline, free

Go to Home

Related Posts