MCP 서버
9488e5f 기준입니다.Konnect는 AI가 보낸 구조화된 요청을 받아 KiCad 프로젝트를 읽고, 편집하고, 검사하는 도구 서버입니다. 사용자가 “저항을 추가하고 두 핀을 연결해 줘”라고 말하면 AI가 필요한 도구와 인자를 고르고, Konnect가 그 요청을 실제 파일 조작이나 KiCad 명령으로 옮깁니다.
AI가 무엇을 할지 결정하더라도, 무엇을 실제로 바꿔도 되는지는 실행 프로그램이 다시 확인해야 합니다. 이 경계를 배우는 것이 이 저장소를 읽는 가장 좋은 이유입니다. AI의 문장 생성 능력과 회로 편집의 정확성은 서로 다른 문제이기 때문입니다.
tools/list로 도구 설명과 입력 형식을 받고, tools/call로 도구를 실행합니다. MCP 서버 자체가 언어 모델인 것은 아닙니다.기사는 “이 저항을 여기로 옮겨요”라고 말합니다. 작업반장은 어느 도면인지, 좌표 단위가 맞는지, 다른 사람이 같은 도면을 열어 수정 중인지 먼저 확인합니다. 옮긴 뒤에는 실제 결과가 지시와 맞는지도 확인합니다.
KiCad는 작업대와 측정 장비에 해당합니다. Konnect는 그 작업대를 AI가 다룰 수 있게 연결하지만, 회로가 현실에서 잘 작동한다는 판단까지 대신 보증하지는 않습니다.
| 하려는 일 | 주된 실행 경로 | 코드에서 볼 곳 |
|---|---|---|
| 회로도 편집 | .kicad_sch를 읽어 구조를 바꾸고 조건을 확인해 저장 | crates/konnect-schematic-editor/, crates/konnect-sexp/ |
| 열린 PCB 편집 | NNG와 Protobuf를 통해 실행 중인 KiCad 10에 요청 | crates/konnect-ipc/src/client.rs |
| 검사·제조 파일 출력 | kicad-cli를 자식 프로세스로 호출 | crates/konnect-core/src/tools/cli.rs |
일부 PCB 작업에는 닫힌 보드 파일을 직접 편집하는 대체 경로도 있습니다. 다만 실시간 통신이 실패했다고 항상 파일을 수정하는 것은 아닙니다. 이 구분은 4절에서 가장 중요하게 다룹니다.
다음은 sch_components 도구 묶음을 불러온 뒤 사용할 수 있는 요청 예입니다. JSON의 필드 이름은 crates/konnect-core/src/tools/sch_components.rs의 입력 스키마에 대응합니다. 경로는 실제 설계 파일을 가리켜야 합니다.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "add_schematic_component",
"arguments": {
"schematic": "/designs/blink/blink.kicad_sch",
"lib_id": "Device:R",
"x": 100.0,
"y": 80.0,
"reference": "R1",
"value": "10k"
}
}
}
lib_id는 부품 기호의 라이브러리 식별자이고, 좌표는 회로도 기준 mm입니다. 도구 설명에는 1.27 mm 격자로 맞춘다고 적혀 있습니다. “저항 하나”라는 자연어도 실행 단계에서는 파일, 종류, 위치, 참조명이라는 구체적인 데이터로 바뀝니다.
2026-10-23의 GitHub Trending Rust Weekly #4로 선정된 프로젝트입니다. 같은 날 GitHub 기준 스타 1,375개, 포크 165개입니다. 아래의 관심 요인은 README와 설계 구조에 근거한 해석입니다. 스타 증가의 원인을 분석한 통계나 사용자 조사 결과로 읽어서는 안 됩니다.
텍스트 편집을 넘어 부품 배치, 배선, 전기 규칙 검사, 제조용 출력까지 도구화합니다. crates/konnect-core/src/tools/sch_wiring.rs, crates/konnect-core/src/tools/pcb_routing.rs, crates/konnect-core/src/tools/manufacturing.rs를 나란히 보면 하나의 설계가 여러 단계의 산출물을 거친다는 점이 드러납니다. 이 경로들의 공통 상위 디렉토리는 crates/konnect-core/src/입니다.
관심을 끄는 지점은 대화창 자체보다, 대화의 결과가 검증 가능한 설계 변경으로 연결되는 과정입니다. 초보 개발자는 여기서 “AI 기능 추가”가 실제로는 기존 소프트웨어의 입력·출력·실패 조건을 정리하는 작업임을 배울 수 있습니다.
README는 이 프로젝트를 KiCAD-MCP-Server의 후속 프로젝트라고 설명합니다. 전작의 TypeScript → Python 자식 프로세스 → SWIG 바인딩 경로를 줄이는 것이 재구현의 동기입니다. 전작의 구성과 유지 상태에 관한 설명은 Konnect README 기준이며, 아래 표는 성능 벤치마크가 아닙니다.
| 비교 축 | KiCad 직접 조작·CLI 조합 | 전작: README 기준 | Konnect |
|---|---|---|---|
| AI와의 연결 | 별도 연결 코드를 작성 | MCP 서버 제공 | Rust MCP 서버에 도구 카탈로그 통합 |
| 호출 경계 | GUI 조작 또는 명령 실행 | TypeScript·Python·SWIG 경유 | 서버 내부는 Rust 함수 호출, KiCad와는 IPC·CLI 경계 유지 |
| 회로도 변경 | 직접 저장 또는 외부 자동화 | kicad-skip 및 별도 로더 | 자체 파서·편집기와 충돌 감지 저장 |
| PCB 연동 | 사용자가 조작 경로 선택 | SWIG 중심, 실험적 IPC | KiCad 10 IPC 중심, 조건부 파일 대체 경로 |
| 도구 노출 | 자동화 구현에 따라 다름 | 라우터 방식 | 묶음별 불러오기·해제, 호출 기록 |
| 도입 조건 | KiCad와 필요한 스크립트 | Node.js·Python 환경 | 서버 바이너리 중심, GUI·출력 기능별 외부 조건 존재 |
장점은 배포 대상과 오류 경계를 줄일 수 있다는 점입니다. 다만 README의 “도구 호출은 함수 호출”은 서버 내부 경로에 관한 설명입니다. KiCad IPC, kicad-cli, 선택적인 외부 라우터까지 한 프로세스로 합쳐졌다는 뜻은 아닙니다.
모든 도구 설명을 매번 AI에게 전달하면 대화 문맥을 많이 차지합니다. Konnect는 project와 config만 먼저 활성화하고 필요한 묶음을 나중에 추가합니다. README는 기본 목록 약 2K 토큰, 전체 목록 약 23K 토큰으로 설명합니다. 이 수치는 문서의 추정치이며 실제 토크나이저나 클라이언트별 측정값은 아닙니다.
공구 200여 개의 사용설명서를 전부 펼치는 대신, 먼저 공구함 목차를 주고 작업에 맞는 서랍을 엽니다. 다만 서랍을 열었다는 알림을 무시하는 AI 클라이언트도 있으므로, 호환성을 위해 처음부터 모두 펼치는 예외가 필요합니다.
| 표기 | 해석 |
|---|---|
| GitHub 소개: 217개 | 2026-10-23 GitHub 설명문에 적힌 도구 수입니다. |
| README: 228개·21묶음 | 커밋 9488e5f의 README 표기입니다. |
| 등록부: 합계 228개 | crates/konnect-core/src/router/registry.rs의 21개 tool_count 합계입니다. 관리 도구는 별도입니다. |
도구 개수만으로 프로젝트의 완성도를 판단하기는 어렵습니다. 같은 저장소에서도 소개 문구와 등록부의 갱신 시점이 다를 수 있습니다. 학습할 때는 실제 도구 정의와 입력 스키마를 확인하는 습관이 더 유용합니다.
루트 Cargo.toml의 워크스페이스에는 7개 crates/ 패키지와 xtask, 총 8개 멤버가 있습니다. Tauri 뷰어는 명시적으로 제외되어 별도로 빌드됩니다. 같은 저장소에 있다는 사실과 같은 실행 파일에 포함된다는 사실은 구분해서 읽어야 합니다.
아래 “선언”은 의존성 파일에 적힌 허용 범위이고, “잠금”은 해당 커밋의 Cargo.lock에 기록된 선택 버전입니다. 예를 들어 tokio = "1"은 정확히 1.0.0을 고정한다는 뜻이 아닙니다.
| 기술 | 선언 → 잠금 | 역할과 소스 근거 |
|---|---|---|
| Rust | 에디션 2021, 최소 1.96, 도구체인 1.96.0 | Cargo.toml의 rust-version, rust-toolchain.toml의 channel |
| Tokio | 1 → 1.53.1 | features = ["full"]. 비동기 진입점, 입출력, 채널, 잠금, 자식 프로세스 |
| Axum | 0.8 → 0.8.9 | crates/konnect/src/transport/http.rs의 HTTP·SSE 통신 계층 |
| Serde | serde 1 → 1.0.229serde_json 1 → 1.0.151 | JSON-RPC 자료형을 Rust 구조체와 JSON 사이에서 변환 |
| JSON Schema | jsonschema 0.58 → 0.58.2 | 서버가 도구 입력을 Draft 2020-12 스키마로 검증 |
| nom | 8 → 8.0.0 | crates/konnect-sexp/src/parser.rs의 S-expression 파서 |
| NNG·Prost | nng 1 → 1.0.1prost 0.13 → 0.13.5 | KiCad IPC의 메시지 운반과 Protobuf 직렬화. crates/konnect-ipc/에서 사용 |
| Reqwest | 0.13 → 0.13.5 | 부품 정보 등 외부 HTTP 연동. JSON·스트림 기능 사용 |
| SQLite | rusqlite 0.40 → 0.40.2 | bundled 기능으로 SQLite 포함. JLCPCB 부품 데이터 접근 |
| TOML | 1.1 → 1.1.6+spec-1.1.0 | crates/konnect/src/config.rs의 설정 읽기 |
| resvg·image | =0.48.1 → 0.48.1image 0.25 → 0.25.10 | SVG를 PNG로 바꾸고 픽셀 차이를 계산. crates/konnect-render/ |
| gix | 0.87 → 0.87.1 | crates/konnect-vcs/의 Git 저장소 탐색 기반. 이 커밋에서는 작은 기반 구현 |
| topola_specctra | 0.1.0 → 0.1.0 | 외부 배선 도구와 교환하는 Specctra 형식의 구문 트리·변환 |
이 표의 의존성 선언은 루트 Cargo.toml과 각 패키지의 Cargo.toml에서 확인할 수 있습니다. konnect-core가 도메인 기능을 조립하고, konnect가 설정·실행·통신 방식을 담당합니다.
| 구성 | 실제 선언·파일 | 배울 점 |
|---|---|---|
| Tauri 2 | crates/schematic-viewer/Cargo.toml: tauri = "2"별도 잠금 파일: 2.12.0 | Rust 명령과 운영체제의 웹뷰를 연결하는 데스크톱 앱 |
| 파일 감시 | notify = "8" → 8.2.0 | 회로도 변경을 감지해 다시 렌더링 |
| 화면 | crates/schematic-viewer/frontend/index.html, 575줄 | HTML·CSS·일반 JavaScript로 확대·이동·시트 선택을 구현 |
| 앱 설정 | crates/schematic-viewer/tauri.conf.json: frontendDist = "frontend", 창 1280 × 900 | 별도 웹 개발 서버 없이 정적 프론트엔드를 포함 |
| 렌더링 원천 | crates/schematic-viewer/src/main.rs::render_to_svg_in() | kicad-cli sch export svg 결과를 표시 |
이 뷰어는 브라우저 기반 SaaS 대시보드가 아닙니다. 이 커밋에는 package.json, pyproject.toml, go.mod, Dockerfile이 없으며, 뷰어에 React나 TypeScript 빌드 파이프라인도 없습니다. 화면 기능의 학습 범위를 실제 코드에 맞추어 잡을 수 있습니다.
| 구성 | 확인한 설정 | 역할 |
|---|---|---|
| KiCad 진입점 | plugin/__init__.py, plugin/settings_dialog.py | KiCad 내부의 pcbnew·wx를 쓰는 Python 실행·설정 연결부 |
| 출력 형태 | crates/konnect/Cargo.toml: 바이너리와 cdylib·rlib | 독립 MCP 서버와 라이브러리 진입점이 함께 선언됨 |
| Protobuf 생성 | crates/konnect-ipc/build.rs, prost-build = "0.13" | protoc로 crates/konnect-ipc/proto/ 정의를 컴파일 |
| NNG 빌드 | README의 cmake 요구, nng-sys 의존성 | NNG C 라이브러리 빌드가 포함되어 순수 Rust 도구만으로 끝나지 않음 |
| 일반 CI | .github/workflows/ci.yml | Linux·Windows·macOS 검사, 테스트·문서 테스트·Clippy·서식·라이선스 검사 |
| 실제 KiCad CI | .github/workflows/e2e-kicad.yml: KiCad 10.0.5 | 주간·수동·릴리스 호출 등에서 실제 설치를 이용하는 별도 경로 |
| 릴리스 | .github/workflows/release.yml: Linux x86_64, Windows x86_64, macOS x86_64·ARM64 | 독립 실행 파일과 OS별 PCM 패키지. macOS PCM은 두 아키텍처를 합침 |
| 재현 환경 | flake.nix, flake.lock, Cargo.lock | Nix 개발·빌드 환경과 Rust 의존성 고정 |
.github/workflows/ci.yml은 protoc@3.23.4 설치와 Python 플러그인 테스트용 3.11을 명시합니다. 패키징 검사는 Python 3.12를 사용합니다. CI의 버전은 검증 환경의 기록이며 모든 사용자에게 그 Python 버전을 별도 설치하라는 뜻은 아닙니다.
rust-toolchain.toml은 컴파일러와 Clippy 변화로 생기는 차이를 줄입니다. resvg = "=0.48.1"은 렌더링 변화가 설계 변화처럼 보이는 것을 줄입니다. 둘 다 재현성을 위한 장치지만, 전자는 빌드 도구를, 후자는 비교 결과를 안정시키려는 선택입니다.
핵심 처리는 crates/konnect-core/src/mcp/handler.rs에 있습니다. handle_message()가 JSON을 요청 자료형으로 바꾸고, dispatch()가 MCP 메서드를 나눕니다. execute_tool()은 호출 시간과 결과 상태를 기록하고, dispatch_tool()이 관리 도구·업무 도구·오류를 구분합니다.
통신 성공, 명령 접수, 설계 변경 완료는 서로 다른 상태이므로 각각의 경계에서 확인해야 합니다. 이 한 문장을 기억하면 아래의 복잡한 코드가 왜 필요한지 이해하기 쉽습니다.
crates/konnect/src/main.rs는 설정을 읽고 McpHandler를 만든 뒤 Stdio·Http·Both 중 하나를 선택합니다. 표준 입출력과 HTTP는 같은 handle_message()를 호출합니다. 업무 도구는 요청이 어느 통로로 들어왔는지 몰라도 됩니다.
이를 어댑터 관점으로 읽어 보세요. 표준 입출력 어댑터는 줄 단위 JSON을 읽고 응답에 줄바꿈을 붙입니다. HTTP 어댑터는 같은 JSON 결과를 HTTP 응답으로 감쌉니다. 형식 변환은 바깥쪽에, 부품을 옮기는 규칙은 안쪽에 둡니다.
| 경계 | 구체적인 처리 | 초보자가 자주 놓치는 점 |
|---|---|---|
| 표준 입출력 | run_stdio()가 응답을 먼저 쓰고 대기 중인 알림을 비움 | stdout에 일반 로그를 쓰면 JSON 메시지와 섞임. 로깅은 stderr 사용 |
| HTTP | run_http()가 /mcp와 /health 등록 | 응답이 필요 없는 알림은 202 Accepted. 도구 실패는 별도의 결과 내용으로 판단 |
| 도구 실행 | ToolDef에 이름·설명·스키마·핸들러·보드 접근 계약을 묶음 | 설명문만 써 두는 것으로 입력 검증이 끝나지 않음 |
crates/konnect-core/src/tools/mod.rs의 tool! 매크로는 비동기 핸들러를 공통 타입으로 감싸 ToolDef::new()에 넣습니다. 그 생성자는 스키마의 허용 필드를 정리하고 검증기를 한 번 컴파일합니다. dispatch_tool()은 필수 인자와 스키마를 검사한 다음에 핸들러를 호출합니다.
// ToolDef의 중요한 필드만 보여 주는 학습용 축약
struct ToolDef {
name: &'static str,
input_schema: Value,
input_validator: Arc<jsonschema::Validator>,
handler: ToolHandlerFn,
board_access: BoardAccess,
}
// 개념적 실행 순서: 실제 오류 응답 코드는 생략
validate_required_fields(&tool.input_schema, &args)?;
tool.input_validator.validate(&args)?;
(tool.handler)(&args, context).await
이 예에서 보조 함수 이름은 흐름을 설명하기 위한 것입니다. 실제 필수 인자 검사 함수는 first_missing_required()입니다. 광고한 스키마와 실행할 때의 검증기를 같은 정의에서 만들면 문서와 동작이 어긋날 가능성을 줄일 수 있습니다.
crates/konnect-core/src/router/registry.rs의 ALL_TOOLSETS는 전체 공구함 목록이고, STARTER_KIT는 ["project", "config"]입니다. ToolRouter는 전체 등록부와 현재 활성 도구를 따로 관리합니다. 활성 묶음은 HashSet, 이름별 도구는 HashMap에 담습니다.
ToolRouter::load()는 해당 묶음의 정의를 활성 맵에 넣습니다. 카탈로그는 OnceLock으로 한 번 만들고, 검증기는 Arc로 공유합니다. “나중에 불러오기”는 여기서 주로 AI에게 공개하는 목록을 확장하는 것이지, 매번 별도 플러그인 파일을 내려받거나 동적 라이브러리를 여는 것은 아닙니다.
// MCP 도구 호출의 인자 부분 예: 배선 도구 묶음 공개 요청
{
"name": "load_toolset",
"arguments": { "name": "sch_wiring" }
}
// 서버가 목록 갱신을 알리는 메서드
notifications/tools/list_changed
McpHandler::notify_tools_list_changed()는 HTTP의 SSE 수신자와 표준 입출력의 알림 채널 양쪽으로 변경을 전달합니다. 클라이언트가 목록을 다시 읽어야 새 입력 스키마를 알 수 있으므로, 서버 안에서 도구를 활성화하는 것만으로는 충분하지 않습니다.
| 항목 | 커밋 기준 집계·기본값 |
|---|---|
| 업무 도구 전체 | 21개 묶음의 등록 수 합계 228개 |
| 기본 활성 업무 도구 | project 7개 + config 7개 = 14개 |
| 항상 공개하는 관리 도구 | 기본 7개. Unix 독립 서버의 표준 입출력 전용 모드에서는 reload_server 1개 추가 |
| 처음 보이는 도구 수 | 일반적으로 21개, 위 Unix 모드에서는 22개. 전체 사전 공개 설정·클라이언트 예외에 따라 달라짐 |
| 모두 활성화한 경우 | 업무 228개 + 관리 7개 = 235개. 위 Unix 모드에서는 236개라는 정적 집계 |
| 자동 확장 설정 | auto_load_toolsets = false, eager_toolsets = false가 기본값 |
McpHandler::adapt_to_client()는 이름이 claude-ai로 시작하는 클라이언트를 목록 캐시 예외로 취급하여 처음부터 전체 묶음을 활성화합니다. 모든 클라이언트가 동적 목록을 잘 지원한다고 가정하지 않는, 실제 호환성 설계의 사례입니다.
회로도 계층에는 서로 다른 두 표현이 있습니다. crates/konnect-sexp/src/parser.rs의 SexpNode는 읽기용 구문 트리이고, 같은 패키지의 crates/konnect-sexp/src/writer.rs는 지정한 문자열 구간만 고칩니다. 한편 crates/konnect-schematic-editor/src/schematic/mod.rs는 Schematic·Symbol 같은 타입으로 편집하고 다시 직렬화합니다.
crates/konnect-core/src/tools/sch_components.rs의 일반 CRUD는 타입 기반 편집기를 사용하며 핀 좌표 계산 등에는 konnect-sexp 기능을 함께 씁니다. 따라서 “모든 쓰기가 문자열 치환이다” 또는 “모든 편집이 파일 전체의 바이트를 보존한다”고 설명하면 틀립니다.
부분 편집에서 중요한 구현은 apply_edits()의 뒤쪽 바이트 위치부터 적용하는 정렬입니다. 앞에서 긴 문자열을 삽입하면 뒤쪽 위치가 밀리지만, 뒤에서 고치면 앞쪽 기준 위치는 유지되기 때문입니다.
// crates/konnect-sexp/src/writer.rs의 실제 구현
pub fn apply_edits(mut content: String, mut edits: Vec<SexpEdit>) -> String {
edits.sort_by_key(|e| std::cmp::Reverse(e.start));
for edit in edits {
assert!(edit.start <= edit.end, "Edit start > end");
assert!(edit.end <= content.len(), "Edit end out of bounds");
content.replace_range(edit.start..edit.end, &edit.replacement);
}
content
}
이 함수의 인덱스는 글자 번호가 아니라 바이트 위치입니다. UTF-8 문자의 중간을 잘라서는 안 되며, 겹치는 편집 구간의 타당성도 호출 쪽에서 보장해야 합니다. 정렬 하나가 모든 입력을 안전하게 만들어 주지는 않습니다.
| 안전 장치 | 실제 함수와 역할 |
|---|---|
| 읽기 일관성 | read_consistent()가 문서 잠금에 참여하여 내용을 읽음 |
| 수정 충돌 감지 | write_atomic_if_unchanged()가 현재 내용과 기대한 원문을 정확히 비교. 다르면 Conflict |
| 파일 교체 | write_atomic_unlocked_with()가 같은 디렉토리의 임시 파일에 쓰고 flush·sync_all·rename 수행 |
| 편집기 충돌 회피 | 쓰기 전과 교체 직전에 KiCad 문서 잠금을 확인하여 열린 설계 파일의 직접 교체를 거부 |
| 모르는 필드 보존 | unmodelled_children()가 타입 모델로 재구성하지 않는 하위 노드도 유지 |
| 여러 파일의 복구 | crates/konnect-sexp/src/transaction.rs::commit_file_transaction()이 변경 전제 확인 → 저널 저장 → 파일별 반영 → 검증 → 저널 삭제 |
여러 파일의 트랜잭션은 운영체제가 모든 파일을 동시에 바꾸는 기능이 아닙니다. recover_file_transactions()는 이미 새 내용인 파일은 두고, 이전 내용인 파일은 변경을 마저 적용합니다. 예상 밖으로 달라진 내용은 덮어쓰지 않고 충돌로 남깁니다. 즉 재시작 후 앞으로 복구할 수 있는 저널 방식입니다.
열린 KiCad 보드에는 아직 저장하지 않은 변경이 있을 수 있습니다. 통신 장애를 “KiCad가 없다”고 단정하고 디스크 파일을 편집하면 화면과 파일이 서로 다른 설계가 됩니다. crates/konnect-core/src/tools/board_session.rs의 BoardSessionMemory는 보드를 실시간으로 관찰한 사실을 기억합니다.
| 관찰한 상황 | 가능한 판단 |
|---|---|
| KiCad에 도달했고 작업이 거부됨 | 거부 이유를 반환. 파일 편집으로 우회하지 않음 |
| KiCad에 도달하지 못함 | 파일 대체 경로를 지원하는 도구만, 잠금·이전 관찰 등 추가 조건을 확인 |
| 이전에 실시간 보드를 봤고 잠금이 남음 | 미저장 상태의 가능성이 있으므로 파일 대체 편집 거부 |
| 실시간 관찰 당시 있던 잠금이 사라짐 | authorize_file_fallback()이 정상 종료의 근거로 보고 관찰 기록을 해제할 수 있음 |
| 변경 요청 후 결과 확인이 불확실함 | 성공·실패를 추측해 재시도하지 않고 상태를 다시 확인 |
실제 IPC 구현의 KiCadIpcClient::run_commit()은 begin_commit()으로 변경 묶음을 열고 작업 성공 시 push_commit()으로 반영하며, 확인된 실패에는 drop_commit()을 시도합니다. 다만 IpcOutcomeUnknown처럼 반영 여부가 불확실하면 취소 요청도 보내지 않으며, LateReply는 별도의 복구 경로를 거칩니다. 이 묶음은 KiCad의 되돌리기 단위와 연결됩니다. 마지막 응답을 받지 못한 경우처럼 반영 여부가 모호한 상황은 일반적인 사전 거부와 구별해야 합니다.
은행 이체 요청의 응답이 끊겼다고 같은 이체를 다시 누르면 중복 출금될 수 있습니다. 부품 이동도 비슷합니다. “응답을 못 받음”과 “아무것도 바뀌지 않음”은 같은 사건이 아닙니다.
crates/konnect-core/src/outcome.rs에는 complete·partial·failed·uncertain 상태가 있습니다. 이 공통 결과 형식을 채택한 도구는 해당 커밋에서 4개로 한정됩니다. 저장소 전체의 모든 도구가 이미 동일한 결과 계약을 갖는다고 일반화해서는 안 됩니다.
폴더 이름을 외우기보다 요청 한 개가 통과하는 파일을 연결하면 큰 저장소도 읽을 수 있습니다. 처음부터 모든 도구 구현을 읽으려 하면 비슷한 JSON 스키마와 긴 테스트에 묻히기 쉽습니다.
| 읽는 순서 | 질문 | 찾아갈 파일 |
|---|---|---|
| 1. 실행 | 누가 서버를 시작하는가? | crates/konnect/src/main.rs |
| 2. 메시지 | 메서드와 도구 이름은 어떻게 나누는가? | crates/konnect-core/src/mcp/handler.rs |
| 3. 등록 | 내가 찾는 도구가 어느 묶음에 있는가? | crates/konnect-core/src/router/registry.rs |
| 4. 한 기능 | 인자 검사 후 무엇을 바꾸는가? | crates/konnect-core/src/tools/sch_components.rs |
| 5. 저장 | 읽은 뒤 파일이 바뀌면 어떻게 되는가? | crates/konnect-sexp/src/writer.rs |
| 6. 실패 사례 | 작성자가 어떤 실수를 예상했는가? | 같은 파일의 #[cfg(test)]와 각 패키지의 tests/ |
커밋 9488e5f에서 Git이 추적하는 파일의 물리적 줄 수입니다. 빈 줄·주석·단위 테스트·통합 테스트를 모두 포함하며, 빌드 산출물은 포함하지 않습니다. 줄 수는 실행 성능이나 구현 품질의 점수가 아니라 읽을 범위를 가늠하는 지표입니다.
| 범위 | 파일 수 | 줄 수 |
|---|---|---|
| Rust 전체 | 147 | 170,956 |
| Python | 7 | 1,443 |
| Protobuf 정의 | 12 | 3,370 |
| HTML | 1 | 575 — 내부 CSS·JavaScript 포함 |
| 셸·PowerShell | 2 | 283 |
| YAML 워크플로·설정 | 5 | 752 |
Rust 중 konnect-core가 124,553줄, konnect-ipc가 16,517줄, konnect-sexp가 12,474줄입니다. 기능 구현과 실패 재현 테스트가 업무 계층에 집중되어 있습니다. 반면 konnect-vcs는 84줄의 기반 코드이므로 완성된 버전 관리 제품처럼 설명하면 안 됩니다.
# 저장소 루트에서 읽기만 하며 Rust 물리적 줄 수 재기
git ls-files -z '*.rs' | python3 -c '
import sys
from pathlib import Path
paths = [p for p in sys.stdin.buffer.read().split(b"\0") if p]
print(sum(len(Path(p.decode()).read_bytes().splitlines()) for p in paths))
'
이 방식은 인라인 테스트를 “구현 코드”와 자동으로 나누지 않습니다. 테스트 비중을 알고 싶다면 파일명뿐 아니라 #[cfg(test)] 내부까지 분석해야 합니다. 여기서는 전체 물리적 줄 수라는 일관된 기준만 사용합니다.
기술을 배웠다는 기준은 코드를 따라 쓰는 것이 아니라, 실패 사례를 하나 더 설명할 수 있게 되는 것입니다. 다음 여섯 주제는 각각 작은 읽기 과제와 독립적인 실습으로 확장할 수 있습니다.
McpHandler는 Arc<ToolContext>를 공유합니다. ToolRouter는 RwLock<HashMap<String, ToolDef>>로 활성 도구 맵을 보호합니다. ToolDef를 복제해도 컴파일한 검증기는 Arc로 공유하므로 검증기를 매 호출마다 새로 만드는 구조가 아닙니다.
배울 것: 소유권과 복사 비용, 읽기·쓰기 잠금의 차이, 트레이트 객체로 서로 다른 비동기 함수를 같은 칸에 담는 방법입니다. ToolHandlerFn의 Pin<Box<dyn Future...>>는 비동기 계산을 공통 반환 타입으로 감싸기 위한 표현부터 이해하면 됩니다.
crates/konnect-core/src/router/mod.rs의 loaded_tools_reuse_their_compiled_input_schema 테스트를 읽고, 왜 값의 동등성 대신 Arc::ptr_eq()를 확인하는지 설명해 보세요. 답은 “같은 내용을 다시 만들었다”와 “같은 검증기를 공유한다”가 다르기 때문입니다.
NNG 클라이언트는 동기식 API를 사용합니다. crates/konnect-core/src/tools/mod.rs::with_ipc_classified()는 이 일을 tokio::task::spawn_blocking()으로 보내 비동기 실행 스레드에서 직접 오래 기다리는 일을 줄입니다. 반면 kicad-cli는 Tokio의 자식 프로세스 API로 기다립니다.
crates/konnect-ipc/src/client.rs에는 기본 명령 수신 대기 30초, 송신 대기 5초, 층 이름 조회 전체 대기 예산 10초가 있습니다. 도구마다 필요한 제한이 다르며, 여러 작은 조회가 누적되면 전체 지연은 커집니다.
실습 아이디어: “요청 전에 연결 실패”, “명령을 보낸 뒤 시간 초과”, “KiCad가 명시적으로 거부”를 세 칸으로 나누세요. 각각을 재시도해도 되는지, 어떤 상태 확인이 필요한지 적으면 비동기 문법보다 중요한 실패 모델을 익힐 수 있습니다.
crates/konnect-sexp/src/parser.rs의 구문 트리는 Atom·Str·List의 재귀 구조입니다. 예를 들어 (at 10 5 90)은 단순한 문자열 네 조각이 아니라 위치와 방향을 나타내는 한 노드입니다. 구문 분석 뒤에는 단위와 좌표계를 해석하는 단계가 남습니다.
// 실제 SexpNode의 세 가지 경우
pub enum SexpNode {
Atom(String),
Str(String),
List(Vec<SexpNode>),
}
// 기호 로컬 좌표 → 회로도 좌표의 처리 순서
Y축 방향 전환 → 회전 → 미러 → 부품 원점만큼 이동
crates/konnect-sexp/src/geometry.rs::transform_pin()은 라이브러리의 위쪽이 양수인 Y축을 화면의 아래쪽이 양수인 Y축으로 바꾼 뒤 회전합니다. 미러는 회전 뒤에 적용합니다. 순서를 바꾸면 90도·270도 배치에서 다른 핀 위치가 나올 수 있습니다.
| 로컬 핀·부품 원점 | 변환 조건 | 기대 위치(mm, 반올림) |
|---|---|---|
| 핀 (2.54, 0), 원점 (10, 5) | 0도, 미러 없음 | (12.54, 5.00) |
| 동일 | 90도, 미러 없음 | (10.00, 2.46) |
| 동일 | 90도, mirror_x = true | (10.00, 7.54) |
또한 crates/konnect-sexp/src/schematic.rs::extract_lib_pins_for_unit()은 Name_N_M 형식의 하위 기호에서 공통 유닛 0과 선택한 유닛의 핀만 모읍니다. 기호 바로 아래의 핀과 이 접미사가 없는 하위 기호의 핀은 항상 포함합니다. 이름의 숫자 의미를 모르면 다른 증폭기 유닛의 핀을 같은 위치에 겹쳐 해석할 수 있습니다. 자료형의 정확성과 전자회로 의미의 정확성을 함께 살펴보세요.
add_schematic_component는 schematic·lib_id·x·y를 필수로 요구하고 unit의 최솟값을 1로 둡니다. 좌표에 문자열 "100"을 보내는 것과 숫자 100을 보내는 것은 다릅니다. 입력을 조용히 기본값으로 바꾸는 대신 잘못된 필드를 알려 주어야 AI도 올바르게 복구할 수 있습니다.
배울 것: JSON이 문법적으로 파싱되는지, 입력 스키마에 맞는지, 실제 설계에서 수행 가능한지는 서로 다른 검사입니다. 예를 들어 숫자 좌표가 유효해도 대상 기호가 존재하지 않으면 작업은 성립하지 않습니다.
실습 아이디어: 필수 키 누락, 타입 오류, 범위 오류, 존재하지 않는 라이브러리, 변경 후 검증 실패를 분리해 기대 응답을 적으세요. crates/konnect-core/src/mcp/error.rs의 구조화된 오류와 crates/konnect-core/src/outcome.rs의 수행 상태를 함께 읽으면 “오류 문구”와 “실제 변경 여부”의 차이를 볼 수 있습니다.
crates/schematic-viewer/src/main.rs의 QUIET_WINDOW는 600 ms입니다. drain_until_quiet()는 연속 저장 이벤트를 모으고, 600 ms의 조용한 구간과 최대 대기 기준인 5초에 따라 렌더링 시점을 정합니다. is_relevant_sch_change()는 자동 저장·잠금 이름을 걸러 내고, 계층 시트 순회는 최대 깊이 20과 조상 집합으로 순환을 막습니다.
별도의 crates/konnect-render/src/lib.rs::svg_to_png()는 화면에 표시되는 텍스트 요소가 있는 SVG를 거부하고, KiCad가 글자를 경로로 내보낸 SVG를 일정한 렌더러로 처리합니다. RENDERER_ID는 resvg-0.48.1입니다. 렌더러 버전이나 글꼴이 달라 생긴 픽셀 차이를 설계 수정으로 오인하지 않으려는 선택입니다.
어제와 오늘의 도면 사진을 비교하는데 카메라 초점과 조명이 바뀌면, 달라진 픽셀이 도면 때문인지 촬영 조건 때문인지 모릅니다. 시각 테스트는 먼저 “같은 카메라로 찍기”부터 해결해야 합니다.
실습 아이디어: 파일 이벤트가 0 ms, 200 ms, 500 ms에 왔을 때 600 ms의 조용한 구간이 언제 완성되는지 시간선을 그리세요. 마지막 이벤트 뒤 약 600 ms가 기준이므로 작업 시간 등을 제외하면 1,100 ms 무렵입니다. 첫 이벤트 직후부터 재는 방식과 구별해 보세요.
crates/konnect-core/src/design_hash.rs::design_state_hash()는 설계 파일 경로를 정렬하고 줄바꿈을 LF로 정규화한 뒤 SHA-256을 계산합니다. 각 파일은 path\0content\0 형태로 구분해 합칩니다. Windows의 CRLF와 다른 운영체제의 LF 때문에 같은 설계를 다른 것으로 보는 일을 줄입니다.
.konnect/의 파생 상태는 설계 해시에서 제외합니다. 검사 결과가 설계 해시를 기록했는데 그 기록 때문에 설계 해시가 다시 바뀌면 순환 문제가 생기기 때문입니다. “어떤 설계에 대한 검사 결과인가”를 명확히 하는 원리는 문서 빌드·데이터 처리·AI 평가에도 적용할 수 있습니다.
어떤 검사가 통과한 직후 부품 위치를 바꾸었다면, 이전 통과 결과를 계속 사용해도 될까요? 검사 이름과 시간만 저장해서는 부족합니다. 검사 대상의 내용 식별자까지 함께 저장해야 그 결과가 현재 설계에도 해당하는지 판단할 수 있습니다.
README에는 CPU 코어 수나 RAM의 공식 최소 수치가 명시되어 있지 않습니다. 서버 바이너리만의 요구와 KiCad GUI·부품 데이터·외부 라우터를 포함한 전체 환경을 분리해 판단해야 합니다. 다음 표는 기능별 의존 조건입니다.
| 사용 범위 | 필요한 조건 | 근거·주의점 |
|---|---|---|
| 소스 학습 | 텍스트 편집기, Git, 줄 수 집계용 Python 등 | KiCad나 언어 모델을 실행하지 않아도 구조와 테스트를 읽을 수 있음 |
| MCP 서버 연결 | 해당 OS용 Konnect 실행 파일과 MCP 클라이언트 | 모델 실행·요금·네트워크 조건은 사용하는 AI 서비스에 따라 별도 |
| 회로도 파일 처리 | 설계 파일과 작업별 필요한 심벌 라이브러리 | 파싱·직접 편집에는 KiCad GUI가 필수는 아님. 라이브러리 조회·출력은 추가 조건 확인 |
| 열린 PCB 실시간 편집 | KiCad 10 PCB 편집기에서 대상 보드를 열고 API 활성화 | KICAD_API_SOCKET·설정·자동 탐색을 통해 올바른 IPC 주소 확보 |
| ERC·DRC·출력 | kicad-cli 실행 파일과 관련 라이브러리 | 설치 위치가 검색되지 않으면 kicad_cli 경로 설정 |
| 선택적 뷰어 | OS 웹뷰 환경과 별도 뷰어 바이너리 | Linux 빌드 워크플로는 GTK 3·WebKitGTK 4.1 개발 패키지 등을 설치 |
| 부품 검색 | JLCPCB 데이터와 해당 저장 공간 | README의 약 250만 부품 카탈로그는 기능 설명. 실제 DB 크기와 메모리 사용량 수치는 별도 |
| 외부 자동 배선 | 호환되는 Freerouting·Java 환경 등 | 선택 기능. check_freerouting으로 엔진·호환성 조건을 구분하는 설계 |
| 소스 빌드 | Rust 1.96.0, protoc, CMake와 플랫폼 빌드 도구 | NNG의 C 빌드와 Protobuf 생성 포함. 뷰어는 별도 시스템 의존성 추가 |
릴리스 워크플로에 적힌 대상은 x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc, x86_64-apple-darwin, aarch64-apple-darwin입니다. 이 목록이 ARM Linux 등 모든 조합의 지원을 의미하지는 않습니다. 패키징 메타데이터는 KiCad 범위를 10.0부터 10.99로 선언합니다.
GPU는 Konnect 서버가 요구하는 구성 요소로 명시되어 있지 않습니다. 이 서버는 LLM 가중치를 로컬에 올리는 추론 서버가 아닙니다. 로컬 모델을 연결하면 그 모델의 하드웨어 요구가 별도로 생기며, KiCad의 큰 보드·3D 작업도 설계 크기에 따라 자원을 사용합니다.
# 설정 형식을 이해하기 위한 예
transport = "stdio"
kicad_cli = "kicad-cli"
auto_load_toolsets = false
eager_toolsets = false
# transport를 "http" 또는 "both"로 바꿀 때 쓰는 기본 주소
http_address = "127.0.0.1:3000"
crates/konnect/src/config.rs::default_config_paths()는 현재 디렉토리의 konnect.toml, settings.json, 실행 파일 주변 설정, 사용자 설정 순으로 후보를 만듭니다. 기본 정책은 처음 존재하는 파일 하나를 읽는 것이며 여러 설정을 합치지 않습니다. --config는 명시적 경로를 선택합니다.
HTTP 계층은 기본적으로 루프백 주소에 묶이며 Origin이 있으면 로컬 출처인지 검사합니다. validate_origin()에서 출처 없는 네이티브 요청은 통과합니다. 이 검사를 사용자 인증이나 공개 인터넷 서비스용 접근 제어와 같은 것으로 이해하면 안 됩니다.
README의 실행 파일 20~25 MB, 다운로드 약 9 MB는 문서의 안내 수치입니다. KiCad 설치, 뷰어의 웹뷰, 선택적인 Java 라우터와 부품 데이터까지 합친 설치 크기가 아닙니다. 모든 플랫폼에서 완전 정적 링크를 보장하는 실측 결과로도 해석할 수 없습니다.
실습의 결과물은 실행 화면 한 장보다, 입력과 기대 결과와 실패 조건을 설명한 작은 기록이면 좋습니다. 아래 과제는 대부분 소스 읽기와 종이 위 추적으로 시작할 수 있습니다. 구현 실험으로 확장할 때는 독립된 연습용 데이터와 프로젝트를 사용하세요.
목표: 1절의 add_schematic_component 요청이 도구 실행까지 어떻게 도착하는지 그립니다.
crates/konnect/src/main.rs에서 표준 입출력 모드 선택 지점을 찾습니다.run_stdio() → handle_message() → dispatch() → execute_tool() → dispatch_tool()을 연결합니다.x가 없을 때를 분기합니다.완료 기준: 각 화살표 옆에 파일 경로를 적고, “도구가 비활성 상태”와 “활성 도구의 입력이 잘못됨”을 다른 오류로 설명할 수 있습니다. 기본 설정에서 자동 불러오기는 꺼져 있다는 점도 표시하세요.
목표: write_atomic_if_unchanged()가 필요한 이유를 설명합니다. 다음 시간선에서 A·B·C는 서로 다른 완전한 파일 내용입니다.
완료 기준: 첫 상황에서는 B를 덮어쓰지 않고 충돌을 반환한다고 설명합니다. 임시 저장·파일 교체·교체 후 확인이 각각 무엇을 막는지, 다중 파일 저널은 왜 별개인지 구별하세요.
목표: transform_pin()과 extract_lib_pins_for_unit()을 숫자 예제로 이해합니다.
mirror_x를 추가하고, 미러를 먼저 적용하면 결과가 달라지는지 비교합니다.완료 기준: 회전·미러의 순서와 Y축 방향을 말로 설명하고, 선택 유닛 외의 핀이 섞이면 어떤 연결 오류가 생길지 설명합니다. 부동소수점 기대값 비교에는 작은 오차 허용이 필요하다는 점도 기록하세요.
목표: 가상의 “부품 여러 개 이동” 도구에 입력 스키마와 결과 계약을 설계합니다. 실제 저장소에 기능을 추가하지 않아도 됩니다.
완료 기준: 각 상태에 입력 예와 결과 예를 한 쌍씩 붙입니다. crates/konnect-core/src/outcome.rs의 ADOPTED_OUTCOME_TOOLS와 비교하여 공통 형식을 전체 도구로 넓히기 전에 어떤 검증이 필요한지 설명하세요.
목표: 운영체제 차이와 중간 종료가 있어도 확인할 수 있는 테스트 사례를 설계합니다.
완료 기준: 최소 6개 사례에 대해 변경 대상·기대 결과·보존할 증거를 표로 작성합니다. 복구가 원래 상태로 되돌리기인지, 남은 변경을 마저 적용하기인지도 명시하세요. 참고 구현은 crates/konnect-core/src/design_hash.rs와 crates/konnect-sexp/src/transaction.rs입니다.
# 다음은 파일을 바꾸지 않는 읽기 명령
rg -n 'STARTER_KIT|ALL_TOOLSETS' crates/konnect-core/src/router/registry.rs
rg -n 'dispatch_tool|first_missing_required' crates/konnect-core/src/mcp/handler.rs
rg -n 'write_atomic_if_unchanged|Conflict' crates/konnect-sexp/src/writer.rs
rg -n 'recover_file_transactions' crates/konnect-sexp/src/transaction.rs
rg -n 'transform_pin|mirror_x' crates/konnect-sexp/src/geometry.rs
검색 결과 한 줄만 보고 결론 내리지 말고 함수 전체와 호출 지점까지 읽으세요. 특히 오류가 반환되는 시점이 변경 전인지 후인지 확인하면 재시도 정책을 더 정확하게 정할 수 있습니다.
주차는 학습 순서의 예시입니다. Rust가 처음이면 1주차를 더 길게 잡고, 전자회로 경험이 없다면 저항·기호·넷·풋프린트의 차이를 먼저 익히세요. 매주 새로운 기능을 더하기보다, 같은 요청의 입력·실행·저장·검증을 차례로 깊게 이해해 보세요.
| 주차 | 학습 주제 | 읽을 코드 | 완료 산출물 |
|---|---|---|---|
| 1주차 | Rust 구조체·열거형·Option·Result·소유권 | crates/konnect-core/src/mcp/protocol.rs, crates/konnect-sexp/src/parser.rs | JSON 요청과 Rust 자료형을 대응시킨 표 |
| 2주차 | JSON-RPC·MCP·입력 스키마·핸들러 | crates/konnect-core/src/mcp/handler.rs, crates/konnect-core/src/tools/mod.rs | 과제 1의 요청 경로와 입력 오류 사례 5개 |
| 3주차 | 구문 트리·문자열 편집·좌표계·유닛 | crates/konnect-sexp/src/geometry.rs, crates/konnect-sexp/src/schematic.rs | 과제 3의 좌표·핀 선택 기대값 표 |
| 4주차 | 잠금·낙관적 충돌 검사·원자 저장·저널 | crates/konnect-sexp/src/writer.rs, crates/konnect-sexp/src/transaction.rs | 과제 2의 시간선과 장애 복구 행렬 |
| 5주차 | Tokio·NNG·Protobuf·실시간/파일 상태 경계 | crates/konnect-ipc/src/client.rs, crates/konnect-core/src/tools/board_session.rs | 접속 불가·거부·불확실을 구별한 재시도 규칙 |
| 6주차 | 파일 감시·시각 비교·통합 테스트·배포 | crates/schematic-viewer/src/main.rs, .github/workflows/ | 실습 결과를 묶은 짧은 설계 검토서 |
.github/workflows/ci.yml은 cargo test --workspace --locked --lib --tests와 문서 테스트를 분리합니다. 뷰어는 워크스페이스 밖이므로 별도 작업에서 검사합니다. “워크스페이스 전체 테스트”라는 말이 저장소의 모든 코드 검사를 뜻하지 않는 사례입니다.
crates/konnect-core/tests/conformance_test.rs는 KiCad가 만든 데모 회로도를 기준으로 읽기·쓰기 동작을 확인하는 테스트 모음입니다. KiCad 데모가 없으면 건너뛸 수 있으므로, 테스트 파일이 존재한다는 사실만으로 실제 KiCad 검증이 수행되었다고 판단해서는 안 됩니다.
.github/workflows/e2e-kicad.yml은 KiCad 10.0.5를 설치한 Windows 환경에서 설계 생성·배선·ERC·Gerber·DRC 경로를 다루도록 구성되어 있습니다. 릴리스 워크플로도 이 별도 검증을 호출합니다. 이는 워크플로의 의도와 설정에 대한 설명이며 특정 실행의 통과 기록을 뜻하지 않습니다.
이 흐름을 자신의 작은 파일 변환기에도 적용해 보세요. 전자회로 전용 지식은 달라도, 입력 계약과 안전한 저장과 검증 증거를 나누는 방법은 그대로 가져갈 수 있습니다.
| 용어 | 쉬운 설명 |
|---|---|
| KiCad | 회로도와 PCB를 설계하는 전자설계 도구입니다. Konnect가 대신 구현한 것이 아니라 연결해서 사용하는 대상입니다. |
| 심벌 | 회로도에서 부품을 나타내는 기호입니다. 핀과 전기적 의미를 표현합니다. |
| 풋프린트 | PCB 위에 부품을 실장하기 위한 패드·외곽 등의 형상입니다. 심벌과 역할이 다릅니다. |
| 참조명 | R1·C2처럼 설계에서 부품을 구별하는 이름입니다. 라이브러리의 부품 종류 이름과 구별합니다. |
| 넷 | 전기적으로 같은 연결에 속한 핀·패드의 묶음입니다. 화면에서 선이 가까워 보이는 것과 실제 연결은 다릅니다. |
| 유닛 | 한 부품 기호를 여러 기능 블록으로 나눈 단위입니다. 선택한 블록과 공통 핀을 올바르게 골라야 합니다. |
| ERC / DRC | ERC는 회로도의 전기 규칙, DRC는 PCB의 간격·배선 같은 설계 규칙을 검사합니다. 검사 통과가 모든 실물 성능을 보증하지는 않습니다. |
| Gerber | 제조업체에 기판의 구리·마스크 등 층 정보를 전달하는 대표적인 출력 형식입니다. |
| BOM / 위치 파일 | BOM은 부품 목록이며 위치 파일은 조립 장비가 쓸 부품 위치·방향 정보입니다. 제조 출력에는 둘 다 중요합니다. |
| MCP | AI 클라이언트가 도구 목록과 입력 형식을 얻고 실행 결과를 받는 통신 약속입니다. |
| JSON-RPC | JSON 안에 메서드·인자·요청 식별자를 넣어 호출하고 응답하는 방식입니다. |
| JSON Schema | JSON에 어떤 필드와 자료형과 범위를 허용하는지 적는 규칙입니다. Konnect는 서버에서도 이를 검사합니다. |
| 도구 묶음 | sch_wiring처럼 관련 도구를 모은 단위입니다. 전체 카탈로그와 현재 활성 상태는 다릅니다. |
| 표준 입출력 | 프로세스의 입력·출력 통로입니다. 이 서버는 한 줄씩 JSON을 주고받으므로 일반 로그를 출력 통로에 섞으면 안 됩니다. |
| SSE | 서버가 연결된 클라이언트로 이벤트를 흘려보내는 HTTP 방식입니다. 여기서는 도구 목록 변경 같은 알림을 보냅니다. |
| IPC | 같은 컴퓨터의 프로그램들이 통신하는 방식입니다. Konnect와 KiCad 사이의 실시간 명령 통로입니다. |
| NNG | 프로세스 사이에서 메시지를 운반하는 라이브러리입니다. KiCad IPC는 요청·응답 패턴을 사용합니다. |
| Protobuf / Prost | Protobuf는 구조화된 메시지를 표현·직렬화하는 형식이고 Prost는 이를 Rust에서 쓰기 위한 도구입니다. |
| 크레이트 / 워크스페이스 | 크레이트는 Rust의 컴파일 단위이며 이 저장소의 Cargo 패키지는 크레이트를 구성합니다. 워크스페이스는 여러 패키지를 함께 관리합니다. |
| Arc | 여러 소유자가 같은 값을 공유하도록 수명을 관리하는 참조 계수 타입입니다. 내용 변경을 자동으로 보호하지는 않습니다. |
| RwLock | 여러 읽기 또는 하나의 쓰기가 들어가도록 접근을 조정하는 잠금입니다. 여기서는 활성 도구 맵 등에 사용합니다. |
| spawn_blocking | 동기식으로 오래 걸릴 수 있는 일을 별도의 작업 스레드에서 수행하도록 넘기는 Tokio 기능입니다. |
| S-expression / AST | 괄호로 중첩한 문서 형식과 그 문서를 나무 구조로 해석한 표현입니다. KiCad 파일 구조를 이해하는 출발점입니다. |
| 원자 교체 | 완성한 임시 파일로 기존 파일을 교체하여 반만 기록된 파일이 보이는 위험을 줄이는 방식입니다. |
| 낙관적 충돌 검사 | 계산하는 동안 오래 잠그는 대신, 저장 직전에 처음 읽은 내용과 여전히 같은지 확인하는 방법입니다. |
| 선행 기록 저널 | 실제 파일을 바꾸기 전에 변경 계획을 먼저 기록하여 중간 종료 뒤에도 복구를 판단하게 하는 장치입니다. |
| 멱등성 | 같은 작업을 반복해도 추가 변화가 생기지 않는 성질입니다. 복구에서 이미 반영된 파일을 다시 건드리지 않는 것이 한 사례입니다. |
| 실행 상태의 권위 | 지금 믿어야 할 설계가 열린 편집기 상태인지 저장된 파일인지 결정하는 기준입니다. |
| 설계 해시 | 파일 내용과 경로로 계산한 식별자입니다. 검사 결과가 어느 설계 버전에 대한 것인지 연결합니다. |
| 결정적 렌더링 | 같은 입력을 같은 조건에서 그리면 같은 결과가 나오게 하는 것입니다. 픽셀 차이 비교의 전제입니다. |
| 디바운스 | 짧은 시간에 반복되는 이벤트를 모아 적절한 때 한 번 처리하는 방식입니다. 파일 저장 도중의 연속 이벤트에 유용합니다. |
| Tauri / PCM | Tauri는 웹뷰와 Rust를 연결하는 데스크톱 앱 도구이고, PCM은 KiCad의 플러그인·콘텐츠 관리자입니다. |
| Specctra DSN / SES | 외부 배선 도구로 설계 정보를 내보내고 결과를 받아오는 교환 형식입니다. 구문 파싱과 안전한 설계 반영은 별도 단계입니다. |
이 용어를 모두 외운 뒤 시작할 필요는 없습니다. 먼저 “도구 요청 → 파일 또는 IPC 변경 → 검증 결과”를 설명해 보고, 막히는 단어만 이 표로 돌아와 확인하면 됩니다.
GitHub 상태 수치는 2026-10-23 기준입니다. 코드 내부의 수치와 동작은 커밋 9488e5f에 고정되어 있습니다. 최근 push 날짜와 분석 대상 커밋 날짜는 서로 다른 범위를 나타냅니다.
| 항목 | 상태 |
|---|---|
| 트렌딩 선정 | GitHub Trending Rust Weekly #4 · 2026-10-23 |
| 스타 / 포크 | 1,375 / 165 |
| 주 언어 | Rust |
| 저장소 생성일 | 2026-07-05 |
| GitHub 최근 push | 2026-10-22 |
| 최신 릴리스 | v0.13.0 · 2026-10-02 |
| 분석 대상 최근 커밋 | 9488e5f · 2026-10-05Merge pull request #835 from neusse/neusse/fix-464-default-unit-pin-layout |
| 소스의 패키지 버전 | 워크스페이스와 별도 뷰어 모두 0.13.0 |
| 코드 규모 | Rust 147파일·170,956줄 / Python 7파일·1,443줄 / Protobuf 12파일·3,370줄 / HTML 1파일·575줄 |
| 집계 기준 | Git 추적 파일의 물리적 줄 수. 테스트·주석·빈 줄 포함. HTML 안의 CSS·JavaScript는 HTML에 포함 |
| 도구 수 | GitHub 소개 217개 / README와 등록부 업무 도구 합계 228개·21묶음 / 관리 도구 별도 |
| KiCad 범위 | PCM 메타데이터 10.0~10.99 선언 / 실제 KiCad 검증 워크플로는 10.0.5 고정 |
| 개발 단계 | README는 beta, PCM 버전 메타데이터는 stable로 표기 |
| 라이선스 | GitHub AGPL-3.0 / Cargo SPDX 표기 AGPL-3.0-only / 별도 상업용 안내 존재 |
시점: 10월 22일 push까지의 모든 변경을 이 문서가 설명하는 것은 아닙니다. 코드 근거는 10월 5일의 커밋에 고정되어 있습니다. 얕은 이력만으로 전체 커밋 수나 기여자 활동을 추정할 수도 없습니다.
완성도: README의 beta와 패키징의 stable 표기는 일치하지 않습니다. 공통 수행 상태 형식도 일부 도구부터 적용 중입니다. konnect-vcs에 기반 코드가 있다는 이유만으로 전체 Git 체크포인트 기능이 완성되었다고 판단해서는 안 됩니다.
검증 범위: 소스와 CI 설정은 설계 의도와 검증 방법의 근거입니다. 실제 설치 성공, 모든 도구의 실행 성공, 성능 수치, 특정 보드의 제조 적합성을 자동으로 입증하지는 않습니다. README의 실행 파일 크기·카탈로그 규모·토큰 수는 문서의 안내 수치입니다.
변경과 검사: 저장 파일과 열린 보드가 다를 수 있고, 일부 작업은 부분 수행이나 불확실 상태를 구분해야 합니다. 복구 가능한 복사본으로 시작하고 결과를 확인하세요. ERC·DRC와 설계 검토 도구가 전원·열·신호 품질 등 모든 공학적 판단을 대신하지는 않습니다.
데이터 경계: 로컬 MCP 서버라고 해서 설계 정보가 어떤 외부 서비스에도 전달되지 않는다는 뜻은 아닙니다. AI 클라이언트·모델 서비스·부품 조회 경로를 함께 확인해야 합니다. 라이선스 적용 조건은 연결된 원문과 상업용 안내를 기준으로 확인하세요.