Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .codex/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[mcp_servers.pcb-lens]
command = "npx"
args = ["tsx", "src/index.ts"]
cwd = "/Users/valentino/Developer/IntelligentElectron/pcb-lens"
15 changes: 8 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.8] - 2026-02-27

### Changed

- `query_net` now groups pin connectivity by component refdes (`pins: { [refdes]: string[] }`) to reduce payload size
- `query_net` now omits empty routing/via arrays and zero-value summary fields (`totalSegments`, `totalVias`)
- `query_net` now rejects patterns that match all nets and directs callers to `get_design_overview` for discovery

## [0.0.7] - 2026-02-27

### Fixed
Expand Down Expand Up @@ -82,10 +90,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Test fixture download script for IPC-2581 consortium samples
- Release automation with CI workflows and binary compilation
- Integration tests against IPC-2581 consortium fixtures

[0.0.6]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.6
[0.0.5]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.5
[0.0.4]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.4
[0.0.3]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.3
[0.0.2]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.2
[0.0.1]: https://github.com/IntelligentElectron/pcb-lens/releases/tag/v0.0.1
149 changes: 78 additions & 71 deletions docs/tools/query_net.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# query_net

Query a net by name pattern. Returns connected pins, routing per layer (trace widths, segment counts), and via information.
Query nets by name pattern. Returns grouped connected pins, routing per layer (trace widths, segment counts), via information, and layers used.

## Description

Finds the first net whose name matches the given regex pattern, then collects its full connectivity and routing data. Returns the list of component pins on the net, per-layer routing details (trace widths, segment counts), via usage, and a summary of layers used. Useful for inspecting signal integrity, checking trace widths on critical nets, or understanding how a net is routed across layers.
Finds all nets whose names match the given regex pattern, then collects connectivity and routing data for each match. Pin connectivity is grouped by component refdes to reduce response size. Empty routing/via fields and zero-value summary fields are omitted to keep payloads compact.

If a pattern matches all nets in a design (for example `.`, `.*`, or `.+`), the tool rejects the query and asks for a more specific pattern.

## Input Parameters

Expand All @@ -16,25 +18,25 @@ Finds the first net whose name matches the given regex pattern, then collects it
## Response Schema

```typescript
interface QueryNetsResult {
pattern: string;
units: "MICRON";
matches: QueryNetResult[];
}

interface QueryNetResult {
netName: string;
units: string; // Always "MICRON"
pins: NetPin[];
routing: NetRouteInfo[];
vias: NetViaInfo[];
totalSegments: number;
totalVias: number;
pins: Record<string, string[]>; // { refdes: [pin, ...] }
layersUsed: string[];
}

interface NetPin {
refdes: string;
pin: string;
routing?: NetRouteInfo[]; // omitted when empty
vias?: NetViaInfo[]; // omitted when empty
totalSegments?: number; // omitted when 0
totalVias?: number; // omitted when 0
}

interface NetRouteInfo {
layerName: string;
traceWidths: number[]; // Unique widths in microns
traceWidths: number[]; // Unique widths in microns
segmentCount: number;
}

Expand Down Expand Up @@ -62,92 +64,97 @@ Call:
Response:
```json
{
"netName": "DDR_D0",
"pattern": "^DDR_D0$",
"units": "MICRON",
"pins": [
{ "refdes": "U1", "pin": "A5" },
{ "refdes": "U8", "pin": "D3" }
],
"routing": [
"matches": [
{
"layerName": "SIG1",
"traceWidths": [100],
"segmentCount": 12
"netName": "DDR_D0",
"pins": {
"U1": ["A5"],
"U8": ["D3"]
},
"routing": [
{
"layerName": "SIG1",
"traceWidths": [100],
"segmentCount": 12
}
],
"totalSegments": 12,
"layersUsed": ["SIG1"]
}
],
"vias": [],
"totalSegments": 12,
"totalVias": 0,
"layersUsed": ["SIG1"]
]
}
```

**Query a power net:**

Call:
Response:
```json
{
"tool": "query_net",
"arguments": {
"file": "/designs/motherboard_ipc2581.xml",
"pattern": "^VCC_3V3$"
}
"pattern": "^VCC_3V3$",
"units": "MICRON",
"matches": [
{
"netName": "VCC_3V3",
"pins": {
"C1": ["1"],
"C2": ["1"],
"C3": ["1"],
"L1": ["2"],
"U1": ["B2", "C7"]
},
"routing": [
{
"layerName": "TOP",
"traceWidths": [200, 300],
"segmentCount": 28
},
{
"layerName": "PWR",
"traceWidths": [500],
"segmentCount": 45
}
],
"vias": [
{ "padstackRef": "VIA_0.3mm", "count": 8 }
],
"totalSegments": 73,
"totalVias": 8,
"layersUsed": ["PWR", "TOP"]
}
]
}
```

Response:
**No match:**
```json
{
"netName": "VCC_3V3",
"pattern": "^MISSING_NET$",
"units": "MICRON",
"pins": [
{ "refdes": "U1", "pin": "B2" },
{ "refdes": "U1", "pin": "C7" },
{ "refdes": "C1", "pin": "1" },
{ "refdes": "C2", "pin": "1" },
{ "refdes": "C3", "pin": "1" },
{ "refdes": "L1", "pin": "2" }
],
"routing": [
{
"layerName": "TOP",
"traceWidths": [200, 300],
"segmentCount": 28
},
{
"layerName": "PWR",
"traceWidths": [500],
"segmentCount": 45
}
],
"vias": [
{ "padstackRef": "VIA_0.3mm", "count": 8 }
],
"totalSegments": 73,
"totalVias": 8,
"layersUsed": ["TOP", "PWR"]
"matches": []
}
```

**No match:**
**Error (pattern matches all nets):**
```json
{
"error": "No net matching pattern '^MISSING_NET$' found"
"error": "Pattern '.*' matches all 307 physical nets. Use a more specific pattern, or use get_design_overview for net counts and discovery."
}
```

**Error (invalid regex):**
```json
{
"error": "Invalid regex pattern: ^VCC[+"
"error": "Invalid regex pattern: '^VCC[+'"
}
```

## Notes

- Matches the **first** net whose name matches the regex; use an anchored pattern like `^DDR_D0$` for exact matches
- Uses three passes: (1) find the matching net name, (2) build a LineDesc dictionary for trace width resolution, (3) collect pins, routing, and vias from LayerFeature sections
- Reference layers (REF-route, REF-both) are skipped to avoid counting template geometry
- `traceWidths` contains unique widths found on that layer (not per-segment)
- All widths are in microns
- `layersUsed` is a flat list of all layers where the net has routing
- Returns all matching nets, sorted by net name
- Uses three passes: (1) match nets and collect LogicalNet/PhyNet data, (2) build a LineDesc dictionary, (3) collect routing and vias from LayerFeature sections
- Reference layers (`REF-route`, `REF-both`) are skipped to avoid counting template geometry
- `traceWidths` contains unique widths found on each layer (not one entry per segment)
- All physical values are normalized to microns
- `layersUsed` merges layers from PhyNet points and routing geometry
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@intelligentelectron/pcb-lens",
"version": "0.0.7",
"version": "0.0.8",
"description": "MCP server for IPC-2581 PCB layout analysis and review",
"type": "module",
"main": "dist/index.js",
Expand Down
10 changes: 5 additions & 5 deletions src/tools/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ export interface RenderNetResult {
*/
export interface QueryNetResult {
netName: string;
pins: NetPin[];
routing: NetRouteInfo[];
vias: NetViaInfo[];
totalSegments: number;
totalVias: number;
pins: Record<string, string[]>;
routing?: NetRouteInfo[];
vias?: NetViaInfo[];
totalSegments?: number;
totalVias?: number;
layersUsed: string[];
}

Expand Down
Loading