Skip to main content

linc-spectra

Attach a debugger to a running Android app (JDWP via kotlin-debug-adapter, or zero-config jdb by fully-qualified name with no sources) or iOS-simulator app (lldb-dap) and read what UI and logcat cannot show — locals at a method hit, exception frames — through 14 MCP tools.

Install

Prerequisites: Python 3.13+ (stock macOS python3 is older; uv tool install linc-spectra fetches its own Python 3.13 automatically, whereas running pip or pip3 on an older interpreter fails with No matching distribution found for linc-cli-kit).

Install with uv, pipx, or pip (Python >= 3.13):

  • uv tool install linc-spectra
  • pipx install linc-spectra
  • pip install linc-spectra

uv tool install places spectra (and linc-spectra) in ~/.local/bin; a shell without ~/.local/bin on PATH gets exit code 127 (command not found) — run uv tool update-shell and open a new shell (or add ~/.local/bin to PATH).

Then check your environment with uvx linc-spectra doctor (or spectra doctor once installed):

  • What it checks: adb, kotlin-debug-adapter, jdb, lldb-dap (macOS only), xcrun (macOS only), and python (>= 3.13). On macOS, doctor probes the /usr/bin/jdb and /usr/bin/xcrun stubs and reports them as failed until a JDK or Xcode / Command Line Tools is installed.
  • Exit codes: exits 0 when at least one debugger lane is usable (Android: adb plus kotlin-debug-adapter or jdb; iOS on macOS: xcrun plus lldb-dap), or exits 1 with a hint: line for every failed check. Pass --json (spectra doctor --json) for a single {ok, checks} JSON object on stdout.

Adapters

  • Android — zero-config jdb lane: requires adb (Android SDK platform-tools), a debuggable build (android:debuggable="true"), and jdb (ships with any JDK on PATH). Breaks on methods and exceptions by fully-qualified JVM name without local source files.
  • Android — full DAP lane: requires adb, a debuggable build, local source files, and kotlin-debug-adapter. Unpack a release zip from fwcd/kotlin-debug-adapter so adapter/bin/kotlin-debug-adapter is on PATH or installed under ~/tools/kotlin-debug-adapter/ (~/tools/kotlin-debug-adapter/adapter/bin/kotlin-debug-adapter).
  • iOS — simulator lane (experimental): requires macOS with Xcode's lldb-dap (checked on PATH first, then resolved via xcrun -f lldb-dap) and xcrun; spectra doctor reports the macOS /usr/bin/jdb and /usr/bin/xcrun stubs as failed until a JDK or Xcode is installed. Simulator only.

Finding your device id

  • Android (device / device_serial): run adb devices and use the value in the first (serial) column (for example, emulator-5554).
  • iOS Simulator (device / device_serial): run xcrun simctl list devices booted to find the booted simulator UDID, or pass the literal booted.

Quickstart

Register the MCP server and run either the zero-config jdb flow (no local sources) or the full DAP flow:

claude mcp add linc-spectra -- spectra bellows
# Or run directly without a global install:
claude mcp add linc-spectra -- uvx linc-spectra bellows

# Zero-config flow (Android jdb — no local source checkout needed):
#   spectra_method_breakpoint(device="emulator-5554", package="com.example.app", method_fqn="com.example.app.AuthRepository.login")
#   -> trigger the UI in the app
#   -> spectra_method_locals(session_id="<session_id>")

# Full DAP flow (Android kotlin-debug-adapter or iOS lldb-dap):
#   spectra_attach(device="emulator-5554", package="com.example.app", platform="android")
#   -> spectra_breakpoint(session_id="<session_id>", source_path="/abs/path/AuthRepository.kt", lines="42")
#   -> spectra_continue(session_id="<session_id>")
#   -> spectra_stacktrace(session_id="<session_id>")
#   -> spectra_variables(session_id="<session_id>", frame_id=0)  # 0 = stopped thread's top frame, or an id from spectra_stacktrace
#   -> spectra_detach(session_id="<session_id>")

MCP Tools (14)

linc-spectra exposes 14 MCP tools grouped by workflow.

DAP Session

Tool Description
spectra_attach Attach a DAP debugger to a running debuggable app (Android JDWP or iOS Simulator LLDB)
spectra_detach Detach the debugger, remove port forwards, and clean up the session
spectra_sessions List all active debug sessions

Stepping

Tool Description
spectra_breakpoint Set file:line breakpoints on local source files
spectra_continue Resume execution and wait for the next breakpoint or stop event
spectra_step Step next (over), in (into), or out (out of the current frame)

Inspection

Tool Description
spectra_stacktrace Get the call stack for the stopped thread
spectra_variables Inspect local and scope variables at a stack frame
spectra_evaluate Evaluate an expression in the current frame context (REPL at a breakpoint)

Zero-Config jdb

Tool Description
spectra_method_breakpoint Arm a zero-config breakpoint on a method by fully-qualified name (<class>.<method>) with no local sources
spectra_method_locals Harvest captured local variables from an armed spectra_method_breakpoint hit
spectra_exception_breakpoint Arm a zero-config exception catchpoint by fully-qualified exception class name
spectra_exception_info Harvest the throwing frame, thread, and locals from an armed spectra_exception_breakpoint

Analytics

Tool Description
spectra_usage_stats Aggregate per-tool call counts, latency percentiles, and error rates from $LINC_HOME/mcp-calls.jsonl

Limitations

  • Upstream kotlin-debug-adapter exception breakpoints do not work: use spectra_exception_breakpoint (the jdb catchpoint) instead.
  • file:line breakpoints report verified: true even without local sources: kotlin-debug-adapter marks non-existent paths as verified even though they can never bind; spectra_breakpoint attaches a warning field when source_path is missing locally (use spectra_method_breakpoint when you do not have the source checkout).
  • One debugger per process: a target process exposes a single JDWP connection at a time — detach any active DAP session before arming a jdb session on the same app (and vice versa).
  • iOS simulator only: iOS debugging via lldb-dap supports booted iOS simulators on macOS only (experimental; physical iOS devices are not supported).
  • iOS spectra_evaluate takes expressions only: iOS expressions run in lldb-dap's expression-only (watch) context and LLDB commands (such as backtick-prefixed commands) are refused.
  • jdb renders values as text: a debuggee string containing line breaks can add a fake name = value line to a jdb reply (spectra keeps the first value of a name within a reply).
  • Bounded jdb waits and stepping: spectra_method_locals and spectra_exception_info wait at most 180 s (wait_s 0–180), and manual stepping takes max_steps 0–16.
  • Python >= 3.13: requires Python 3.13 or newer.

Trust

  • No telemetry, no phone-home. spectra runs locally over stdio MCP and opens no network listener; it talks only to your local adb, jdb, kotlin-debug-adapter, xcrun, and lldb-dap processes.
  • Local usage log under your control. Every MCP tool call is recorded in $LINC_HOME/mcp-calls.jsonl (default ~/.linc/mcp-calls.jsonl, rotated at 10 MB). Control logging with SPECTRA_USAGE_LOG=off|redacted|full:
    • redacted (default) — sensitive fields (expression and source_path) are replaced by length-only placeholders (<redacted len=N>, no digest), expression text is scrubbed from recorded error strings, and the log file is opened owner-only (0600) with O_NOFOLLOW.
    • off — nothing is written to disk.
    • full — raw parameter values are logged (long strings truncated at 500 characters, byte buffers summarized by length). Opt in only on a machine you trust.
  • spectra_evaluate runs code inside the debuggee. By design, spectra_evaluate and the jdb tools execute inside the attached debuggable application. Identifiers that reach adb shell, xcrun simctl, or jdb stdin are validated with strict re.fullmatch patterns before execution. See SECURITY.md for the threat model and vulnerability reporting instructions.

How this repo works

This repository is a release mirror of LINC's private repository — each release lands here as a single commit. Issues are welcome; pull requests are accepted by arrangement (open an issue first). See CONTRIBUTING.md.


Built by LINC Innovations. Licensed under Apache-2.0.

Metadata

Release files for linc-spectra 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for linc-spectra 0.1.0
File Size Uploaded Provenance
linc_spectra-0.1.0.tar.gz 174.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for linc-spectra 0.1.0
File Interpreter ABI Platform
linc_spectra-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 250.8 kB

Release files / linc_spectra-0.1.0.tar.gz

Download URL linc_spectra-0.1.0.tar.gz
Size 174.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3f15cecf9de25e8f23b26d080a11c3d8d6c22042a3b1f096a1a32254f550346d
BLAKE2b-256 checksum
How to use checksums
437a84d8a66e1c8f9d8f5176a2078b059f8269ae6c27f8051346f661b7e134bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / linc_spectra-0.1.0-py3-none-any.whl

Download URL linc_spectra-0.1.0-py3-none-any.whl
Size 76.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e57b2279f1c334ba5fd0929677dd790d4d28e6b124d1ed1b77ba0d2a5388d2a7
BLAKE2b-256 checksum
How to use checksums
fa18dc67cbd61fed1f6daeaebf96c0bc0f5d08bf1c87f2402d39874f10c01980
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for linc-spectra 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for linc_spectra-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page