MCP Server Setup: Why a Running Server Proves Nothing

A running MCP server only proves the launch worked. How to write the launch entry, why a wrong database path still lists every tool, and the test that catches i

$$&&#{}$$::MCP SERVER SETUPAuricIDE · Blog

The failure that looks exactly like success

You start the server by hand. It answers. You add it to your agent client and restart. The tool list comes back complete, every tool where you expected it, which is the moment you stop suspecting the setup and start trusting it. So you ask about a ticket that is open on your screen right now.

Nothing. No error. No empty-list warning, just a polite answer about having no such record, which sounds credible enough to send you looking somewhere else.

That gap is the setup. The server is fine. The registration worked. What went wrong sits between them, in a launch entry nobody reads out loud. This article is about connecting a server that already works. Building one is a separate job.

Why does a running server prove so little?

Because the client never touched the one you started.

A stdio MCP server has no listening socket to connect to. It talks over stdin and stdout, and those pipes only ever go to the one process that spawned it -- there is no equivalent of dialing an address after the fact. The client itself launches it as a child process, using the command written into its configuration, which is how it gets those pipes in the first place. Your hand-started copy is one process, with its pipes going to your terminal. The client's own copy is another, with its own launch, its own pipes, and its own lifecycle. They can open different data.

MCP formalizes that separation with a client-host-server design: the client is always the process that launches and owns the connection, never the other way round.

A running server proves that one launch worked. It proves nothing about the copy your client is talking to, so "it runs" and "it works" are separate claims and the second needs evidence from the client.

The client decides one more thing for you. It picks the working directory. Every relative path in that launch entry then resolves against a directory you never chose, which is why both paths below are absolute and why yours should be.

Why does a wrong path sometimes not break anything?

Because one path fails loudly and the other quietly builds you a replacement.

The client runs your command and hands over each argument in order. For auric-pm the database path is the third one, read by position. auric-pm has no --db flag. Invent one and all you do is shove the real path out of its slot.

{
  "mcpServers": {
    "auric-pm": {
      "command": "npx",
      "args": [
        "tsx",
        "/absolute/path/to/AuricIDE/src/mcp/server.ts",
        "/absolute/path/to/your-project/.auric/project.db"
      ]
    }
  }
}

The first path points at the server's own source. The second, the project database. They may share no parent directory at all.

Get the first one wrong and the launch stops. You know immediately. That is the easy failure. Get the second one wrong and, if its parent directory happens to be writable, the server creates a database there, builds the tables, and starts up perfectly happy. Every tool still appears. Every answer describes an empty project.

One wrong address sends your visitor to an empty lot. The other sends them to an empty house, where they settle in.

What a wrong path does
What you observe
Processstarts
Tool listall listed
Your datayour project

Both arguments are absolute and point where you meant them to. Worth noticing what this state looks like, because the next two copy its top half exactly.

The check that separates them

Not “did the server start”, but “did a tool return something I recognise”. Call one read-only tool and look at what comes back.

The safest fix for a wrong slot is to stop writing it by hand. AuricIDE can write the entry for you. Open Settings, then MCP Server, then Init .mcp.json. It writes .mcp.json into the open project root, leaves your other top-level keys and other server entries alone, and replaces only the auric-pm block. If the file already there is invalid JSON, the action stops with an error rather than overwriting it. Afterwards the panel says whether it created the file or updated one.

Open it anyway. Confirm the command is npx, the first argument is tsx, and both later arguments are absolute.

One catch in what it generates is worth knowing before you trust the output. Init .mcp.json builds both paths below whichever project is currently open, and that is correct only when the project you have open is AuricIDE itself. Open anything else and the server path points at a file that is not there. Fix it by hand, or point the client at the server another way.

A digital illustration of a laptop screen showing the AuricIDE settings menu with MCP Server options enabled.

What does "Running (PID: …)" actually tell you?

That AuricIDE has a child process. That is the whole claim.

The same settings panel can start auric-pm directly. Select Start, and a successful launch turns the status into Running (PID: …). What that process does not have is any connection to your agent client. A client launched through .mcp.json starts its own copy for its own connection, so the panel is reporting on a process your client has never heard of. Stopping one leaves the other running. Their lifecycles are separate. The status dot knows about one.

The panel also cannot tell you why anything failed. AuricIDE captures the child process output and drains both pipes so a full pipe cannot block the process. It shows you none of it. You get a PID and a status. No diagnostic text.

Who launched the server?
What you can see
Status and PIDRunning (PID: …)
Diagnosticsread and dropped
AnswersIs it running?

AuricIDE starts the server as its own child process and drains both output streams. The status dot and the PID are the entire signal, so this panel cannot tell you why something is misbehaving.

Why it splits this way

Only the process holding the pipe can read what comes out of it. Two questions, two different panels.

The client using stdio owns the streams that matter. JSON-RPC travels on stdout, diagnostics go to stderr, and whether you can read that stderr depends on your client's interface and logging. That is where to look.

What do you give up by keeping it local?

Quite a lot, and on purpose.

auric-pm speaks stdio. It opens no port. It has no listening socket. No daemon, no auth layer, no health endpoint. That keeps local setup small. The price is that this process can never be a shared service for your team.

The same choice runs through the data. Each project points at its own .auric/project.db, and tickets, tasks and history all come from that file. AuricIDE creates .auric/.gitignore with a wildcard, so the database stays on your machine. A clone brings no work record with it. That is the price of the record never leaving the laptop, and it is a real one. Sharing state now needs its own export or sync plan, one write happens at a time because it is a local file, and you register the server once per project rather than once.

Whether that suits you is a question about your team, not about the tool. One repository owning one work record is a scope decision. The useful part is noticing when you have outgrown it, rather than finding out during a handover.

How do you know the client really loaded it?

Ask it something whose answer you already know.

Change the entry, then reload the client. Open the tool list. If nothing about that list has changed, the client is probably still running on its old configuration. Now call one read-only tool, and pick a question you can check yourself: a ticket sitting in front of you in AuricIDE, a goal you wrote yesterday. A tool in the list proves the client found the server. A record you recognise proves the server found the right database. Two separate proofs, and only the second one tells you the data is real -- the first is exactly the kind of success that opened this article, complete and wrong at the same time.

Stderr often tells you more than a blank tool list does. A missing database argument prints the usage line and exits with code 1, so no tools appear at all until the launch command is fixed. That failure explains itself -- it maps straight onto the first proof.

AuricIDE ships one such server, so it is a short way to walk that test once. The lesson survives whichever server you wire up next. Process health is not connection health. A tool list is not data. Anything that answers you at all can answer you from the wrong place, so the last step of any setup is a question you already know the answer to.

Further reading

MCP's official architecture docs describe the protocol's stateless core, and Further reading on MCP adoption covers how teams are adopting it more broadly.

AuricIDE is open source

AGPL v3, alpha, and built in the open. If the loop above sounds like the way you want to work, the code is the fastest way to judge it.

★ Star on GitHub