MCP server writes global KiCad library tables at startup and exits if it can't
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
- Make registration lazy — call
ensureGlobalLibraryTables()on firstlibrary_*invocation rather than inmain(). No new config surface, and search-only users never touch the tables. - Degrade instead of exiting — on failure, log and disable the
library_*tools, but keep servingcomponent_search. - Add a
--read-onlymode 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. - 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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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