{"id":924,"date":"2026-04-07T13:05:53","date_gmt":"2026-04-07T04:05:53","guid":{"rendered":"https:\/\/kitag.issp.u-tokyo.ac.jp\/?p=924"},"modified":"2026-04-17T21:30:57","modified_gmt":"2026-04-17T12:30:57","slug":"%e8%87%aa%e5%8b%95%e5%8c%96%e5%af%be%e5%bf%9c%e6%b8%ac%e5%ae%9a%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0kame","status":"publish","type":"post","link":"https:\/\/kitag.issp.u-tokyo.ac.jp\/en\/%e8%87%aa%e5%8b%95%e5%8c%96%e5%af%be%e5%bf%9c%e6%b8%ac%e5%ae%9a%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0kame\/","title":{"rendered":"KAME, AI-assisted automation program for physical property measurements"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large is-resized\"><a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"663\" src=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-1024x663.png\" alt=\"\" class=\"wp-image-495\" style=\"width:640px\" srcset=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-1024x663.png 1024w, https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-600x388.png 600w, https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-768x497.png 768w, https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-1536x994.png 1536w, https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/wp-content\/uploads\/2025\/01\/dd21dff192ba7bde3beb0830a80d886c-2048x1326.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/screenshot-4.jpg\" alt=\"\"><a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/screenshot-4-l.jpg\">&nbsp;<\/a><img decoding=\"async\" src=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/screenshot-7.jpg\" alt=\"\"><a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/screenshot-7-l.jpg\">&nbsp;<\/a><br>KAME is an open-source, multi-threaded framework for automated physical property measurements, developed at&nbsp;<a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/\">Kitagawa Laboratory, ISSP, University of Tokyo<\/a>. It is particularly suited to NMR and ODMR experiments, and supports flexible measurement orchestration across compatible instruments without custom programming.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>License:<\/strong>&nbsp;GPL v2 or later&nbsp;<strong>Authors:<\/strong>&nbsp;Kentaro Kitagawa, Shota Suetsugu&nbsp;<strong>Platforms:<\/strong>&nbsp;macOS, Windows (64-bit); Linux support discontinued&nbsp;<strong>Manual:<\/strong>&nbsp;<a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/%e8%87%aa%e5%8b%95%e5%8c%96%e5%af%be%e5%bf%9c%e6%b8%ac%e5%ae%9a%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0kame\/\">\u65e5\u672c\u8a9e<\/a>&nbsp;\u00b7&nbsp;<a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/kame-7-en.pdf\">English<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Features<a href=\"https:\/\/github.com\/northriv\/KAME#features\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Calibration curves (cspline, Chebyshev, polynomial) for resistance thermometers and generic sensors; calibrated entries feed into graphs, charts, and data recording like any native scalar<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Transactional, lock-free node\/data model (Software Transactional Memory)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Python (+Jupyter notebook) and Ruby scripting \u2014 nearly full control from scripts<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>AI-assisted experiment automation via&nbsp;<a href=\"https:\/\/modelcontextprotocol.io\/\">MCP<\/a><\/strong>&nbsp;\u2014 Claude and other AI assistants can read instruments, control parameters, and run measurement sequences through natural language<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">OpenGL-based 2-D \/ 1-D graph display; arbitrary scalar combinations (T, V, \u2026)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Real-time NMR relaxation fitting (T1, T2, Tst.e.), Inverse Laplace Transform<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fourier step-sum spectrum measurement with field \/ frequency sweeping<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Complete data logging with post-measurement re-analysis<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Save \/ restore full measurement state to&nbsp;<code>.kam<\/code>&nbsp;files<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modular driver plug-in architecture; Python drivers redefinable at runtime<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Codes\/Binaries<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Source here: <a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/src\/kame-8.0.zip\">kame-8.1<\/a>.zip\u00a0(2.2MB, Apr. 14, 2026).<\/li>\n\n\n\n<li>All other source zips <a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/src\">here<\/a>. Git repositry here in <a href=\"http:\/\/github.com\/northriv\/KAME\">GitHub<\/a>.<\/li>\n\n\n\n<li>Windows 64bit binaries: <a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/src\/kame-win32-llvm64-8.0.zip\">8.1<\/a>, <a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/web\/kame\/src\/kame-win32-llvm64-7.7.2.zip\">7.8<\/a>. At least Qt is additionally needed, follow instructions below to install.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Supported instruments<a href=\"https:\/\/github.com\/northriv\/KAME#supported-instruments\"><\/a><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Category<\/th><th>Models<\/th><\/tr><\/thead><tbody><tr><td><strong>Oscilloscopes (DSO)<\/strong><\/td><td>Tektronix TDS, Lecroy\/Teledyne\/Iwatsu, Thamway PROT3 streaming DSO, Thamway DV14U25 A\/D board, NI-DAQmx as DSO, Digilent WaveForms AIN<\/td><\/tr><tr><td><strong>Signal generators<\/strong><\/td><td>Kenwood SG7130\/7200, HP\/Agilent 8643\/8644\/8648\/8664\/8665, Keysight\/Agilent E44xB SCPI, Rohde-Schwarz SML01\/02\/03\/SMV03, DSTech DPL-3.2XGF, LibreVNA SG SCPI<\/td><\/tr><tr><td><strong>Function \/ pulse generators<\/strong><\/td><td>NF WAVE-FACTORY, LXI 3390 arbitrary function generator<\/td><\/tr><tr><td><strong>Network analysers<\/strong><\/td><td>HP\/Agilent 8711\/8712\/8713\/8714, Agilent E5061\/E5062, Copper Mountain TR1300\/1504\/4530, DG8SAQ VNWA3E, LibreVNA SCPI, Thamway T300-1049A impedance analyser<\/td><\/tr><tr><td><strong>Lock-in amplifiers \/ bridges<\/strong><\/td><td>Stanford SR830, NF LI5640, Signal Recovery 7265, LakeShore M81-SSM, Agilent\/HP 4284A LCR meter, Andeen-Hagerling 2500A capacitance bridge<\/td><\/tr><tr><td><strong>DC sources<\/strong><\/td><td>Yokogawa 7651, Advantest TR6142\/R6142\/R6144, MICROTASK\/Leiden triple current source, Optotune ICC4C-2000<\/td><\/tr><tr><td><strong>Multimeters \/ picoammeters<\/strong><\/td><td>Keithley 2000\/2001, 2182 nanovolt meter, 2700+7700, 6482 picoammeter; Agilent 34420A, 3458A, 3478A; Sanwa PC500\/5000<\/td><\/tr><tr><td><strong>Temperature controllers<\/strong><\/td><td>Cryocon M32\/M62, LakeShore 218\/340\/350\/370\/372 (1ch, 8ch, 16ch scanner), Picowatt AVS-47, Oxford ITC-503, Neocera LTC-21, Scientific Instruments 9302\/9304\/9308, LinearResearch LR-700, OMRON E5*C Modbus<\/td><\/tr><tr><td><strong>Magnet power supplies<\/strong><\/td><td>Oxford PS-120, Oxford IPS-120, Cryogenic SMS10\/30\/120C<\/td><\/tr><tr><td><strong>NMR pulsers<\/strong><\/td><td>Thamway N210-1026 PG32U40 (USB), PG027QAM (USB), N210-1026S\/T (GPIB\/TCP); NI-DAQ analog+digital output, digital output only, M+S Series; handmade H8, handmade SH2<\/td><\/tr><tr><td><strong>NMR \/ RF measurement<\/strong><\/td><td>Thamway PROT NMR (USB\/TCP), NMR FID\/echo analyser, T1\/T2 relaxation, field-swept spectrum, frequency-swept spectrum, NMR built-in network analyser, NMR LC autotuner<\/td><\/tr><tr><td><strong>Cameras \/ imaging<\/strong><\/td><td>IEEE 1394 IIDC, Euresys eGrabber (CoaXPress), Euresys Grablink (CameraLink), Hamamatsu via Grablink, JAI via Grablink, OceanOptics\/Insight USB\/HR2000+\/4000 spectrometer<\/td><\/tr><tr><td><strong>Laser modules<\/strong><\/td><td>Coherent Stingray, Newport\/ILX LDX-3200, Newport\/ILX LDC-3700(C)<\/td><\/tr><tr><td><strong>ODMR<\/strong><\/td><td>Frequency-swept spectrum, FM peak tracker, 2-D image analysis, filter wheel (STM-driven)<\/td><\/tr><tr><td><strong>Motors \/ positioners<\/strong><\/td><td>OrientalMotor FLEX CRK, CVD2B, CVD5B, FLEX AR\/DG2, EMP401; SigmaOptics PAMC-104 piezo-assisted; Micro CAM z\/x\/\u03c6; Two-axis rotator<\/td><\/tr><tr><td><strong>Flow controllers<\/strong><\/td><td>Fujikin FCST1000 series<\/td><\/tr><tr><td><strong>Level meters<\/strong><\/td><td>Oxford ILM helium level meter, Cryomagnetics LM-500<\/td><\/tr><tr><td><strong>Vacuum gauges<\/strong><\/td><td>Pfeiffer TPG361\/362<\/td><\/tr><tr><td><strong>Pump controllers<\/strong><\/td><td>Pfeiffer TC110 turbopump controller<\/td><\/tr><tr><td><strong>Counters<\/strong><\/td><td>Mutoh Digital Counter NPS<\/td><\/tr><tr><td><strong>Quantum Design PPMS<\/strong><\/td><td>PPMS low-level interface<\/td><\/tr><tr><td><strong>NI DAQmx<\/strong><\/td><td>Pulser (AO+DO, DO-only, M+S Series), DSO<\/td><\/tr><tr><td><strong>Resistance measurement<\/strong><\/td><td>Four-terminal with polarity switching; Python-based 4-terminal (simple and multi-current variants)<\/td><\/tr><tr><td><strong>Monte Carlo simulation<\/strong><\/td><td>Monte Carlo driver<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s New in 8.0<a href=\"https:\/\/github.com\/northriv\/KAME#whats-new-in-80\"><\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>MCP server for AI-assisted experiment automation<\/strong>&nbsp;\u2014 built-in&nbsp;<a href=\"https:\/\/modelcontextprotocol.io\/\">Model Context Protocol<\/a>&nbsp;server lets AI assistants (Claude Code, Claude Desktop, etc.) execute Python code in the running KAME process, read instrument values, and control measurements through natural language. Matplotlib plots are returned inline. Long-running experiments (sweeps, scans) run asynchronously. To our knowledge, this is the first measurement software to integrate an MCP server.<\/li>\n\n\n\n<li><strong>Calibrated scalar entries<\/strong>&nbsp;\u2014&nbsp;<code>XCalibratedEntry<\/code>&nbsp;applies a calibration curve to any scalar entry; the result appears in graphs, charts, and data recording like a native scalar.<\/li>\n\n\n\n<li><strong>Usermode NI USB-GPIB on Apple Silicon<\/strong>&nbsp;\u2014 the embedded userspace linux-gpib port now works reliably on macOS ARM64 without any kernel module.<\/li>\n\n\n\n<li><strong>Window cascade placement<\/strong>&nbsp;\u2014 instrument windows are automatically arranged on show.<\/li>\n\n\n\n<li><strong>Comprehensive bug audit<\/strong>&nbsp;\u2014 20 bug fixes across 12 source files (GIL safety, buffer bounds, null-pointer guards, logic errors).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture<a href=\"https:\/\/github.com\/northriv\/KAME#architecture\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Driver \/ Plug-in Architecture<a href=\"https:\/\/github.com\/northriv\/KAME#driver--plug-in-architecture\"><\/a><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Instrument drivers are&nbsp;<strong>shared libraries<\/strong>&nbsp;under&nbsp;<code>modules\/<\/code>&nbsp;loaded at runtime via&nbsp;<code>ltdl<\/code>. Each driver subclasses&nbsp;<code>XDriver<\/code>&nbsp;(<code>kame\/driver\/driver.h<\/code>), which carries a timestamped&nbsp;<code>Payload<\/code>&nbsp;(<code>time()<\/code>&nbsp;= phenomenon time,&nbsp;<code>timeAwared()<\/code>&nbsp;= operator-visible time) and emits&nbsp;<code>onRecord<\/code>&nbsp;\/&nbsp;<code>onVisualization<\/code>&nbsp;signals.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hardware communication is abstracted in&nbsp;<code>modules\/charinterface\/<\/code>&nbsp;(serial, TCP, GPIB, USB). Drivers can also be subclassed in Python via&nbsp;<code>XPythonDriver<\/code>&nbsp;(<code>kame\/driver\/pythondriver.h<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scalar values extracted from driver records are represented as&nbsp;<code>XScalarEntry<\/code>&nbsp;objects (<code>kame\/analyzer\/<\/code>). A derived&nbsp;<code>XCalibratedEntry<\/code>&nbsp;applies any registered calibration curve to an existing entry, and the result appears in graphs, charts, and data recording exactly like a native scalar. Calibration curves (<code>kame\/thermometer\/<\/code>) include cubic spline (<code>XApproxThermometer<\/code>,&nbsp;<code>XGenericCalibration<\/code>), Chebyshev polynomial (<code>XLakeShore<\/code>), and polynomial (<code>XScientificInstruments<\/code>) types.&nbsp;<code>XGenericCalibration<\/code>&nbsp;supports user-configured labels and units, making it applicable to any sensor, not just thermometers.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Usermode NI USB-GPIB<a href=\"https:\/\/github.com\/northriv\/KAME#usermode-ni-usb-gpib\"><\/a><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><code>modules\/charinterface\/usermode-linux-gpib\/<\/code>&nbsp;contains a userspace port of the NI USB-GPIB kernel driver from linux-gpib 4.3.6. The upstream&nbsp;<code>ni_usb_gpib.c<\/code>&nbsp;is minimally patched (Linux-only headers guarded with&nbsp;<code>#ifdef __KERNEL__<\/code>); a compatibility header (<code>osx_compat.h<\/code>&nbsp;\/&nbsp;<code>win_compat.h<\/code>) replaces every Linux kernel API \u2014&nbsp;<code>kmalloc<\/code>, spinlocks, wait queues, USB URBs \u2014 with POSIX\/libusb or Win32 equivalents.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The result is a standalone executable that speaks to NI USB-B, USB-HS, USB-HS+, KUSB-488A, and MC USB-488 adapters on macOS, Linux, and Windows without installing a kernel module or any proprietary driver. On macOS this is the only viable path for USB-GPIB on Apple Silicon.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Python Integration<a href=\"https:\/\/github.com\/northriv\/KAME#python-integration\"><\/a><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><em>This section was written by Claude (Anthropic) based on analysis of the source code.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Python access is provided via&nbsp;<a href=\"https:\/\/pybind11.readthedocs.io\/\">pybind11<\/a>. The embedded interpreter runs in its own OS thread; the Qt main thread and the Python thread communicate through the Talker\/Listener signal mechanism.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Accessing the node tree from Python:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root = Root()                      # root of the instrument node tree\n\n# Read a value (Snapshot)\nshot = Snapshot(root)\nprint(shot[root])                  # payload of the root node\n\n# Navigate children\ntempcontrol = root[\"tempcontrol\"]  # by name\nprint(float(tempcontrol[\"temp\"]))  # XDoubleNode coerces to float\n\n# Write a value (Transaction)\nfor tr in Transaction(tempcontrol[\"setpoint\"]):\n    tr[tempcontrol[\"setpoint\"]] = 4.2   # retry loop, just like C++<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Writing instrument drivers in Python:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Any C++ driver base class can be subclassed in Python via&nbsp;<code>XPythonDriver&lt;T&gt;<\/code>. The subclass is registered at runtime with&nbsp;<code>exportClass()<\/code>&nbsp;and instantiated by the framework exactly like a compiled driver. This enables rapid prototyping of new instrument interfaces without recompiling KAME.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class MyDriver(kame.XPythonCharDeviceDriverWithThread):\n    def analyzeRaw(self, reader, payload):\n        payload.local()[\"value\"] = float(reader.pop_string())\n    def visualize(self, shot):\n        ...\nMyDriver.exportClass(\"MyDriver\", MyDriver, \"My Instrument\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The driver&#8217;s&nbsp;<code>Payload.local()<\/code>&nbsp;dict is deep-copied per transaction, giving Python state the same snapshot-isolation semantics as C++ Payload fields.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Jupyter notebook support:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">KAME optionally embeds an IPython kernel. When IPython is available, a Jupyter client can connect to the running process for interactive exploration and live plotting alongside the native KAME UI. The kernel integrates with the asyncio event loop via a custom ipykernel integration (<code>loop_kamepysupport<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>AI-assisted experiment automation (MCP):<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">KAME includes an&nbsp;<a href=\"https:\/\/modelcontextprotocol.io\/\">MCP<\/a>&nbsp;(Model Context Protocol) server that lets AI assistants such as Claude execute Python code directly in the running KAME interpreter. The MCP server connects to the embedded IPython kernel, giving the AI full access to&nbsp;<code>Root()<\/code>,&nbsp;<code>Snapshot()<\/code>,&nbsp;<code>Transaction()<\/code>, and all loaded drivers \u2014 the same environment available in Jupyter notebooks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This enables scenarios like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Conversational experiment control (&#8220;sweep temperature from 100 K to 300 K and record resistance&#8221;)<\/li>\n\n\n\n<li>Automated data collection with adaptive logic<\/li>\n\n\n\n<li>Real-time monitoring and analysis<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">See&nbsp;<a href=\"https:\/\/github.com\/northriv\/KAME#mcp-setup-ai-assisted-experiment-automation\">MCP setup<\/a>&nbsp;below for configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Threading notes:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Long-running C++ calls release the GIL (<code>gil_scoped_release<\/code>) so the Python thread does not block Qt.<\/li>\n\n\n\n<li>Any Qt UI operation (loading&nbsp;<code>.ui<\/code>&nbsp;files, showing forms) must be dispatched to the main thread via&nbsp;<code>kame.kame_mainthread(closure)<\/code>.<\/li>\n\n\n\n<li>Payload garbage collection uses a deferred deque + mutex to avoid holding the GIL during snapshot cleanup (GIL-enabled builds only); Python 3.13 free-threading (<code>Py_GIL_DISABLED<\/code>) is also supported.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Serialization (<code>.kam<\/code>&nbsp;files)<a href=\"https:\/\/github.com\/northriv\/KAME#serialization-kam-files\"><\/a><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<code>.kam<\/code>&nbsp;file is a Ruby script generated by&nbsp;<code>XRubyWriter<\/code>&nbsp;and re-executed on load. Nodes marked&nbsp;<code>runtime=true<\/code>&nbsp;are written as comments and not restored.&nbsp;<code>XListNode<\/code>&nbsp;children are recreated via&nbsp;<code>createByTypename()<\/code>; the typename must match the key registered in&nbsp;<code>XTypeHolder<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Software Transactional Memory (STM)<a href=\"https:\/\/github.com\/northriv\/KAME#software-transactional-memory-stm\"><\/a><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">KAME&#8217;s core data model is a lock-free, snapshot-based STM (<code>kame\/transaction.h<\/code>). All instrument data lives in a tree of&nbsp;<code>Node&lt;XN&gt;<\/code>&nbsp;objects; reads and writes are expressed as&nbsp;<strong>snapshots<\/strong>&nbsp;and&nbsp;<strong>transactions<\/strong>&nbsp;rather than locks.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Node&lt;XN&gt;\n \u2514\u2500 Linkage  \u2500\u2500atomic_shared_ptr\u2500\u2500\u25b6  PacketWrapper\n                                          \u2514\u2500 Packet\n                                              \u251c\u2500 Payload   (user data)\n                                              \u2514\u2500 PacketList (child packets)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Reading \u2014 O(1) snapshot:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Snapshot&lt;NodeA&gt; shot(node);         \/\/ atomic load, no lock\ndouble x = shot[node].m_x;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Writing \u2014 optimistic transaction with automatic retry:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">node.iterate_commit([](Transaction&lt;NodeA&gt; &amp;tr) {\n    tr[node].m_x += 1;             \/\/ copy-on-write on first access\n});                                 \/\/ retried automatically on conflict<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How commits work:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>Transaction<\/code>&nbsp;saves&nbsp;<code>m_oldpacket<\/code>&nbsp;at construction.<\/li>\n\n\n\n<li><code>operator[]<\/code>&nbsp;clones the payload (copy-on-write) on first write, stamping it with a unique serial.<\/li>\n\n\n\n<li><code>commit()<\/code>&nbsp;does a single CAS on&nbsp;<code>Linkage<\/code>; if&nbsp;<code>packet != m_oldpacket<\/code>&nbsp;a conflict is detected and the transaction retries.<\/li>\n\n\n\n<li>Listeners receive deferred events only after a successful commit \u2014 no intermediate states are visible.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Lock-free atomic shared pointer<a href=\"https:\/\/github.com\/northriv\/KAME#lock-free-atomic-shared-pointer\"><\/a><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The O(1) snapshot reads and CAS-based commits above require a shared pointer that is itself lock-free.&nbsp;<code>atomic_shared_ptr<\/code>&nbsp;(in&nbsp;<code>kame\/atomic_smart_ptr.h<\/code>, introduced in January 2006 as part of the 2.0-beta3 rewrite) provides this. It is a custom implementation of what C++20 calls&nbsp;<code>std::atomic&lt;shared_ptr&gt;<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The core technique embeds a small&nbsp;<strong>local reference counter<\/strong>&nbsp;in the low bits of the pointer to the reference-control block \u2014 bits guaranteed zero by allocator alignment.&nbsp;<code>acquire_tag_ref_()<\/code>&nbsp;atomically increments this local counter via CAS to &#8220;pin&#8221; the pointer for reading;&nbsp;<code>release_tag_ref_()<\/code>&nbsp;decrements it. Between these two calls, even if another thread swaps the pointer, the object cannot be freed because the local count is non-zero. A separate&nbsp;<strong>global reference counter<\/strong>&nbsp;in the control block tracks long-lived ownership (copies held across scopes). Setters transfer any outstanding local count to the global counter before swapping, so&nbsp;<code>release_tag_ref_()<\/code>&nbsp;can fall back to decrementing the global counter if the pointer changed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For types that inherit&nbsp;<code>atomic_countable<\/code>&nbsp;(notably&nbsp;<code>Payload<\/code>), the global reference counter is stored inside the object itself (<strong>intrusive counting<\/strong>), eliminating a separate heap allocation per shared-pointer instance. Non-intrusive types get an external control block (<code>atomic_shared_ptr_gref_<\/code>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Comparison with standard-library implementations (as of late 2024):<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Implementation<\/th><th>Technique<\/th><th>Lock-free?<\/th><\/tr><\/thead><tbody><tr><td>libstdc++ (GCC)<\/td><td>Spinlock on internal table<\/td><td>No \u2014 vulnerable to priority inversion<\/td><\/tr><tr><td>MSVC<\/td><td>Lock bit +&nbsp;<code>WaitOnAddress<\/code><\/td><td>No \u2014 blocking under contention<\/td><\/tr><tr><td>libc++ (Clang)<\/td><td>Not yet implemented<\/td><td>N\/A<\/td><\/tr><tr><td>KAME (2006\u2013)<\/td><td>Tagged-pointer CAS<\/td><td>Yes \u2014 lock-free reads and writes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">On modern compilers (GCC 5.1+, Clang, MSVC), the CAS primitives delegate to&nbsp;<code>std::atomic<\/code>&nbsp;(<code>atomic_prv_std.h<\/code>). Hand-written assembly fallbacks for x86, PowerPC, and ARM remain in the tree for older toolchains.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Multi-node consistency<\/strong>&nbsp;is achieved through a&nbsp;<em>bundling<\/em>&nbsp;protocol: a parent packet absorbs child packets via multi-phase CAS protocol, making the entire subtree consistent under a single atomic pointer. A&nbsp;<code>m_missing<\/code>&nbsp;flag marks packets with stale children, driving re-bundling on demand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Collision backoff:<\/strong>&nbsp;<code>Linkage::negotiate()<\/code>&nbsp;uses a&nbsp;<code>m_transaction_started_time<\/code>&nbsp;timestamp to impose a proportional wait on detected collisions, preventing live-lock under high write contention.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>iterate_commit_while(lambda)<\/code>&nbsp;lets the caller abort the retry loop (return&nbsp;<code>false<\/code>&nbsp;from the lambda to stop), enabling conditional transactions.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Caution:<\/strong>&nbsp;Taking a nested&nbsp;<code>Snapshot<\/code>&nbsp;inside a transaction on a tree that contains a hard link (a child with two parents) can break consistency. Use&nbsp;<code>tr[*node]<\/code>&nbsp;instead of a nested&nbsp;<code>Snapshot<\/code>&nbsp;in that situation.<\/p>\n<\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\">Comparison with other STM designs<a href=\"https:\/\/github.com\/northriv\/KAME#comparison-with-other-stm-designs\"><\/a><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The following comparison was written by Claude (Anthropic) based on analysis of the source code.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Most widely-used STMs (GHC\/Haskell&nbsp;<code>TVar<\/code>, Clojure&nbsp;<code>Ref<\/code>\/<code>dosync<\/code>, ScalaSTM) are&nbsp;<strong>flat<\/strong>: the unit of transaction is a set of independent transactional variables. KAME&#8217;s STM is instead&nbsp;<strong>tree-structured<\/strong>&nbsp;\u2014 the entire instrument node tree is the shared state, and snapshots are always subtree-consistent. This difference drives several design choices:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Aspect<\/th><th>Flat STMs (Haskell, Clojure, ScalaSTM)<\/th><th>KAME STM<\/th><\/tr><\/thead><tbody><tr><td>Conflict granularity<\/td><td>Per-variable<\/td><td>Per-packet (subtree root)<\/td><\/tr><tr><td>Read model<\/td><td><code>readTVar<\/code>&nbsp;\/&nbsp;<code>deref<\/code>&nbsp;inside transaction<\/td><td><code>Snapshot<\/code>&nbsp;(outside) or&nbsp;<code>tr[*node]<\/code>&nbsp;(inside)<\/td><\/tr><tr><td>Consistency scope<\/td><td>Variables listed explicitly<\/td><td>Entire subtree, guaranteed by bundling<\/td><\/tr><tr><td>Commit log<\/td><td>Redo log or write set<\/td><td>Copy-on-write + CAS on single&nbsp;<code>Linkage<\/code><\/td><\/tr><tr><td>Retry primitive<\/td><td><code>retry<\/code>&nbsp;\/&nbsp;<code>orElse<\/code>&nbsp;(Haskell)<\/td><td><code>iterate_commit<\/code>&nbsp;\/&nbsp;<code>iterate_commit_while<\/code><\/td><\/tr><tr><td>Blocking<\/td><td><code>retry<\/code>&nbsp;suspends on read-set change<\/td><td>No blocking; backoff via timestamp<\/td><\/tr><tr><td>Memory management<\/td><td>GC<\/td><td>Lock-free&nbsp;<code>atomic_shared_ptr<\/code>&nbsp;(ref-counted)<\/td><\/tr><tr><td>Hard real-time suitability<\/td><td>Limited (GC pauses)<\/td><td>Good (no GC, bounded CAS retries)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Compared to Hardware Transactional Memory (Intel TSX\/RTM):<\/strong>&nbsp;HTM aborts on cache-line conflicts regardless of logical independence, and has strict capacity limits. KAME&#8217;s STM aborts only on semantic conflicts (packet identity change), tolerates large read sets, and degrades gracefully to software backoff rather than falling back to a global lock.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Compared to TinySTM \/ NOrec (C libraries):<\/strong>&nbsp;These use a global version clock and per-object version stamps with a full read\/write log per transaction. KAME avoids the read log entirely \u2014 a&nbsp;<code>Snapshot<\/code>&nbsp;is just an immutable pointer, so reads outside a transaction are truly zero-overhead. The trade-off is that KAME&#8217;s write path must clone the payload upfront (copy-on-write), whereas log-based STMs defer that cost to commit time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What makes KAME&#8217;s design distinctive<\/strong>&nbsp;is the&nbsp;<em>bundling<\/em>&nbsp;protocol: rather than tracking which variables a transaction touched, it tracks whether the packet at the subtree root has been replaced since the transaction started. This is efficient for KAME&#8217;s access pattern (many readers of a stable tree, infrequent writes from acquisition threads) but would be coarser than necessary for workloads with many independent fine-grained variables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why STM?<\/strong>&nbsp;Laboratory software must acquire data on tight hardware timings while simultaneously updating a UI and running user scripts \u2014 all from different threads. Traditional mutex-based designs either serialize too aggressively (dropping samples) or require intricate lock ordering that is error-prone to extend. The STM approach offers three concrete benefits for this domain:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Deadlock-free by design.<\/strong>&nbsp;No locks are held across hardware I\/O or UI redraws. A slow UI thread can never stall a fast acquisition thread.<\/li>\n\n\n\n<li><strong>Consistent multi-instrument views.<\/strong>&nbsp;A&nbsp;<code>Snapshot<\/code>&nbsp;of any subtree is always internally consistent \u2014 the UI always sees a coherent set of readings even when multiple drivers update simultaneously.<\/li>\n\n\n\n<li><strong>Safe scripting from Python\/Ruby.<\/strong>&nbsp;Scripts read and write the node tree through the same transaction API as C++ code, so user scripts cannot corrupt instrument state regardless of when they run.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Dependencies<a href=\"https:\/\/github.com\/northriv\/KAME#dependencies\"><\/a><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Library<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td><strong>Qt<\/strong>&nbsp;\u2265 5.7 or Qt 6<\/td><td>Qt 5 compatibility module required for Qt 6<\/td><\/tr><tr><td><strong>Ruby<\/strong><\/td><td>scripting<\/td><\/tr><tr><td><strong>pybind11<\/strong><\/td><td>Python scripting<\/td><\/tr><tr><td><strong>GSL<\/strong><\/td><td><\/td><\/tr><tr><td><strong>FFTW 3<\/strong><\/td><td><\/td><\/tr><tr><td><strong>Eigen 3<\/strong><\/td><td><\/td><\/tr><tr><td>LAPACK \/ ATLAS \/ BLAS&nbsp;<em>(optional)<\/em><\/td><td><\/td><\/tr><tr><td><strong>libtool-ltdl<\/strong><\/td><td>runtime plug-in loading<\/td><\/tr><tr><td><strong>zlib<\/strong><\/td><td><\/td><\/tr><tr><td><strong>libusb<\/strong><\/td><td>USB instrument interfaces<\/td><\/tr><tr><td>linux-gpib or NI 488.2&nbsp;<em>(optional)<\/em><\/td><td>GPIB interfaces<\/td><\/tr><tr><td>NI DAQmx&nbsp;<em>(optional)<\/em><\/td><td>NI data-acquisition hardware<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A C++11-capable compiler is required (the build uses&nbsp;<code>CONFIG += c++11<\/code>&nbsp;via qmake).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Optional: IPython \/ Jupyter notebook, linux-gpib or NI 488.2, NI DAQmx, libdc1394 (macOS cameras).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Building<a href=\"https:\/\/github.com\/northriv\/KAME#building\"><\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">macOS<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/northriv\/KAME#macos\"><\/a><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Open&nbsp;<code>kame.pro<\/code>&nbsp;in&nbsp;<strong>Qt Creator<\/strong>&nbsp;(use the genuine open-source Qt,&nbsp;<strong>not<\/strong>&nbsp;the MacPorts Qt).<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Install dependencies via MacPorts:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo port install gsl fftw-3 libtool-ltdl libusb eigen3 pybind11<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Optionally, for a universal (arm64 + x86_64) binary, build fftw-3 with:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo port install fftw-3 +universal +clang13 -gfortran<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Additional notes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add&nbsp;<code>\/opt\/local\/bin<\/code>&nbsp;to PATH in the Qt Creator build-environment pane if needed.<\/li>\n\n\n\n<li>In Qt Creator&#8217;s&nbsp;<strong>executable environment<\/strong>&nbsp;pane,&nbsp;<strong>deactivate<\/strong>&nbsp;&#8220;Add build library search path to DYLD_LIBRARY_PATH \u2026&#8221;, otherwise KAME crashes on launch.<\/li>\n\n\n\n<li>If&nbsp;<code>ruby.h<\/code>&nbsp;is not found, reinstall Xcode command-line tools:&nbsp;<code>xcode-select --install<\/code>.<\/li>\n\n\n\n<li>Qt 6: the&nbsp;<strong>Qt5 compatibility module<\/strong>&nbsp;must be selected during Qt installation.<\/li>\n\n\n\n<li>NI 488.2 is not supported on Apple Silicon.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Windows (x86-64, MSYS2 \/ MinGW)<a href=\"https:\/\/github.com\/northriv\/KAME#windows-x86-64-msys2--mingw\"><\/a><\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Requires&nbsp;<strong>Qt \u2265 6.10<\/strong>&nbsp;with the llvm-mingw64 toolchain. Open&nbsp;<code>kame.pro<\/code>&nbsp;in&nbsp;<strong>Qt Creator<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Install dependencies via MSYS2:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pacman -S make \\\n    mingw-w64-x86_64-zlib \\\n    mingw-w64-x86_64-fftw \\\n    mingw-w64-x86_64-gsl \\\n    mingw-w64-x86_64-eigen3 \\\n    mingw-w64-x86_64-pybind11 \\\n    mingw-w64-x86_64-libusb \\\n    mingw-w64-x86_64-python-numpy \\\n    mingw-w64-x86_64-ruby<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">NI 488.2 or DAQmx drivers are optional.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Before running KAME<\/strong>, copy the following DLLs from&nbsp;<code>C:\\msys64\\mingw64\\bin<\/code>&nbsp;alongside the KAME executable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>libfftw3-3.dll  libgsl.dll  libgslcblas-0.dll\nzlib1.dll  libgmp-10.dll  libusb-1.0.dll\nx64-msvcrt-ruby3**.dll\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Also copy&nbsp;<code>kame\/script\/rubylineshell.rb<\/code>&nbsp;and&nbsp;<code>kame\/script\/pythonlineshell.py<\/code>&nbsp;to&nbsp;<code>.\/Resources<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Launch scripts:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Script<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>kame.bat<\/code><\/td><td>Standard launch (system Python)<\/td><\/tr><tr><td><code>kame-msyspython.bat<\/code><\/td><td>Launch with MSYS2 Python (numpy, etc.)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">To launch from Qt Creator, add to&nbsp;<strong>Projects \u2192 Environment<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PATH=C:\\msys64\\usr\\bin;C:\\msys64\\mingw64\\bin;C:\\msys64\\mingw64\\lib\nPYTHONHOME=C:\\msys64\\mingw64\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Scripting<a href=\"https:\/\/github.com\/northriv\/KAME#scripting\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">KAME exposes its entire node tree to&nbsp;<strong>Ruby<\/strong>&nbsp;and&nbsp;<strong>Python<\/strong>. Scripts can be run from the&nbsp;<strong>Script<\/strong>&nbsp;tab in the UI, loaded from&nbsp;<code>.kam<\/code>&nbsp;files, or executed interactively in a Jupyter notebook connected to KAME&#8217;s embedded IPython kernel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<code>.kam<\/code>&nbsp;file is a Ruby script that recreates the full measurement state when executed. When Python is available,&nbsp;<code>.kam<\/code>&nbsp;files are loaded via a fast Python-based translator instead of the Ruby interpreter.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">AI-Assisted Experiment Automation (MCP)<a href=\"https:\/\/github.com\/northriv\/KAME#ai-assisted-experiment-automation-mcp\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">KAME 8.0 ships a built-in&nbsp;<a href=\"https:\/\/modelcontextprotocol.io\/\">MCP<\/a>&nbsp;(Model Context Protocol) server that lets AI assistants execute Python code directly in the running KAME interpreter. The MCP server connects to the embedded IPython kernel via&nbsp;<code>jupyter_client<\/code>, giving the AI full access to&nbsp;<code>Root()<\/code>,&nbsp;<code>Snapshot()<\/code>,&nbsp;<code>Transaction()<\/code>, and all loaded drivers \u2014 the same environment available in Jupyter notebooks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This enables conversational experiment control:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"Read the current temperature from LakeShore1\"\n\"Sweep the magnetic field from 0 to 5 T in 0.1 T steps, recording NMR signal at each point\"\n\"Plot the last 100 DMM readings\"\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Available MCP tools<a href=\"https:\/\/github.com\/northriv\/KAME#available-mcp-tools\"><\/a><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tool<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>kame_api<\/code><\/td><td>Return the Python API quick reference (call first)<\/td><\/tr><tr><td><code>execute_code<\/code><\/td><td>Run Python in KAME&#8217;s interpreter (returns text + matplotlib plots)<\/td><\/tr><tr><td><code>execute_code_async<\/code><\/td><td>Run long experiments asynchronously (sweeps, scans)<\/td><\/tr><tr><td><code>get_result<\/code><\/td><td>Check status of an async job<\/td><\/tr><tr><td><code>tree<\/code><\/td><td>Browse the node tree with configurable depth (compact indented output)<\/td><\/tr><tr><td><code>kame_status<\/code><\/td><td>Check if KAME is running and list active drivers (JSON)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Quick start<a href=\"https:\/\/github.com\/northriv\/KAME#quick-start\"><\/a><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Install prerequisites:pip install mcp jupyter_client<\/li>\n\n\n\n<li>Start KAME and launch a Jupyter notebook (Script \u2192 Launch Jupyter Notebook). KAME writes&nbsp;<code>.mcp.json<\/code>&nbsp;to the notebook workspace directory automatically.<\/li>\n\n\n\n<li>Open Claude Code in the same directory \u2014 the MCP server is discovered and connected automatically.<\/li>\n\n\n\n<li>Ask Claude to interact with your instruments. The&nbsp;<code>.mcp.json<\/code>&nbsp;file is removed when KAME exits.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Manual setup<\/strong>&nbsp;(without Jupyter):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">claude mcp add kame \/path\/to\/python \/path\/to\/KAME\/Resources\/kame_mcp_server.py<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">How it works<a href=\"https:\/\/github.com\/northriv\/KAME#how-it-works\"><\/a><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>When KAME launches a Jupyter notebook, it writes the kernel connection path to&nbsp;<code>~\/.kame_kernel_connection.json<\/code>.<\/li>\n\n\n\n<li>The MCP server reads that file and connects to the kernel via ZMQ (<code>jupyter_client<\/code>).<\/li>\n\n\n\n<li>The AI client launches the MCP server as a subprocess (stdio transport).<\/li>\n\n\n\n<li>The server ships&nbsp;<code>kame_python_api.md<\/code>&nbsp;\u2014 an API reference that Claude reads automatically before writing code, reducing trial-and-error.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Contributing<a href=\"https:\/\/github.com\/northriv\/KAME#contributing\"><\/a><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bug reports and pull requests are welcome on&nbsp;<a href=\"https:\/\/github.com\/northriv\/KAME\">GitHub<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\"><em>This README was written with the assistance of&nbsp;<a href=\"https:\/\/claude.ai\/\">Claude<\/a>&nbsp;(Anthropic).<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp;&nbsp;KAME is an open-source, multi-threaded framework for automated physical property measurements, dev&hellip;&nbsp;<a href=\"https:\/\/kitag.issp.u-tokyo.ac.jp\/en\/%e8%87%aa%e5%8b%95%e5%8c%96%e5%af%be%e5%bf%9c%e6%b8%ac%e5%ae%9a%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%a0kame\/\" class=\"\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">KAME, AI-assisted automation program for physical property measurements<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":495,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_locale":"en_US","_original_post":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wordpress\/?p=67","footnotes":""},"categories":[5],"tags":[],"class_list":["post-924","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-underdevelop","en-US"],"_links":{"self":[{"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/posts\/924","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/comments?post=924"}],"version-history":[{"count":7,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/posts\/924\/revisions"}],"predecessor-version":[{"id":960,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/posts\/924\/revisions\/960"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/media\/495"}],"wp:attachment":[{"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/media?parent=924"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/categories?post=924"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kitag.issp.u-tokyo.ac.jp\/wp-json\/wp\/v2\/tags?post=924"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}