MagicON RF Design Engines
TX/RX/T-R chains, OTA link, radar, PCB filters, patch antennas, stackup, thermal, PDN, compliance.
Should I use this
Quality & Safety
Findings (1)
- MEDIUMin run_planar_filter
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"magicon": {
"url": "https://api.pcbgenerator.com/mcp/"
}
}
}Remote endpoints
https://api.pcbgenerator.com/mcp/streamable-httpWhat it can do
Tool inventory
Tools (14)
🟢design_rf_chain(frequency, target_output_power, input_power_dbm, application, bandwidth, ...)
Design a complete RF transmitter chain with the convergent orchestrator: selects the driver, PA, filter, and connector (the signal source is the user's input power by default — no VCO unless one is explicitly the generator), matches drive power between stages, inserts a pre-driver or attenuator when needed to reach the target output power, and returns the BOM plus a convergence summary (achieved vs target output). When the BOM's pricingCoverage is 'partial', total_usd is a subtotal of pricedLines of totalLines parts: never call it the total, and state no figure for the unpriced parts.
Input Schema
{
"type": "object",
"properties": {
"frequency": {
"description": "Operating frequency in GHz (scalar).",
"type": "number"
},
"target_output_power": {
"description": "Target transmitter output power in dBm.",
"type": "number"
},
"input_power_dbm": {
"description": "The power the user's radio or signal source delivers into the chain, in dBm (e.g. 0 or -10), ONLY when the user states it. It is the INPUT, never the target output. Omit it when not stated — the result then says which level was assumed.",
"type": "number"
},
"application": {
"description": "Application context (e.g. satcom_c_band, 5g_cellular, wifi_wlan). Defaults to 'general'. For a drone, send the most specific link the user names: drones_digital_video (digital/OFDM video: the PA is judged on LINEAR power), drones_analog_video (analog FM video: saturated power, plus the FCC 15.249 licence note) or drones_control_telemetry; plain 'drones' means the modulation is unknown (the PA is judged on P1dB).",
"type": "string"
},
"bandwidth": {
"description": "Signal bandwidth in MHz (optional).",
"type": "number"
},
"internally_matched_only": {
"description": "Prefer internally 50-ohm matched parts (optional). A preference, not a filter: an unmatched PA can still win on score, and the result's warnings then say so.",
"type": "boolean"
},
"main_board_input_voltage": {
"description": "Board DC supply voltage in volts that the power tree steps down/up to the per-component rails (optional; defaults to 12 V). Set it when the user states their supply rail, e.g. a 28 V or 48 V bench/battery input.",
"type": "number"
},
"input_voltage_min_v": {
"description": "Lowest voltage the board supply reaches, in volts (optional; e.g. a battery at cut-off). Only when the user STATES it — never derive it from a cell count or chemistry. Give it together with input_voltage_max_v and a main_board_input_voltage inside the two; the power tree then picks regulators that work across the whole span.",
"type": "number"
},
"input_voltage_max_v": {
"description": "Highest voltage the board supply reaches, in volts (optional; e.g. a fully charged battery). Only when the user STATES it. Pair with input_voltage_min_v.",
"type": "number"
},
"transmit_duty_cycle_percent": {
"description": "Transmit duty cycle in percent for a PULSED system (radar). Default 100 = continuous wave (CW). Set it to the real duty (e.g. 10 for a 10% radar) so thermal, stress, and compliance use AVERAGE power, not peak.",
"type": "number"
},
"transmit_bias_pulsed": {
"description": "Pulsed designs only: true when the user says the amplifier bias (gate or drain) is switched off between pulses, false when it stays on. Omit when not stated — the idle draw between pulses is then counted as heat.",
"type": "boolean"
},
"region": {
"description": "Target market / regulatory region (e.g. 'USA', 'Europe', 'Global'). Set it when the user states their market so the design-time power clamp can enforce the right limits — an EU/Europe design with a known antenna gain is held to the ETSI e.i.r.p. limit (EN 300 328 / EN 301 893), not just the FCC ISM conducted limit.",
"type": "string"
},
"antenna_gain_dbi": {
"description": "Antenna gain in dBi. Set it when the user states their antenna so an EU/ETSI design can enforce the e.i.r.p. limit at the real gain (conducted ceiling = e.i.r.p. limit − antenna gain); without it the ETSI clamp does NOT engage (no 0 dBi assumption is made in the design).",
"type": "number"
},
"hopping_channels": {
"description": "Drone control/telemetry only: the number of hopping channels the link uses, WHEN THE USER STATES IT. 50 or more lifts the design ceiling from FCC 15.247(b)(2)'s 24 dBm to 30 dBm. Never guess it.",
"type": "integer"
},
"digital_modulation": {
"description": "Drone control/telemetry only: true WHEN THE USER STATES the link uses digital modulation (FCC 15.247(b)(3)), which lifts the 24 dBm ceiling to 30 dBm. Never guess it.",
"type": "boolean"
},
"harmonic_2nd_dbc": {
"description": "The 2nd-harmonic limit at the output in dBc (a negative number, e.g. -40), ONLY when the user states one. The filters after the PA are then chosen and judged against it. Never guess it and never derive it from a regulation.",
"type": "number"
},
"protected_bands": {
"description": "Bands another radio on the same platform listens on (e.g. a drone's GNSS receiver), checked against the filters after the PA. Only when the user asks to protect a band. A cited ITU RNSS band is named by source ('table:rnss_1164_1215', 'table:rnss_1215_1240', 'table:rnss_1240_1300', 'table:rnss_1559_1610', 'table:rnss_5010_5030') and needs no edges; a band the user states uses source 'user' with name, fLowHz and fHighHz. requiredRejectionDb ONLY when the user states it — it narrows the filter choice. Never invent an edge or a requirement.",
"items": {
"properties": {
"source": {
"type": "string"
},
"name": {
"type": "string"
},
"fLowHz": {
"type": "number"
},
"fHighHz": {
"type": "number"
},
"requiredRejectionDb": {
"type": "number"
}
},
"required": [
"source"
],
"type": "object"
},
"type": "array"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
},
"required": [
"frequency",
"target_output_power"
]
}🟢design_rf_receiver(rfFrequencyHz, bandwidthHz, requiredSnrDb, ifHz, loSide, ...)
Design or analyse a superheterodyne RECEIVER. Selects catalog parts for each slot (limiter, LNA, image filter, mixer, LO, IF filter, IF amp, step attenuator) and returns the frequency plan (image, half-IF, LO leakage), the cascaded noise figure, noise floor, MDS, sensitivity, SFDR and dynamic range, plus the ADC interface (sample rate, Nyquist zone, ENOB, jitter limit). Pass rfFrequencyHz to design one; pass stages[] only for a bench receiver the user described with their own numbers.
Input Schema
{
"type": "object",
"properties": {
"rfFrequencyHz": {
"description": "RF centre frequency in Hz (e.g. 9.4e9 for X-band).",
"type": "number"
},
"bandwidthHz": {
"description": "Receiver noise bandwidth in Hz. Required for noise floor, MDS and sensitivity — omit it and those are reported as unavailable rather than assumed.",
"type": "number"
},
"requiredSnrDb": {
"description": "SNR needed at the demodulator, in dB.",
"type": "number"
},
"ifHz": {
"description": "Intermediate frequency in Hz. Omit to let the server choose one and disclose that it did.",
"type": "number"
},
"loSide": {
"description": "LO above or below the RF. Omit to let the server pick.",
"enum": [
"high",
"low"
],
"type": "string"
},
"application": {
"description": "Application context, the same label design_rf_chain takes (e.g. drones, marine_radar, wifi_wlan). Every part is scored for it; free text is resolved to the nearest known label, and one that cannot be resolved is scored as 'general' with a warning saying so. Omit for 'general'.",
"type": "string"
},
"main_board_input_voltage": {
"description": "Board DC supply voltage in volts, the same argument design_rf_chain takes. This tool returns no bill of materials or power tree, so a value given here is reported back as unused rather than applied.",
"type": "number"
},
"architecture": {
"description": "front_end_only for a radio built on an integrated transceiver (drones): selects only limiter, preselector and LNA, ending at the transceiver input. Omit for a full superheterodyne.",
"enum": [
"superheterodyne",
"front_end_only"
],
"type": "string"
},
"transceiverNfDb": {
"description": "The transceiver's own noise figure in dB, front_end_only only. Omit it and system NF, MDS and sensitivity are withheld, never assumed.",
"type": "number"
},
"inputPowerDbm": {
"description": "Signal level at the antenna port, in dBm. Omit for a small-signal reference, which the result discloses.",
"type": "number"
},
"stages": {
"description": "Explicit receive chain, ONLY for a bench receiver the user described with their own numbers. Do not hand-build this from memory — pass rfFrequencyHz instead and let the server select real parts.",
"items": {
"properties": {
"id": {
"type": "string"
},
"role": {
"type": "string"
},
"gainDB": {
"type": "number"
},
"lossDB": {
"type": "number"
},
"nfDB": {
"description": "Noise figure in dB. May be omitted for a passive stage given only a loss: the engine then uses its loss, as for a passive part at 290 K, and says so.",
"type": "number"
},
"oip3Dbm": {
"type": "number"
},
"p1dbDbm": {
"type": "number"
},
"mixerRole": {
"description": "true when this stage is the mixer. This, not role, is what marks a mixer.",
"type": "boolean"
},
"nfSideband": {
"description": "Definition of the mixer's nfDB: 'ssb' (single-sideband) or 'dsb' (double-sideband). Only when the user or datasheet says which, never guessed; without it the result warns that the figure is ambiguous.",
"enum": [
"ssb",
"dsb"
],
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢design_tr_module(frequencyGhz, targetOutputPowerDbm, topology, application, main_board_input_voltage, ...)
Design a T/R (transmit/receive) module that shares ONE antenna between a transmitter and a receiver. Designs both chains through the existing engines, selects the shared front end (a T/R switch, or a circulator with a receive-path limiter), and returns four safety budgets: TX-to-RX isolation against the receiver's damage limit, the receive window left after switching and limiter recovery (with the blind range: the closest echo the receiver can hear), limiter leakage driving the LNA into compression, and transmit power against each part's survivability rating. Pass frequencyGhz and targetOutputPowerDbm to design one; pass txPeakPowerDbm and isolationDb only to check a front end the user already described with their own numbers.
Input Schema
{
"type": "object",
"properties": {
"frequencyGhz": {
"description": "Operating frequency in GHz (e.g. 9.4 for X-band).",
"type": "number"
},
"targetOutputPowerDbm": {
"description": "Transmit output power the chain is designed to, in dBm (20 W = 43 dBm). Required — every safety budget is measured against it and no default is substituted.",
"type": "number"
},
"topology": {
"description": "Shared-antenna element. Omit to use tr_switch, which the result discloses. Choose circulator_limiter for high transmit power — if the stress budget reports over_limit for a switch, re-run with this. switch_and_circulator belongs to architecture array_element only (and is its only topology); any other pairing is refused.",
"enum": [
"tr_switch",
"circulator_limiter",
"switch_and_circulator"
],
"type": "string"
},
"application": {
"description": "Application context, the same label design_rf_chain takes (e.g. drones, marine_radar, wifi_wlan). Every part is scored for it; free text is resolved to the nearest known label, and one that cannot be resolved is scored as 'general' with a warning saying so. Omit for 'general'.",
"type": "string"
},
"main_board_input_voltage": {
"description": "Board DC supply voltage in volts that the power tree steps down/up to the per-component rails (optional; defaults to 12 V). Set it when the user states their supply rail, e.g. a 14.8 V 4S battery or a 28 V bench input. Same meaning as on design_rf_chain.",
"type": "number"
},
"prfHz": {
"description": "Pulse repetition frequency in Hz, for a pulsed system. Omit and the switching/blanking budget is absent, not assumed.",
"type": "number"
},
"pulseWidthS": {
"description": "Transmit pulse width in seconds (e.g. 1e-6).",
"type": "number"
},
"minDetectionRangeM": {
"description": "The closest target the user must detect, in metres, when they state one. Checked against the blind range (pulse width + switch back to receive + limiter recovery). Needs prfHz and pulseWidthS; omit when not stated — no requirement is assumed.",
"type": "number"
},
"minTxToRxIsolationDb": {
"description": "The user's required TX-to-RX isolation in dB (e.g. 40 for '> 40 dB'). Judged against the shared part's own isolation and reported under requirements. Not the same as isolationDb. Omit when not stated.",
"type": "number"
},
"maxUnblankingRecoveryS": {
"description": "The user's maximum unblanking (receiver) recovery time in seconds (e.g. 100e-9 for '< 100 ns'). Judged against the switch back to receive plus limiter recovery. Omit when not stated.",
"type": "number"
},
"maxPulseToPulsePhaseDeg": {
"description": "The user's pulse-to-pulse phase stability requirement in degrees. Not computed; reported as not evaluated with the reason. Omit when not stated.",
"type": "number"
},
"maxPulseToPulseAmplitudeDb": {
"description": "The user's pulse-to-pulse amplitude stability requirement in dB. Not computed; reported as not evaluated with the reason. Omit when not stated.",
"type": "number"
},
"maxTxGainFlatnessDb": {
"description": "The user's transmit gain flatness requirement across the band, in dB. Not computed; reported as not evaluated with the reason. Omit when not stated.",
"type": "number"
},
"transmitDutyCyclePercent": {
"description": "Transmit duty cycle in percent (e.g. 10 for a 10% pulsed radar). Selects each part's PULSED survivability rating instead of its CW rating, which for a limiter is commonly 7 dB higher. Omit for continuous wave — the CW rating is then used, and a part declaring no pulsed rating keeps its CW one with that substitution disclosed. Redundant if prfHz and pulseWidthS are both given, which imply it.",
"type": "number"
},
"transmitBiasPulsed": {
"description": "Pulsed designs only: true when the user says the transmit amplifier bias (gate or drain) is switched off between pulses, false when it stays on. Omit when not stated — the idle draw between pulses is then counted as heat, and the thermal disclosures say so.",
"type": "boolean"
},
"antennaReturnLossDb": {
"description": "Antenna return loss in dB. Without it the antenna-mismatch leakage path assumes a 1.5:1 VSWR (13.98 dB) and says so.",
"type": "number"
},
"bandwidthHz": {
"description": "Receiver noise bandwidth in Hz.",
"type": "number"
},
"requiredSnrDb": {
"description": "SNR needed at the demodulator, in dB.",
"type": "number"
},
"architecture": {
"description": "front_end_only for a radio built on an integrated transceiver (drones): selects only limiter, preselector and LNA, ending at the transceiver input. array_element for ONE element of a phased array, beamformer port to antenna port: phase shifter + step attenuator shared by both paths, a low-power T/R switch and a circulator; requires beamformerDriveDbm. Omit for a full superheterodyne.",
"enum": [
"superheterodyne",
"front_end_only",
"array_element"
],
"type": "string"
},
"transceiverNfDb": {
"description": "The transceiver's own noise figure in dB, front_end_only only. Omit it and system NF, MDS and sensitivity are withheld, never assumed.",
"type": "number"
},
"beamformerDriveDbm": {
"description": "array_element only: the input power at the beamformer port, in dBm, as the user stated it. Required for an array element — never assumed; the tool refuses and names it when absent.",
"type": "number"
},
"beamformerNfDb": {
"description": "array_element only: the beamformer's own noise figure behind the common leg, in dB. Omit it and the system noise figure at the beamformer port is withheld.",
"type": "number"
},
"antennaFilter": {
"description": "array_element only: true to add a shared bandpass filter between the circulator and the antenna, charged to both paths. Off unless the user asks for it.",
"type": "boolean"
},
"txPeakPowerDbm": {
"description": "Peak transmit power AT THE ANTENNA PORT, in dBm. Pass this ONLY to check a front end the user already has — it skips design entirely. To design a module, pass targetOutputPowerDbm instead.",
"type": "number"
},
"isolationDb": {
"description": "Transmit-to-receive isolation in dB, for the explicit-inputs path only.",
"type": "number"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_link_budget(inputPowerDbm, bandwidthHz, requiredSnrDb, stages, user_request)
Compute a cascaded RF link budget. For the chain just designed, call with NO arguments — the server derives stages and input power from the design. Pass stages + inputPowerDbm only for a bench/hypothetical chain. Returns per-stage output power, cumulative gain, Friis cascaded NF, gain-referred reciprocal-sum cascaded OIP3, P1dB headroom warnings, and overall risk. Optionally pass bandwidthHz (and requiredSnrDb) to also get the receiver noise floor, MDS, sensitivity, SFDR, and instantaneous dynamic range.
Input Schema
{
"type": "object",
"properties": {
"inputPowerDbm": {
"description": "Input power into the first stage, in dBm. Omit for a just-designed chain (derived from its power flow).",
"type": "number"
},
"bandwidthHz": {
"description": "Optional receiver noise bandwidth in Hz. When given, the result adds the thermal noise floor, MDS, SFDR, and instantaneous dynamic range (a receiver figure of merit).",
"type": "number"
},
"requiredSnrDb": {
"description": "Optional SNR (dB) required for detection/demod. With bandwidthHz, yields receiver sensitivity = MDS + this SNR.",
"type": "number"
},
"stages": {
"description": "Ordered list of RF stages for a bench/hypothetical chain. Omit for a just-designed chain (derived server-side). Each stage may declare gainDB or lossDB (loss is treated as -|lossDB|), nfDB, oip3Dbm, p1dbDbm, and an authoritative outputPowerDbm that snap-seeds the cascade. Mark a mixer with mixerRole, plus nfSideband when the user or datasheet says which definition its nfDB uses.",
"items": {
"properties": {
"id": {
"type": "string"
},
"gainDB": {
"type": "number"
},
"lossDB": {
"type": "number"
},
"nfDB": {
"description": "Noise figure in dB. May be omitted for a passive stage given only a loss: the engine then uses its loss, as for a passive part at 290 K, and says so.",
"type": "number"
},
"oip3Dbm": {
"type": "number"
},
"p1dbDbm": {
"type": "number"
},
"outputPowerDbm": {
"type": "number"
},
"mixerRole": {
"description": "true when this stage is a mixer.",
"type": "boolean"
},
"nfSideband": {
"description": "Definition of a mixer's nfDB: 'ssb' (single-sideband) or 'dsb' (double-sideband). Only when the user or datasheet says which, never guessed; without it a mixer's result warns that the figure is ambiguous.",
"enum": [
"ssb",
"dsb"
],
"type": "string"
}
},
"type": "object"
},
"type": "array"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_stackup_solver(layer_count, frequency_ghz, impedance_ohms, topology, impedance_targets, ...)
Run the impedance-aware stackup constraint solver to find optimal PCB configurations. Use when the user wants ranked material/thickness/copper solutions for a given layer count and frequency. Returns scored and ranked feasible stackups. Each solution's prepreg_thickness_mm is ONE prepreg layer: prepreg_sheets (1-3) x prepreg_sheet_thickness_mm (maker's table). Per-layer numbers do NOT sum to total_thickness_mm — the total uses the pressed thickness, 0.04064 mm thinner per layer. Report both as returned; never 'correct' one to match the other.
Input Schema
{
"type": "object",
"properties": {
"layer_count": {
"description": "Total copper layers (even number, 2-32)",
"type": "number"
},
"frequency_ghz": {
"description": "Operating frequency in GHz",
"type": "number"
},
"impedance_ohms": {
"description": "Target impedance in Ohms (default 50). Single-target convenience — ignored when impedance_targets is given.",
"type": "number"
},
"topology": {
"description": "Transmission line type: microstrip or stripline (default microstrip)",
"enum": [
"microstrip",
"stripline"
],
"type": "string"
},
"impedance_targets": {
"description": "Up to 4 impedance targets the stackup must satisfy SIMULTANEOUSLY, each {ohms, topology ('microstrip'|'stripline'), differential (bool), spacing_mm (differential pair gap in mm, default 0.15)}. Use for multi-impedance boards — e.g. 50 ohm RF plus a 100 ohm differential pair. Overrides impedance_ohms/topology.",
"items": {
"type": "object"
},
"type": "array"
},
"cost_priority": {
"description": "Cost preference: low, balanced, or performance. Default balanced; an HDI build_type OR a frequency at or above 18 GHz defaults to performance instead, because at mm-wave a balanced weighting ranks an FR4-class laminate above every low-loss one. Pass it explicitly to override either default — a stated preference always wins. The priority actually used comes back as costPriority.",
"enum": [
"low",
"balanced",
"performance"
],
"type": "string"
},
"target_thickness_mils": {
"description": "Board thickness in mils (default 62)",
"type": "number"
},
"thickness_tolerance_mm": {
"description": "Allowed deviation from the target thickness in mm. OMIT it and the solver uses 10% of the target thickness. Set it only when the user states a tolerance. The value the solve used comes back as thicknessToleranceMm - cite that one.",
"type": "number"
},
"allowed_core_materials": {
"description": "Restrict core dielectrics to these catalog materials (e.g. RO4350B, MEGTRON6; 'FR4' = the standard FR-4 grades). Pass ONLY materials the user named; omit for the full catalog.",
"items": {
"type": "string"
},
"type": "array"
},
"allowed_prepreg_materials": {
"description": "Restrict prepregs to these catalog materials (e.g. RO4450F, MEGTRON6; 'FR4' = the standard FR-4 grades). Pass ONLY materials the user named; omit for the full catalog.",
"items": {
"type": "string"
},
"type": "array"
},
"allowed_inner_core_materials": {
"description": "For a HYBRID board (an RF core on the two outer cores, a cheaper laminate on the cores between them): the catalog materials the inner cores may be. Omitted, they are 'FR4' (the standard FR-4 grades). Pass ONLY what the user named for the inner cores; giving it also asks for hybrids.",
"items": {
"type": "string"
},
"type": "array"
},
"build_type": {
"description": "Lamination build: 'single' (default) or HDI level hdi1-hdi4. HDI defaults cost_priority to performance.",
"enum": [
"single",
"hdi1",
"hdi2",
"hdi3",
"hdi4"
],
"type": "string"
},
"construction": {
"description": "Lamination. OMIT it unless the user named one: an omitted lamination is built foil; naming a core material builds core_outer where it can be (4+ layers, build_type 'single'), whatever the frequency. 'foil' puts prepreg outermost, so an outer microstrip rides on prepreg; 'core_outer' puts a core outermost, so the core material, such as an RF laminate, sits directly under the outer microstrip — the same choice Guided Phase IV offers. 'auto' searches BOTH and ranks them together; send it only when the user asks to compare the two. On 6+ layers, naming a core outside the FR-4 grades (e.g. RO4350B) under core_outer ALSO searches hybrid boards: that core on the two outer cores, an FR-4 grade on the cores between (a hybrid solution names its inner_core_material); the other boards have every core that material. No hybrid with a stripline target. Each solution reports the construction it was built as; name it when you cite that solution.",
"enum": [
"foil",
"core_outer",
"auto"
],
"type": "string"
},
"solder_mask": {
"description": "Solder mask covering the OUTER trace, as {thickness_mm, dk}. Mask raises the effective permittivity around the trace and pulls Z0 down, so the solver returns a NARROWER width for the same target impedance. OMIT IT (the default) and the microstrip is solved BARE — pass it only when the user says the outer traces are mask-covered, or states a mask thickness or mask Dk. Applies to microstrip targets only: a stripline is buried under laminate, not mask. Both members are optional and default to typical green LPI (0.02 mm, Dk 3.5); thickness_mm must be over 0 and at most 0.2, dk over 1 and at most 10. Mask LOSS is not modeled: the insertion-loss score leaves it out, and a masked result says so in diagnostics — tell your user when you cite a masked solve.",
"properties": {
"thickness_mm": {
"description": "Cured mask thickness over the conductor in mm (typical LPI 0.015-0.030; default 0.02).",
"type": "number"
},
"dk": {
"description": "Mask dielectric constant (typical green LPI 3.3-3.9; default 3.5).",
"type": "number"
}
},
"type": "object"
},
"reflow_process": {
"description": "Assembly reflow process; enforces a Tg floor on all dielectrics (default lead_free).",
"enum": [
"leaded",
"lead_free"
],
"type": "string"
},
"copper_weight_oz": {
"description": "Restrict solutions to this copper weight in oz (0.5, 1, 2, or 3). Omit to let the solver optimize copper weight; an omitted value inherits the latest update_stackup_config copper weight automatically. The value is the FINISHED thickness, with outer-layer plating already included (1 oz = 0.035 mm finished, plated up from 0.5 oz starting foil). A spec written as '0.5 oz base foil + plating, 1.7 mil finished' uses the OTHER convention — pass 1, not 0.5.",
"type": "number"
},
"max_solutions": {
"description": "Max solutions to return, 1-20 (default 5)",
"type": "number"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
},
"required": [
"layer_count",
"frequency_ghz"
]
}🟢run_thermal_analysis(analysis_input, via_config, stackup_layers, theta_jc_c_per_w, heatsink, ...)
Run a full PCB thermal analysis: via array Rth, junction-to-ambient stack, Kennedy spreading, Coffin-Manson barrel stress, Timoshenko warpage, and resin-flow estimation. Mirrors POST /api/stackups/{id}/thermal-analysis. Call with no arguments once a design exists: the server takes power_w from the designed chain's dissipated power and defaults ambient_c to 25 C. The result carries `recommendations` (thermal vias, copper, plating) — answer adjustment questions from those entries. If the user states a heatsink or airframe spreader, pass `heatsink` (θcs, θsa and mount, all three as stated — never guessed); Tj is then computed through it instead of still-air convection.
Input Schema
{
"type": "object",
"properties": {
"analysis_input": {
"description": "Optional once a design exists. {power_w, ambient_c} are BOTH optional: the server fills power_w from the designed chain's dissipated power and defaults ambient_c to 25 C. Omit this entirely to run thermal on the current design.",
"properties": {
"power_w": {
"type": "number"
},
"ambient_c": {
"type": "number"
}
},
"type": "object"
},
"via_config": {
"description": "Optional thermal via array. ALL SEVEN properties are required together — a partial object is rejected — and plating_thickness_mm must be < via_diameter_mm / 2.",
"properties": {
"via_diameter_mm": {
"description": "Via drill diameter in mm (e.g. 0.3).",
"type": "number"
},
"via_pitch_mm": {
"description": "Center-to-center pitch in mm (e.g. 0.6).",
"type": "number"
},
"via_array_rows": {
"description": "Rows in the via array (e.g. 20).",
"type": "integer"
},
"via_array_cols": {
"description": "Columns in the via array (e.g. 20).",
"type": "integer"
},
"copper_fill": {
"description": "filled (solid copper) or plated (annular ring).",
"enum": [
"filled",
"plated"
],
"type": "string"
},
"plating_thickness_mm": {
"description": "Plating thickness in mm, must be < via_diameter_mm/2 (e.g. 0.025).",
"type": "number"
},
"board_thickness_mm": {
"description": "Total board thickness in mm (e.g. 1.6).",
"type": "number"
}
},
"type": "object"
},
"stackup_layers": {
"description": "Optional per-layer thermal contributions.",
"items": {
"type": "object"
},
"type": "array"
},
"theta_jc_c_per_w": {
"description": "Device junction-to-case thermal resistance in °C/W (datasheet R_θJC). Optional — the server derives it from the designed chain's PA record when available.",
"type": "number"
},
"heatsink": {
"description": "Optional user-STATED heatsink (or drone airframe spreader) the part is mounted to. ALL THREE properties are required together and NONE is ever defaulted — if the user has not stated one, ask; a partial object is rejected naming the missing field. When given it REPLACES still-air convection; the result echoes it with source 'user_supplied' and a heat_path.",
"properties": {
"theta_cs_c_per_w": {
"description": "Case/board-to-sink interface resistance in °C/W (thermal pad, grease or TIM). >= 0; 0 only if stated.",
"type": "number"
},
"theta_sa_c_per_w": {
"description": "Sink-to-ambient resistance in °C/W from the heatsink datasheet or the user. Must be > 0.",
"type": "number"
},
"mount": {
"description": "board: SMT part, heat crosses the PCB vias into the sink under the board. flange: bolt-down part, heat goes straight into the sink, bypassing the PCB.",
"enum": [
"board",
"flange"
],
"type": "string"
}
},
"type": "object"
},
"source_area_mm2": {
"description": "Heat source footprint area in mm² — typically the IC die or package pad footprint. Used for Kennedy spreading resistance.",
"type": "number"
},
"pour_area_mm2": {
"description": "Total copper-pour spreader area in mm² on the heat-sink side; larger pours reduce the spreading-Rth term.",
"type": "number"
},
"copper_thickness_mm": {
"description": "Plane/pour copper thickness in mm (e.g. 0.035 for 1 oz, 0.070 for 2 oz). Drives the lateral spreading conductance.",
"type": "number"
},
"board_length_mm": {
"description": "Overall PCB length in mm — used for Timoshenko warpage and CTE-mismatch curvature estimates.",
"type": "number"
},
"board_width_mm": {
"description": "Overall PCB width in mm (warpage / CTE inputs).",
"type": "number"
},
"copper_coverage_top_pct": {
"description": "Fractional copper coverage on the top side (0–100 %). Used for warpage symmetry and effective-CTE calculations.",
"type": "number"
},
"copper_coverage_bottom_pct": {
"description": "Fractional copper coverage on the bottom side (0–100 %). Asymmetry vs. top drives warpage predictions.",
"type": "number"
},
"layer_count": {
"description": "Total copper layer count (even number, typically 2–32). Used to scale per-layer thermal contributions.",
"type": "integer"
},
"effective_cte_z_ppm": {
"description": "Effective z-axis CTE in ppm/°C — input to Coffin-Manson barrel-stress life estimation. Typical 40–70 ppm/°C for FR4.",
"type": "number"
},
"delta_t_c": {
"description": "Thermal-cycling ΔT in °C for Coffin-Manson fatigue analysis (e.g. 100 °C from −40 to +60 °C operating swing).",
"type": "number"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_pdn_analysis(plane_pairs, decoupling_caps, target, user_request)
Run a PDN (power delivery network) impedance analysis: interplanar plane-pair capacitance, multi-cap decoupling impedance vs. target impedance, violations, and recommended decoupling caps. Reuses the Phase-25 engine behind POST /api/pdn/analyze. Inputs are derived server-side from the solved stackup, the BOM's PDN passives, and the power-tree rail — call with no arguments once a design exists.
Input Schema
{
"type": "object",
"properties": {
"plane_pairs": {
"description": "Optional. Power/ground plane pairs. Derived from the solved stackup when omitted.",
"items": {
"type": "object"
},
"type": "array"
},
"decoupling_caps": {
"description": "Optional. Decoupling capacitors. Derived from the BOM's PDN passive lines when omitted.",
"items": {
"type": "object"
},
"type": "array"
},
"target": {
"description": "Optional target-impedance config {voltage_v, ripple_pct, transient_current_a, rise_time_ns} or {preset_name}. Derived from the power-tree rail when omitted.",
"type": "object"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_compliance_analysis(standards, layers, stackup_config, user_request)
Audit the solved stackup against PCB standards (IPC-2221, IPC-6012, IPC-4101, MIL, UL-94, RoHS, REACH): per-rule pass/fail with severities and remediation. Reuses the engine behind POST /api/compliance/check. Layers are derived from the solved stackup and standards default to IPC-2221 + IPC-6012 Class 2 — call with no arguments once a stackup exists.
Input Schema
{
"type": "object",
"properties": {
"standards": {
"description": "Optional. Standards to check (e.g. IPC_2221, IPC_6012_CLASS3, ROHS_3, ETSI_EN_300_328, ETSI_EN_301_893) or a region name for advisory reference limits (e.g. 'China', 'SRRC', 'Japan', 'Canada'). Defaults to IPC-2221 + IPC-6012 Class 2 when omitted.",
"items": {
"type": "string"
},
"type": "array"
},
"layers": {
"description": "Optional. Stackup layers. Derived from the solved stackup when omitted.",
"items": {
"type": "object"
},
"type": "array"
},
"stackup_config": {
"description": "Optional stackup config (layer_count, total_thickness_mm). Derived when omitted.",
"type": "object"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_ota_link(txPowerDbm, txPowerW, txGainDbi, rxGainDbi, frequencyGhz, ...)
Compute a one-way over-the-air link budget — EIRP, free-space path loss (Friis), received power, link margin against receiver sensitivity, a closes/marginal/fails verdict, and the maximum range — using the SAME engine behind POST /api/ota-link/compute. Receiver sensitivity is reused from a prior link budget and transmit antenna gain/frequency from a prior antenna design when not given. FREE-SPACE ONLY: excludes rain, terrain, multipath and fading beyond the misc-loss and fade-margin inputs. Distance and misc loss are user assumptions, disclosed on the result.
Input Schema
{
"type": "object",
"properties": {
"txPowerDbm": {
"description": "Transmit power in dBm. Use ONLY when the user states dBm; otherwise pass txPowerW. Wins if both are given.",
"type": "number"
},
"txPowerW": {
"description": "Transmit power in WATTS (pass 0.1 for 100 mW). PREFER this for W/mW inputs — the server converts to dBm. Do NOT convert yourself.",
"type": "number"
},
"txGainDbi": {
"description": "Transmit antenna gain (dBi). Reused from a prior patch-antenna design if omitted.",
"type": "number"
},
"rxGainDbi": {
"description": "Receive antenna gain (dBi). Defaults to 0 (isotropic) — pass it when the far-end antenna is known.",
"type": "number"
},
"frequencyGhz": {
"description": "Carrier frequency (GHz). Reused from a prior antenna design if omitted.",
"type": "number"
},
"distanceM": {
"description": "Link distance in METRES (pass 5000 for 5 km). USER ASSUMPTION.",
"type": "number"
},
"miscLossDb": {
"description": "Misc/implementation loss lump (dB): cables, connectors, pointing, polarization. USER ASSUMPTION. Default 0.",
"type": "number"
},
"fadeMarginDb": {
"description": "Fade margin required for the link to count as closing (dB). Default 0.",
"type": "number"
},
"sensitivityDbm": {
"description": "Receiver sensitivity (dBm). Reused from a prior link budget if omitted.",
"type": "number"
},
"rxNfDb": {
"description": "Receiver noise figure (dB) — used to derive sensitivity when none is available.",
"type": "number"
},
"bandwidthHz": {
"description": "Receiver noise bandwidth (Hz) — used to derive sensitivity.",
"type": "number"
},
"requiredSnrDb": {
"description": "Demodulation SNR required (dB) — used to derive sensitivity.",
"type": "number"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_radar_performance(peakPowerW, peakPowerDbm, gainTxDbi, gainRxDbi, frequencyGhz, ...)
Compute radar performance — the monostatic range equation (received power, SNR vs range, maximum detection range, coherent/non-coherent integration gain) and pulsed-waveform relations (duty cycle, unambiguous range/velocity, range resolution, blind speeds) — using the SAME engine behind POST /api/radar/performance. Antenna gain enters as a dBi number; the detection floor is reused from a prior link budget's MDS when not given. RCS, target range, and system loss are user assumptions, disclosed on the result.
Input Schema
{
"type": "object",
"properties": {
"peakPowerW": {
"description": "Transmit peak power in WATTS (pass 1000 for 1 kW). PREFER this for W/kW/MW inputs — the server converts to dBm. Do NOT convert to dBm yourself.",
"type": "number"
},
"peakPowerDbm": {
"description": "Transmit peak power in dBm. Use ONLY when the user states dBm directly; otherwise pass peakPowerW. Wins if both are given.",
"type": "number"
},
"gainTxDbi": {
"description": "Transmit antenna gain (dBi).",
"type": "number"
},
"gainRxDbi": {
"description": "Receive antenna gain (dBi); defaults to gainTxDbi (monostatic).",
"type": "number"
},
"frequencyGhz": {
"description": "Carrier frequency (GHz).",
"type": "number"
},
"rcsM2": {
"description": "Target radar cross-section (m^2). USER ASSUMPTION.",
"type": "number"
},
"targetRangeM": {
"description": "Target range (m). USER ASSUMPTION.",
"type": "number"
},
"systemLossDb": {
"description": "System loss budget (dB). USER ASSUMPTION. Default 0.",
"type": "number"
},
"integrationCount": {
"description": "Pulses integrated (N >= 1). Default 1.",
"type": "integer"
},
"integrationMode": {
"description": "'coherent' (+10log10 N) or 'noncoherent' (~6.5log10 N).",
"type": "string"
},
"requiredSnrDb": {
"description": "Detection SNR (dB) used to solve maximum range.",
"type": "number"
},
"mdsDbm": {
"description": "Detection floor (dBm). Reused from a prior link budget if omitted.",
"type": "number"
},
"prfHz": {
"description": "Pulse repetition frequency (Hz).",
"type": "number"
},
"pulseWidthS": {
"description": "Pulse width tau (s).",
"type": "number"
},
"compressedBandwidthHz": {
"description": "Pulse-compression bandwidth B (Hz); overrides range resolution.",
"type": "number"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢run_planar_filter(filter_class, topology, response, order, ripple_db, ...)
Synthesize a passive planar (copper-on-PCB) filter from analytical formulas: stepped-impedance / open-stub low-pass, or parallel-coupled / hairpin band-pass, Chebyshev or Butterworth. Returns per-section line impedances (Z0e/Z0o for coupled sections), width/spacing, quarter-wave lengths, the total occupied board area, a copper footprint, passband markers, a simulated S21/S11 frequency response (response_curve) with modeled insertion loss / return loss / 3-dB bandwidth (response_summary), and accuracy warnings. Reuses the engine behind POST /api/planar-filter/compute (SSOT). Use it to replace a purchased SMT filter with board copper. Interdigital/combline are not implemented.
Input Schema
{
"type": "object",
"properties": {
"filter_class": {
"description": "Low-pass or band-pass.",
"enum": [
"LPF",
"BPF"
],
"type": "string"
},
"topology": {
"description": "LPF: stepped_impedance or open_stub. BPF: parallel_coupled or hairpin. (interdigital/combline are Tier B — not implemented.)",
"enum": [
"stepped_impedance",
"open_stub",
"parallel_coupled",
"hairpin"
],
"type": "string"
},
"response": {
"description": "Prototype response. chebyshev requires ripple_db.",
"enum": [
"chebyshev",
"butterworth"
],
"type": "string"
},
"order": {
"description": "Filter order N (number of reactive elements), >= 1.",
"type": "integer"
},
"ripple_db": {
"description": "Passband ripple in dB (required for chebyshev).",
"type": "number"
},
"fc_ghz": {
"description": "Cutoff frequency in GHz (LPF only).",
"type": "number"
},
"f0_ghz": {
"description": "Center frequency in GHz (BPF only).",
"type": "number"
},
"fractional_bw": {
"description": "Fractional bandwidth 0<Δ<1 (BPF only), e.g. 0.10 for 10%.",
"type": "number"
},
"z0_ohm": {
"description": "System (port) impedance in ohms, e.g. 50.",
"type": "number"
},
"substrate": {
"description": "PCB substrate. line_topology 'microstrip' or 'stripline'; material (the laminate the user named) or er (only a Dk the user stated); h_mm (microstrip height) or b_mm (stripline plate spacing); optional t_mm (copper thickness), tan_d, fab_min_spacing_mm.",
"properties": {
"line_topology": {
"enum": [
"microstrip",
"stripline"
],
"type": "string"
},
"material": {
"description": "Laminate name, e.g. RO4350B, FR408, FR4. Dk and loss tangent then come from the material catalog at the filter frequency; never pass er from memory.",
"type": "string"
},
"er": {
"type": "number"
},
"h_mm": {
"type": "number"
},
"b_mm": {
"type": "number"
},
"t_mm": {
"type": "number"
},
"tan_d": {
"type": "number"
},
"fab_min_spacing_mm": {
"type": "number"
}
},
"type": "object"
},
"impedance_extremes": {
"description": "Stepped-impedance LPF only: zh_ohm (high-Z line) and zl_ohm (low-Z line). open_stub uses zh_ohm alone.",
"properties": {
"zh_ohm": {
"type": "number"
},
"zl_ohm": {
"type": "number"
}
},
"type": "object"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
},
"required": [
"filter_class",
"topology",
"response",
"order",
"z0_ohm",
"substrate"
]
}🟢design_patch_antenna(frequency_ghz, dk, df, h_mm, material, ...)
Design a rectangular microstrip patch antenna (and, when both nx and ny are given, a uniform planar array of it) using the Balanis cavity/transmission-line + array-factor model — the SAME engine behind POST /api/antenna/patch/design and the Guided Phase IV antenna panel. The substrate (dk/df/h) derives from the latest solved stackup's outer prepreg dielectric unless dk/df/h_mm are given explicitly. Returns patch dimensions, resonance/bandwidth/gain, and (for an array) beamwidths, pattern cuts, and a grating-lobe check. The designed gain auto-applies to the chain's antennaGainDbi (compliance/SAR) unless apply_gain=false.
Input Schema
{
"type": "object",
"properties": {
"frequency_ghz": {
"description": "Target resonant frequency f0 (GHz). Required.",
"type": "number"
},
"dk": {
"description": "Manual substrate dielectric constant override.",
"type": "number"
},
"df": {
"description": "Manual substrate loss tangent override.",
"type": "number"
},
"h_mm": {
"description": "Manual substrate height (mm) override.",
"type": "number"
},
"material": {
"description": "Substrate material NAME the user gave (e.g. 'FR4', 'FR408', 'RO4350B'). The server resolves Dk/Df — the catalog for a branded grade, a nominal value for generic 'FR4' — and assumes a standard thickness, disclosing both. Pass this instead of dk/df when the user names a material rather than numbers; do NOT invent dk/df yourself.",
"type": "string"
},
"nx": {
"description": "Array elements along x (width). Requires ny.",
"type": "integer"
},
"ny": {
"description": "Array elements along y (length). Requires nx.",
"type": "integer"
},
"spacing_lambda": {
"description": "Array element spacing as a fraction of lambda0 (default 0.5).",
"type": "number"
},
"spacing_x_mm": {
"description": "Explicit x-axis element spacing (mm); wins over spacing_lambda.",
"type": "number"
},
"spacing_y_mm": {
"description": "Explicit y-axis element spacing (mm); wins over spacing_lambda.",
"type": "number"
},
"steer_theta_deg": {
"description": "Beam-steer elevation angle (deg), default 0.",
"type": "number"
},
"steer_phi_deg": {
"description": "Beam-steer azimuth angle (deg), default 0.",
"type": "number"
},
"apply_gain": {
"description": "Auto-apply the designed gain to the chain's antennaGainDbi. Default true.",
"type": "boolean"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
},
"required": [
"frequency_ghz"
]
}🟢run_glass_weave_analysis(frequency_ghz, impedance_tolerance_pct, trace_width_mm, is_differential_pair, user_request)
Recommend PCB glass-weave (fiber-weave) styles for the current design: ranks catalogued styles by impedance variation and cost for the design frequency and marks the cheapest one meeting the impedance tolerance. Reuses the Phase-24 engine behind POST /api/glass-weave/recommend. Frequency is derived from the solved stackup / RF specs; tolerance and trace width default to stated assumptions — call with no arguments once a design exists.
Input Schema
{
"type": "object",
"properties": {
"frequency_ghz": {
"description": "Optional. Design frequency in GHz. Derived from the solved stackup / RF specs when omitted.",
"type": "number"
},
"impedance_tolerance_pct": {
"description": "Optional impedance tolerance target in percent (default 5).",
"type": "number"
},
"trace_width_mm": {
"description": "Optional trace width in mm (default 0.1, worst-case narrow).",
"type": "number"
},
"is_differential_pair": {
"description": "Optional. True halves the effective tolerance (differential pairs are more skew-sensitive). Default false.",
"type": "boolean"
},
"user_request": {
"type": "string",
"description": "The end user's own words that prompted this call, verbatim. Used to verify that the figures you pass were stated by your user rather than inferred. Omit it and the results will be labelled caller-asserted.",
"maxLength": 4000
}
}
}🟢check_grounding(text)
Check a draft passage against the engine results computed in THIS session. It returns every figure no engine produced, and every claim it checks that the results do not support or contradict (for example a solver score called a loss), each in `findings` with the reason. Run it before publishing or handing over a report, fabrication sheet, BOM summary or any other figure-bearing deliverable built from these tools. It computes nothing and adds no evidence — it only reports what the results back. Fix each finding the way its `why` says: quote the engine's own value, call the tool that computes it, correct the wording, or say plainly in the text that the figure is not from a tool.
Input Schema
{
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The draft passage to check, verbatim. Pass the prose the end user will actually read — including tables and captions, since a figure in a table is a figure. Markdown is fine.",
"maxLength": 100000
}
},
"required": [
"text"
]
}Community
Evidence