l3wi / l3wi/jlc-cli

MCP server writes global KiCad library tables at startup and exits if it can't

Open
#5 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
11
Forks
4
PR merge metrics
No merged PRs in 30d

Description

Thanks for building this — the LCSC-to-KiCad conversion is just what I need.

One thing I noticed while evaluating it, in packages/mcp/src/index.ts:

async function main() {
  const registration = await ensureGlobalLibraryTables();
  if (!registration.success) {
    process.exit(1);
  }
  const httpPort = startHttpServer();
  ...
}

The server writes KiCad's global sym-lib-table and fp-lib-table before any tool is called. MCP hosts start servers speculatively — on session start, in every project, whether or not the user touches them. So merely having jlc-mcp in an MCP config mutates machine-global KiCad configuration that affects every project on the box, not just the one being worked on. For users with a deliberate library layout (shared repo-relative libraries, ${KIPRJMOD} paths) that's a surprising thing to have happen unasked.

The sharper problem is the process.exit(1). If the tables aren't writable, or the KiCad version isn't detected, the server doesn't start at all — so component_search, which is read-only and needs no libraries, becomes unavailable because of a filesystem write it never uses. A read path is gated behind an unrelated write.

Smaller version of the same thing: startHttpServer() binds a port unconditionally for the browser UI, so a user who only wants stdio tool calls gets a listening socket they didn't ask for.

Suggested fixes, roughly in order of value
  1. Make registration lazy — call ensureGlobalLibraryTables() on first library_* invocation rather than in main(). No new config surface, and search-only users never touch the tables.
  2. Degrade instead of exiting — on failure, log and disable the library_* tools, but keep serving component_search.
  3. Add a --read-only mode that omits the five writing tools from the advertised tool list entirely. That's a stronger guarantee than skipping startup work, since a model can't call a tool that isn't listed — useful for anyone wanting sourcing lookups without granting write access to their KiCad libraries.
  4. Same treatment for the HTTP server — --no-http, or start it lazily.

(1) and (2) alone would resolve it for me; (3) is the nice-to-have.

I'm happy to offer a PR for any subset of these if you'd welcome it. Just say which shape you'd prefer before I write anything, since the work spans packages/core and packages/mcp. Per your project protocol, I would include a changeset.

Unrelated: LICENSE file issue

package.json declares MIT, but there's no LICENSE in the repo, so GitHub reports the license as unset. Would you consider adding one? It makes contributing unambiguous.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/mcp/src/index.ts at main(), ensureGlobalLibraryTables(), and startHttpServer(), then trace the library_* and component_search tool registration across packages/core and packages/mcp. Confirm the preferred scope with maintainers before changing it; done should leave read-only search available without an unnecessary global table write or process exit, with any HTTP behavior explicitly decided and a changeset included.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, tooling
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.