# Jarroba Tools (npm · @jarroba/mcp)

104 deterministic tools for your AI: logs, tests, SQL, diagrams, SPARQL. Local, no network.

- Trust score: 65/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- npm · `@jarroba/mcp`: 65/100 (this document), [markdown](https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp.md), [page](https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp)

## Channel facts

- Registry: `npm`
- Package: `@jarroba/mcp`
- Version: `0.1.5`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 35 of 110 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 19/100
  - Repository check failed: the declared repository URL returned HTTP 404.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Security-disclosure policy not yet verified: we couldn't inspect the source repository.
- **Schema Quality & AI Usability**: 68/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 14133 tokens (~135/item across 104 items; 104 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 92/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 76% of tool parameters carry a description.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 0 of 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "calc_eval" implies "eval" and declares readOnlyHint instead, contradicting what its own name says it does.
  - An AI judge read all 105 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Jarroba Tools MCP server?

Jarroba Tools runs locally as an npm package, launched with npx -y @jarroba/mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add invarato-jarroba-tools -- npx -y @jarroba/mcp
```

### Cursor

```json
{
  "mcpServers": {
    "invarato-jarroba-tools": {
      "command": "npx",
      "args": [
        "-y",
        "@jarroba/mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "invarato-jarroba-tools": {
      "command": "npx",
      "args": [
        "-y",
        "@jarroba/mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add invarato-jarroba-tools -- npx -y @jarroba/mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "invarato-jarroba-tools": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@jarroba/mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add invarato-jarroba-tools --command npx --arg -y --arg @jarroba/mcp
```

### Hermes

```yaml
mcp_servers:
  invarato-jarroba-tools:
    command: "npx"
    args: ["-y", "@jarroba/mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "invarato-jarroba-tools": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@jarroba/mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add invarato-jarroba-tools -t stdio -c npx -a -y @jarroba/mcp
```

### Other

```json
{
  "mcpServers": {
    "invarato-jarroba-tools": {
      "command": "npx",
      "args": [
        "-y",
        "@jarroba/mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-19 (score 65, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-09-18 (score 49, −15)

- [security regression] Malware scan: pass → unverified
- [functional] Package version: 0.1.4 → 0.1.5

### 2026-09-17 (score 64, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-09-16 (score 48, −13)

- [security regression] Malware scan: pass → unverified
- [security regression] Tool safety: pass → unverified
- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Stability: unverified → 0.13
- [functional] First check of Schema quality: unverified
- [functional] Package version: 0.1.2 → 0.1.4

### 2026-09-13 (score 61, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-09-12 (score 46)

First indexed and scored.

## MCP tools (104)

### `cidr_info` (~91 tokens)

Analyze an IPv4 network from CIDR or IP+mask: network and broadcast addresses, first/last host, mask and wildcard, host count, class, private/special ranges, binary form and reverse PTR name.

Input parameters:

- `input` (string, required): e.g. "192.168.1.10/24" or "10.0.0.0 255.255.255.0"

### `cidr_contains` (~38 tokens)

Is this IP inside that CIDR network? Returns true/false.

Input parameters:

- `cidr` (string, required)
- `ip` (string, required)

### `cidr_vlsm` (~48 tokens)

Split a base network into variable-length subnets (VLSM) sized to the host counts you ask for.

Input parameters:

- `base` (string, required)
- `requests` (array, required)

### `count_tokens` (~89 tokens)

Count tokens EXACTLY with the model's real BPE (o200k_base=GPT-4o, cl100k_base=GPT-4/3.5, p50k_base=Codex, r50k_base=GPT-3/2). Returns tokens, words, characters and % of the context window.

Input parameters:

- `encoding` (string)
- `text` (string, required)

### `hash_text` (~36 tokens)

SHA-256, SHA-384 and SHA-512 (hex) of a UTF-8 string.

Input parameters:

- `text` (string, required)

### `jwt_decode` (~37 tokens)

Decode a JSON Web Token WITHOUT verifying its signature: header, payload and metadata (exp, iat…).

Input parameters:

- `token` (string, required)

### `text_encode` (~35 tokens)

Encode a string to URL-encoding, Base64 and HTML-escape (all three at once).

Input parameters:

- `input` (string, required)

### `text_decode` (~31 tokens)

Try to decode a string from URL-encoding, Base64 and HTML entities.

Input parameters:

- `input` (string, required)

### `string_escape` (~44 tokens)

Escape a string for a target context: javascript, json, sql, regex, html, url or css.

Input parameters:

- `mode` (string, required)
- `text` (string, required)

### `string_unescape` (~45 tokens)

Unescape a string from a context (javascript, json, sql, regex, html, url, css).

Input parameters:

- `mode` (string, required)
- `text` (string, required)

### `regex_test` (~53 tokens)

Test a regex against a string: whether it matches, every match and its capture groups. Exact matching, not guessed.

Input parameters:

- `flags` (string)
- `pattern` (string, required)
- `text` (string, required)

### `timestamp_convert` (~76 tokens)

Convert an instant between formats: Unix (s/ms), ISO 8601, human, log, and per-locale/timezone. Accepts a Unix number or a date string.

Input parameters:

- `input` (string, required): e.g. "1700000000" or "2024-01-15T10:30:00Z"

### `cron_next` (~88 tokens)

Next run times of a 5-field cron expression, as ISO dates. "When does this actually fire?" is a calculation LLMs routinely get wrong.

Input parameters:

- `count` (integer)
- `expr` (string, required): e.g. "*/15 9-17 * * 1-5"
- `tz` (string): IANA timezone, e.g. "Europe/Madrid"

### `color_convert` (~51 tokens)

Convert a color between HEX, RGB and HSL. Accepts "#3498db", "rgb(52,152,219)", "hsl(...)" or CSS names.

Input parameters:

- `input` (string, required)

### `url_parse` (~34 tokens)

Break a URL into protocol, host, port, path, query (parsed) and fragment.

Input parameters:

- `url` (string, required)

### `chmod_explain` (~67 tokens)

Read Unix permissions: takes octal ("755") or symbolic ("rwxr-xr-x") and returns both forms plus the breakdown (user/group/other, setuid/setgid/sticky).

Input parameters:

- `input` (string, required): "755" or "rwxr-xr-x"

### `json_diff` (~45 tokens)

Structural differences between two JSON documents, by path: added / removed / changed / type changed.

Input parameters:

- `a` (string, required): JSON A
- `b` (string, required): JSON B

### `unit_convert` (~82 tokens)

Convert data sizes between SI multiples (kB/MB, base 1000) and IEC multiples (KiB/MiB, base 1024), and between bits and bytes. Settles the usual KB-vs-KiB confusion.

Input parameters:

- `input` (string, required): e.g. "15 Mb", "1 GiB", "1500 kB"

### `hamming_encode` (~51 tokens)

Encode bits with a Hamming (SEC) code: inserts the parity bits. Input is a string of 0s and 1s.

Input parameters:

- `bits` (string, required): e.g. "1011"

### `hamming_check` (~49 tokens)

Detect and correct a single-bit error in a received Hamming word: whether there is an error, which bit, and the corrected data.

Input parameters:

- `word` (string, required): The received Hamming word

### `ieee754_from_decimal` (~64 tokens)

IEEE-754 representation of a decimal number in 32-bit (single) or 64-bit (double): sign, exponent, mantissa, raw bits, hex, and the value actually stored.

Input parameters:

- `number` (number, required)
- `precision` (number)

### `number_bases` (~89 tokens)

Show an integer in binary, octal, decimal and hex, plus its bit view (signed/unsigned, popcount, leading/trailing zeros) at the chosen width. Accepts decimal, 0x…, 0b…, 0o…

Input parameters:

- `input` (string, required): e.g. "255", "0xff", "0b1010"
- `width` (number)

### `calc_eval` (~108 tokens)

Evaluate a mathematical expression WITH UNITS and dimensional checking: "100 km/h to m/s", "5 km + 300 m", "70 kg to lbs", "det([[1,2],[3,4]])". Adding incompatible units is an error, not a silent number. Also flags results that are not finite (NaN, infinity).

Input parameters:

- `expression` (string, required): e.g. "100 km/h to m/s" or "sqrt(2)^2 + 2^10"

### `calc_solve` (~139 tokens)

Solve an equation in one unknown ("x^2 - 5x + 6 = 0", "sin(x) = 0.5") or a linear system (one equation per line). Says whether the answer is EXACT or an approximation, and over which interval it searched. Never invents a root it did not find.

Input parameters:

- `equations` (string, required): One equation, or several separated by newlines for a system
- `from` (number): Lower bound for the numeric search
- `to` (number): Upper bound for the numeric search
- `unknown` (string): Which variable to solve for (guessed if omitted)

### `calc_sheet` (~141 tokens)

Evaluate a multi-line calculation sheet and return the result of EVERY line. Variables carry downwards, units travel with the value, "#" starts a comment, "ans" is the previous result, and an error stays on its own line instead of killing the sheet. Declare currencies with "# @moneda USD = 1.08 EUR". Good for checking a quote or a budget line by line.

Input parameters:

- `as_markdown` (boolean): Also return the sheet as a Markdown table
- `sheet` (string, required): One expression per line, e.g. "width = 3.5 m height = 2.4 m area = width * height"

### `calc_derive` (~192 tokens)

Differentiate an expression symbolically, exactly: "x^3 + 2x", "sin(x)*cos(x)", "x^x". Keeps units, so d/dx (3 m * x) is "3 m" and not 3. Can take higher-order derivatives and evaluate the result at a point. Says which name it read as a unit, and refuses to answer "0" when the variable is not in the expression.

Input parameters:

- `at` (number): Also evaluate the derivative at this value of the variable
- `expression` (string, required): e.g. "x^3 + 2x" or "9.8 m/s^2 * t^2 / 2"
- `order` (integer): 1 = first derivative, 2 = second… up to 4
- `variable` (string): Differentiate with respect to this (guessed if omitted)

### `calc_steps` (~165 tokens)

Show the WORKED STEPS of a calculation, verified step by step: a linear or quadratic equation, a derivative (naming which rule applies), or Gaussian elimination on a linear system row by row. Each step comes with the name of the rule used. When it cannot explain a case it says so (covered: false) instead of inventing a plausible-looking derivation — useful when you have to show your work to a person.

Input parameters:

- `input` (string, required): An equation ("2x + 6 = 0"), an expression to differentiate ("sin(x)*x^2"), or one equation per line for a system
- `kind` (string): What to explain
- `variable` (string): The unknown or the variable to differentiate by (guessed if omitted)

### `binary_calc` (~89 tokens)

Programmer's calculator on exact integers (BigInt): arithmetic (add/sub/mul/div/mod/pow) and bitwise (and/or/xor/nand/nor/xnor/shl/shr/sar/rol/ror). Returns the result in every base.

Input parameters:

- `a` (string, required)
- `b` (string, required)
- `op` (string, required)
- `width` (number)

### `semver_parse` (~49 tokens)

Parse a SemVer version (major.minor.patch + pre-release + build metadata).

Input parameters:

- `version` (string, required): e.g. "1.4.2-beta.1+build.9"

### `semver_satisfies` (~59 tokens)

Given a list of versions, which ones satisfy a SemVer range (^, ~, >=, <, x, …).

Input parameters:

- `range` (string, required): e.g. "^1.2.0"
- `versions` (array, required)

### `wcag_contrast` (~81 tokens)

WCAG contrast ratio between two colors, and whether it passes AA/AAA for normal and large text. Accepts #rgb/#rrggbb, rgb(), hsl() or CSS names.

Input parameters:

- `background` (string, required): e.g. "#fff" or "white"
- `foreground` (string, required): e.g. "#333" or "black"

### `format_convert` (~46 tokens)

Convert data between formats: json, yaml, properties, env, csv, markdown.

Input parameters:

- `from` (string, required)
- `input` (string, required)
- `to` (string, required)

### `unicode_info` (~45 tokens)

Unicode details for every character in a string: code point (U+…), name/category, UTF-8/16 bytes, HTML entity, escapes.

Input parameters:

- `input` (string, required)

### `diagram_validate` (~86 tokens)

Validate a JTD (Jarroba Tools Diagram) document: structure, allowed shapes and chart types, and edge references. Returns {ok, errors, warnings, summary}. Spec: public/jtd.md. Use it to check your JSON before handing it to anyone.

Input parameters:

- `jtd` (string, required): The JTD document as JSON (an object with a "jtd" key).

### `diagram_svg` (~64 tokens)

Render a JTD to SVG with no browser and no dev server, so you get the actual drawing back and can check it. Validates first. This is the one to use to SEE what you built.

Input parameters:

- `jtd` (string, required): The JTD document as JSON.

### `diagram_render` (~98 tokens)

Render a JTD to PNG with the app's REAL engine (full fidelity; only needed to check skins and effects). Requires a checkout of the repo AND a running dev server. For everything else use diagram_svg, which needs neither.

Input parameters:

- `baseUrl` (string): Dev server URL (default http://localhost:4201)
- `jtd` (string, required)
- `out` (string): Output PNG path (default: a temp file)

### `diagram_new` (~91 tokens)

Start an EMPTY JTD diagram in memory, discarding any previous one. Lets you build it piece by piece with diagram_add and look at it with diagram_preview, instead of writing the whole JSON in one shot.

Input parameters:

- `background` (string)
- `layout` (string): flow-down|flow-right|free|grid|radial
- `theme` (string)
- `title` (string)

### `diagram_add` (~90 tokens)

Append the "nodes"/"edges"/"charts" of a JTD FRAGMENT (same format) to the diagram held in memory, on top of whatever is already there. Returns the new counts plus the warnings and errors of validating the result.

Input parameters:

- `jtd` (string, required): JTD fragment: {"nodes":[...],"edges":[...],"charts":[...]} — only what you want to add.

### `diagram_get` (~30 tokens)

Return the COMPLETE JTD document built so far in memory, ready to save or paste into the web tool.

### `diagram_preview` (~56 tokens)

Validate and DRAW (SVG) the diagram held in memory, so you can look at it and keep adding or fixing in a loop. This is the generate → look → correct cycle; a model cannot judge a diagram by reading its JSON.

### `kg_query` (~115 tokens)

Run SPARQL 1.1 (SELECT/ASK/CONSTRUCT/DESCRIBE) over in-memory RDF — a real engine, not pattern matching. Accepts Turtle, N-Triples, N-Quads, TriG, JSON-LD or RDF/XML. Returns rows (SELECT), a boolean (ASK) or Turtle (CONSTRUCT/DESCRIBE).

Input parameters:

- `data` (string, required): The RDF graph as text
- `format` (string)
- `query` (string, required): SPARQL query

### `kg_validate` (~83 tokens)

Validate RDF data against its SHACL shapes (core subset): sh:targetClass + sh:path with minCount, maxCount, datatype, class and nodeKind. Returns whether it conforms plus every violation (node, property, constraint, message).

Input parameters:

- `data` (string, required): The RDF graph (data + sh: shapes) as text
- `format` (string)

### `kg_semantic_validate` (~111 tokens)

Validate a SEMANTIC LAYER document (term→predicate glossary + named SPARQL metrics) before trusting it: structure, required fields (term/target, name/sparql), metric names usable as identifiers, and uniqueness. Returns {ok, errors, warnings}. This is "semantics as code": define once, compute the same everywhere.

Input parameters:

- `semantic` (object, required): Semantic layer: { glossary: [{term,target,synonyms?}], metrics: [{name,label?,sparql}] }

### `kg_metric` (~169 tokens)

Run a NAMED metric from the semantic layer against RDF data: fills its {{param}} placeholders from `args` and executes the resulting SPARQL. Use it so "revenue" or "active users" is computed from the AGREED definition instead of a query you invented — the fix for "one number, three answers". Returns the effective SPARQL and the result, or which parameters are missing.

Input parameters:

- `args` (object): Values for the metric's {{...}} parameters
- `data` (string, required): The RDF graph as text
- `format` (string)
- `metric` (string, required): Name of the metric to run
- `semantic` (object, required): Semantic layer: { glossary: [{term,target,synonyms?}], metrics: [{name,label?,sparql}] }

### `db_translate_sql` (~86 tokens)

Translate SQL from another engine to PostgreSQL

Detect whether a SQL script comes from MySQL/MariaDB, SQLite, SQL Server or Oracle and translate it to PostgreSQL, explaining every change with its line number. Changes that are NOT exact equivalents are flagged as such.

Input parameters:

- `dialect` (string): Source engine; "auto" detects it from markers in the SQL itself
- `sql` (string, required): The source SQL script

### `db_schema_review` (~115 tokens)

Review a database schema

Run a DDL in an ephemeral PostgreSQL and return the REAL schema (tables, columns, keys, indexes, constraints) plus the design problems found: tables with no primary key, foreign keys with no index, money in floating point, timestamps without a time zone, types that do not match on the two sides of a relation, and redundant indexes. The schema is executed, not guessed with regular expressions.

Input parameters:

- `ddl` (string, required): CREATE TABLE… (PostgreSQL; for another engine, run db_translate_sql first)

### `db_docs` (~69 tokens)

Document a schema

Turn a DDL into Markdown documentation, DBML (dbdiagram.io) or a Mermaid erDiagram, with relations and their 1:1 / 1:N cardinality derived from the keys.

Input parameters:

- `ddl` (string, required): CREATE TABLE… (PostgreSQL)
- `format` (string)

### `db_entities` (~105 tokens)

Generate code entities from a schema

Turn a DDL into classes in your language: Java/JPA, TypeScript, Python (SQLAlchemy 2.0), C#/EF Core or Go. Types are respected — `numeric` becomes BigDecimal/decimal, never a double — and so is which fields are optional.

Input parameters:

- `ddl` (string, required): CREATE TABLE… (PostgreSQL)
- `namespace` (string): Package (Java) or namespace (C#)
- `target` (string, required): Target language

### `db_join_path` (~168 tokens)

How two tables join

Find the foreign-key paths between two tables and return the SELECT with the JOINs already written. If the script carries data, every path is EXECUTED and they are ranked by the rows they actually return — a short path that yields zero rows joins nothing. Hub tables (related to almost everything) can be set aside, since they connect any pair without explaining anything.

Input parameters:

- `avoidHubs` (boolean): Set aside tables that are related to almost every other one
- `from` (string, required): Source table ("orders" or "sales.orders")
- `maxHops` (integer): Maximum hops per path
- `sql` (string, required): CREATE TABLE… (PostgreSQL) plus its INSERTs, if you want ranking by real rows
- `to` (string, required): Target table

### `db_fk_infer` (~177 tokens)

Relations that exist in the data but are not declared

Propose the missing foreign keys: find by name and type the columns that look like they point at another table, then CHECK each one against the rows, counting how many of its values actually exist on the other side. The percentage is counted rows, not a hunch. At 100% the relation holds and the returned ALTER TABLE cannot fail; with orphan rows PostgreSQL would reject it, so how many and which ones are reported.

Input parameters:

- `includeWeak` (boolean): Also return the ones that do NOT hold (under 80% coverage), so you can rule them out by looking
- `orphanSample` (integer): How many unmatched rows to bring back as evidence for each proposal
- `sql` (string, required): CREATE TABLE… plus its INSERTs (PostgreSQL). With no data there is nothing to check against

### `db_rls_check` (~197 tokens)

Review and simulate row-level security (RLS)

Run the script in an ephemeral PostgreSQL and review row-level security, warning about the SILENT failures: RLS on with no policies, policies with RLS off, the owner bypassing them because FORCE is missing, a superuser role, or the missing GRANT/USAGE that makes "zero rows" not the policy's fault at all. Given a role and a table it also SIMULATES: it looks at the table through that role's eyes, inside a transaction that is rolled back, and reports how many rows it can see, update and delete.

Input parameters:

- `role` (string): Role whose eyes to look through (your application's role, not the owner)
- `sql` (string, required): The complete script: CREATE TABLE, INSERT, CREATE ROLE, GRANT, ENABLE ROW LEVEL SECURITY and CREATE POLICY
- `table` (string): Table to simulate. Without it, every table with RLS enabled is simulated

### `prompt_review` (~162 tokens)

Review a system prompt

Check a system prompt against the rules that make it followable: an explicit output contract, a definition of done, what to do when the model does not know (the rule that prevents made-up answers), contradictions, unverifiable requirements, prohibitions with no alternative, example count and context budget. It does NOT judge whether the prompt is GOOD — that needs evals and a real model run — it is the deterministic layer underneath. Useful on your own system prompt.

Input parameters:

- `examples` (integer): How many input→output (few-shot) examples accompany the prompt
- `outputFormat` (string): The part describing the output format, if it is kept separate from the prompt
- `prompt` (string, required): The complete system prompt, exactly as it would be sent

### `rag_prepare` (~161 tokens)

Chunk a text and rank the chunks against a query

Split a text on real boundaries (paragraph, else sentence, never mid-word) with the overlap you ask for, and optionally rank the chunks against a query with BM25. Use it to prepare a RAG corpus, or to see why a query fails to retrieve what it should. No model involved: this is the lexical half, the one that finds literal terms — a code, a surname, a version number — that an embedding dissolves.

Input parameters:

- `overlap` (integer): Overlap between consecutive chunks; capped at half the size
- `query` (string): If given, chunks come back ranked by BM25 against it
- `size` (integer): Target size of each chunk, in characters
- `text` (string, required): The text to split

### `log_analyze` (~163 tokens)

Understand a log without reading it: detected format, number of EVENTS (a 40-line stack trace counts as one), breakdown by level, time range, the errors with their ROOT CAUSE resolved, and the most frequent patterns. Accepts a file PATH — that is how you look at a log that does not fit in your context, such as a CI log of hundreds of MB.

Input parameters:

- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `log_reduce` (~206 tokens)

Cut a log down to a CHARACTER budget while keeping what matters: errors with their full stack trace, the window of what happened just before, and anything that appears only once or twice. Repeats are collapsed with their count ([xN]) and gaps are marked ([...N]). Use it to hand a big log to a model without spending the context on the same line repeated.

Input parameters:

- `context` (integer): Events kept before each error
- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `fullTraces` (boolean): false collapses each stack trace to its one-line summary
- `maxChars` (integer): Character budget for the output
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `log_patterns` (~184 tokens)

Group log lines into TEMPLATES (Drain algorithm): "connected to 10.0.0.1" and "connected to 10.0.0.7" are the same message. Turns a million lines into a few hundred readable things, each with its count, worst level and time range. Also returns the RARE ones (seen once or twice), which in a production log are usually what you were looking for.

Input parameters:

- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `limit` (integer): How many patterns to return
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `log_stacktrace` (~131 tokens)

Read an exception stack trace (Java/JVM, Python, Node, Go, .NET, Rust, Ruby or PHP) and answer the only question anyone asks it: WHERE TO LOOK. Follows the "Caused by" chain to the root cause, separates your code from the framework, and points at your first frame. Infers which package is yours from the trace itself if you do not say.

Input parameters:

- `myPrefixes` (array): Prefixes of your own code, e.g. ["com.acme.", "src/"]
- `trace` (string, required): The stack trace, pasted as-is

### `log_lint` (~169 tokens)

Check whether the log is WELL WRITTEN — not what happened in the system: secrets or personal data printed, one line flooding the file, timestamps with no time zone (which make two machines impossible to correlate), the clock going backwards, everything at the same level, no request id, payload dumps, and orphan stack traces with no error line. Every finding comes with its count and a sample; secrets are masked.

Input parameters:

- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `log_convert` (~190 tokens)

Convert a log from one format to another through OpenTelemetry's Logs Data Model: JSON, logfmt, syslog RFC 5424, CSV, OpenTelemetry or Elastic Common Schema. Tells you UP FRONT what the conversion loses — syslog only has eight severities and a text body, so coming down to it from JSON drops fields.

Input parameters:

- `columns` (array): CSV only: which fields become columns
- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `host` (string)
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `service` (string)
- `target` (string, required): Output format
- `text` (string): The log as text. Alternative to `path`.

### `claim_check` (~145 tokens)

Separate what is backed from what is merely asserted

Split a text into claims and say, for each, whether it comes with a source and of what kind: peer-reviewed, preprint (arXiv and friends), registry/link, or self-published. Flags the ABSOLUTE claims with NO source at all, which is the expensive failure mode because they sound exactly as confident as the backed ones. It does NOT say whether something is true — it cannot — it says whether it is supported, which is a different thing. An arXiv DOI is still a preprint: registration is not review. Worth running on your own answer before you send it.

Input parameters:

- `text` (string, required): The text to review, as-is

### `eval_check` (~163 tokens)

Review and run an eval suite

Review an eval suite and run it against the outputs you provide. The review catches what silently ruins a suite: assertions that CANNOT FAIL (an empty `contains`, a regex like `.*`, a case with no assertions) and ones that can never pass (requiring and forbidding the same thing, an inverted range). A suite with those scores 100% on day one and has measured nothing. Assertion types: contains, not-contains, regex, json, range, max-chars and supported (no absolute claim without a source). Calls no model: you pass the outputs in already produced.

Input parameters:

- `cases` (array, required): The suite cases, with their outputs already obtained
- `promptfoo` (boolean): If true, also return the equivalent promptfoo configuration

### `mcp_catalog_audit` (~276 tokens)

Audit an MCP server catalogue for design quality

Paste the `tools/list` response of an MCP server — yours, or a third party's you are evaluating whether to install — and check its catalogue quality: missing descriptions or annotations, a tool name that suggests it writes or deletes while its annotations say otherwise, context cost per tool (real BPE tokenization), and whether the top-level `instructions` field is set and fits under the ~2 KB some Tool Search clients trim. Add `serverJson`/`packageJson` to also catch the official MCP registry's own field-length and namespace-pattern limits, and a version mismatch between the two — the exact 422/403/400 errors this project hit publishing its own packages. This is NOT an access-security review: it does not evaluate what the tools are permitted to do, only how the catalogue is described.

Input parameters:

- `encoding` (string): BPE encoding for the token-cost measurement
- `instructions` (string): The server-level `instructions` string, if you have it
- `packageJson` (string): package.json, to cross-check its version against server.json
- `serverJson` (string): The registry manifest (server.json), to check its own limits
- `toolsListJson` (string, required): The `tools/list` response, either `{"tools": [...]}` or the bare array

### `log_trends` (~238 tokens)

Answer WHEN IT STARTED, which is what a log is really asked. Compares each pattern against ITSELF rather than against total volume — in a busy service everything rises at 9am and nothing has happened — and returns three different things: what SPIKED relative to its own normal and at what time; what is NEW, which did not exist before and is usually what a deploy left behind; and what STOPPED APPEARING, which raises no counter and is often the worse news.

Input parameters:

- `bucketSeconds` (integer): Width of the time bucket; by default chosen from the log's own range
- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `limit` (integer): How many findings to return
- `minRatio` (number): How many times its own normal counts as a spike
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `log_around` (~237 tokens)

What ELSE happened around a moment in time. Given an instant — the spike log_trends returned, or the time of an alert — find the patterns that cluster there and do not appear the same way in the rest of the log. Correlation is NOT causation, and what settles it is order: what started BEFORE comes first and is a candidate explanation; what came after is usually a consequence. Background noise is filtered out even when a narrow window lands on one of its bursts.

Input parameters:

- `at` (string, required): Reference instant, in ISO 8601 (e.g. "2026-08-27T10:40:00Z")
- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `limit` (integer)
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `radiusSeconds` (integer): How far to look on each side
- `text` (string): The log as text. Alternative to `path`.

### `log_rotation` (~155 tokens)

Put a folder or a list of rotated logs into TIME ORDER, split into series. Rotation numbering runs BACKWARDS against time: `app.log.3.gz` is older than `app.log.1.gz`, and plain `app.log` is the newest; alphabetically `app.log.10` sorts before `app.log.9` while in time it comes after. Use this BEFORE reading several logs of one service, or you will read them backwards. Returns the paths already ordered, ready to feed to log_analyze one by one.

Input parameters:

- `directory` (string): Folder to look in (does not recurse). Alternative to `names`.
- `names` (array): List of file names or paths, in any order

### `log_profile_check` (~107 tokens)

Validate a Jarroba Tools LOG PROFILE (the `logprofile: 1` JSON that configures the log tools: format, server time zone, own-code prefixes, rules and AI budget). Returns ALL errors at once, each with the exact field (`rules[2].pattern`) and what was expected, so you can fix them in one pass instead of one at a time. Format documented in `public/logprofile.md`.

Input parameters:

- `profile` (string, required): The profile as JSON

### `log_profile_suggest` (~183 tokens)

Propose a LOG PROFILE from a real log: infers the format, the own-code prefix (read from the stack traces, which is where it is demonstrated) and a starting set of rules covering the most frequent errors and whatever floods the file. What it does NOT propose is the server time zone: that is not in the log, and inventing it shifts the entire timeline without anyone noticing. Accepts a file path.

Input parameters:

- `format` (string): Force the format instead of detecting it
- `from` (string): Which end to read if the file is over 32 MB
- `name` (string): Name for the profile
- `path` (string): Path to the log file. Use this for big logs: they do not fit in a tool call.
- `text` (string): The log as text. Alternative to `path`.

### `queue_analyze` (~184 tokens)

M/M/c queue: with N resources, how many people wait, how long, and what fraction leaves without a place. With `waitingRoom` the model becomes M/M/c/K (finite waiting area — the realistic case); without it the queue is infinite. Output times are in MINUTES. Erlang and M/M/c are exactly the kind of arithmetic a model does "from memory" and gets wrong.

Input parameters:

- `arrivalsPerHour` (number, required): Arrivals per hour (lambda), e.g. 12 groups/hour.
- `avgServiceMinutes` (number, required): Mean time one resource stays occupied, in minutes, e.g. 75.
- `servers` (integer, required): Resources: tables, beds, bays, checkouts…
- `waitingRoom` (integer): Waiting places IN ADDITION to the resources. Omit for an unbounded queue (nobody leaves).

### `queue_size` (~183 tokens)

How many resources do you need? Returns the MINIMUM that meets your target (max wait, max turned away, or max utilization) and how the system behaves at that number. This is the question asked before building a place, not after.

Input parameters:

- `arrivalsPerHour` (number, required): Arrivals per hour (lambda), e.g. 12 groups/hour.
- `avgServiceMinutes` (number, required): Mean time one resource stays occupied, in minutes, e.g. 75.
- `maxTurnedAway` (number): Maximum fraction that leaves without a place (0-1).
- `maxUtilization` (number): Maximum utilization per resource (0-1). The 0.85 rule for hospital beds is this number.
- `maxWaitMinutes` (number): Maximum acceptable mean wait.
- `waitingRoom` (integer): Waiting places in addition to the resources.

### `queue_loss` (~98 tokens)

Pure LOSS system (Erlang B): there is no waiting area, so whoever finds no free resource leaves. Car parks, workshop bays, phone lines, critical-care beds.

Input parameters:

- `arrivalsPerHour` (number, required): Arrivals per hour (lambda), e.g. 12 groups/hour.
- `avgServiceMinutes` (number, required): Mean time one resource stays occupied, in minutes, e.g. 75.
- `servers` (integer, required)

### `queue_simulate` (~132 tokens)

Simulate the queue customer by customer (discrete events, fixed seed, so the result is reproducible). Its job is to CROSS-CHECK the analytic answer: if the simulation and the formula disagree, one of them is wrong.

Input parameters:

- `arrivalsPerHour` (number, required): Arrivals per hour (lambda), e.g. 12 groups/hour.
- `avgServiceMinutes` (number, required): Mean time one resource stays occupied, in minutes, e.g. 75.
- `customers` (integer)
- `seed` (integer)
- `servers` (integer, required)
- `waitingRoom` (integer)

### `make_simulate` (~251 tokens)

Simulate `make` WITHOUT RUNNING ANYTHING: which targets would be rebuilt, in what order, and WHY, naming the file to blame. Answers the two questions no other tool answers: "why is it rebuilding this when I changed nothing?" and "why is it NOT rebuilding it?". With `project` it reads the Makefile and the REAL mtimes from disk; `touch` asks "what if I changed this file?" without changing it. The reasons use the same vocabulary as the Linux kernel's `make V=2`.

Input parameters:

- `file` (string): Path to a specific Makefile
- `files` (array): List of project paths, if no folder is given
- `forceAll` (boolean): Like `make -B`: rebuild everything without looking at dates
- `project` (string): Project folder: its Makefile and its files' real mtimes are read
- `targets` (array): What to build. Empty = the Makefile's default target
- `text` (string): The Makefile pasted, if there is no folder
- `touch` (array): Files to treat as just-modified, WITHOUT actually touching them (like `make -W`)

### `make_lint` (~205 tokens)

Review a Makefile and return the mistakes that actually bite, each with WHAT is wrong, HOW it breaks in practice and HOW to fix it: a recipe indented with spaces instead of a tab, a `cd` that does not persist to the next line, a `$` that make eats before the shell sees it, `$(shell ...)` inside a `=` variable (re-executed on every use), a pipeline without `pipefail`, a missing `.PHONY`, and a missing `.DELETE_ON_ERROR`. Calibrated NOT to complain about correct code: a well-written Makefile comes back with zero findings.

Input parameters:

- `file` (string): Path to a specific Makefile
- `files` (array): Project paths: with them more cases are detected (e.g. a .PHONY that collides with a real file)
- `project` (string): Project folder (its Makefile is read)
- `text` (string): The Makefile pasted

### `make_generate` (~210 tokens)

Generate a ready-to-use Makefile for a stack (node, python, go, rust, c or generic). What it generates PASSES its own linter with zero findings: it always ships `.DELETE_ON_ERROR`, `SHELL := /bin/bash` with `.SHELLFLAGS := -eu -o pipefail -c`, and declared `.PHONY` targets — the three lines that are almost never there and that prevent the most expensive failures. With `withLogs`, targets record their output through `tee`, redirect stderr, timestamp the file name, and take the log directory as an order-only prerequisite.

Input parameters:

- `projectName` (string): Project name (default "mi-proyecto")
- `stack` (string, required): Project stack
- `withDocker` (boolean): Docker image targets (default no)
- `withHelp` (boolean): Self-documenting `make help` built from ## comments (default yes)
- `withLogs` (boolean): Targets that record their output to files (default yes)

### `make_role` (~292 tokens)

Answer the question that decides whether `make` is giving you anything: is this Makefile a BUILD, or a script LAUNCHER? make exists in order NOT to redo what is already done — mtimes, a dependency graph, skipping what did not change — and most Makefiles today use none of it: they are `make test`, `make lint`, `make docker-up`, all .PHONY, all running every time. Here each target is classified WITH THE SIGNAL that decided it (including the signals that pointed the other way: a .PHONY whose recipe creates that very file is a bug waiting to happen), what make is giving you TODAY is measured, and with `convertTo` it is converted to just, Taskfile or npm scripts. Whatever cannot be converted is OMITTED with its reason, rather than emitting a recipe that would look the same and rebuild every time. Honest caveat: `make` is POSIX and is everywhere; just and task have to be installed.

Input parameters:

- `convertTo` (string): If given, also convert to that format instead of only diagnosing
- `file` (string): Path to a specific Makefile
- `files` (array): Project paths: used to know whether a target already exists on disk
- `project` (string): Project folder: its Makefile and its real paths are read
- `text` (string): The Makefile pasted

### `ignore_check` (~236 tokens)

Say which paths a `.gitignore` or `.dockerignore` ignores AND BY WHICH LINE — it is `git check-ignore -v` without git. And it does what no other tool does: it reads the SAME file as git and as Docker and points at where they do NOT decide the same. The two formats look alike and are not: a pattern with no slashes (`node_modules`) applies at any depth in git but ONLY at the root in Docker, so a `.dockerignore` copied from a `.gitignore` pulls into the build context exactly what you thought you had excluded. It also warns about the `!` that cannot work because its folder is already excluded, which is the number-one cause of "my exception does nothing".

Input parameters:

- `file` (string): Path to the rules file
- `files` (array): Paths to evaluate, if no folder is given
- `mode` (string): Which rule dialect decides (default git)
- `project` (string): Project folder: its real paths are read and, failing anything else, its .gitignore
- `text` (string): The rules pasted

### `dockerfile_cache` (~236 tokens)

Say which LAYERS of a Dockerfile would be rebuilt when given files change, and which come from cache. Dockerfile linters spot suspicious ordering patterns; this SIMULATES invalidation, which is a different thing: it needs to know which files exist and which changed. In Docker, when one layer is invalidated so is EVERY layer after it, so a `COPY . .` before the `RUN` that installs dependencies condemns you to reinstalling all of them every time you touch a line of code — and that shows up here as numbers. Respects the `.dockerignore`: what stays out of the context cannot invalidate anything.

Input parameters:

- `changed` (array): Files changed since the last build. Empty = none
- `dockerignore` (string): .dockerignore rules pasted (otherwise looked up in the folder)
- `file` (string): Path to a specific Dockerfile
- `files` (array): Project paths, if no folder is given
- `project` (string): Project folder: its Dockerfile, .dockerignore and files are read
- `text` (string): The Dockerfile pasted

### `test_audit` (~216 tokens)

Audit a test file and say, case by case, what it ACTUALLY checks: which ones assert about a value, which only check that something exists, which assert nothing at all, and which are disabled. Returns the EVIDENCE behind each verdict (the assertions it found) so you can check the checker. TypeScript, JavaScript, Python, Java and Go. Executes nothing. Run it on the tests you just wrote, BEFORE you hand them over: told to "make the tests pass", widening a matcher is cheaper than fixing the bug, and this is what notices.

Input parameters:

- `dialects` (array): Your own assertion helpers. If your team has a home-made expect(), declare it here and it will stop coming back as "indeterminate".
- `language` (string): Required if you pass `text` without `path`.
- `path` (string): Path to the test file. The language is inferred from the extension.
- `text` (string): The test file as text. Alternative to `path`.

### `test_diff_audit` (~183 tokens)

Compare TWO versions of the same test file and say whether the change STRENGTHENED or WEAKENED the safety net: widened matchers (toBe -> toContain -> toBeGreaterThan), assertions that disappeared, and cases that stopped running. Call it on your own work after touching tests, and above all after fixing a red suite: reaching green by softening an assertion is cheaper than fixing the bug, and this is what catches it. Executes nothing.

Input parameters:

- `after` (string): New version, as text.
- `afterPath` (string): Path to the new version.
- `before` (string): Previous version, as text.
- `beforePath` (string): Path to the previous version (e.g. what `git show HEAD:file` produced).
- `language` (string): Required if you pass the texts without paths.

### `element_info` (~90 tokens)

Data sheet for an element by atomic number or symbol: name, mass, category, group/period/block, electronegativity, radius, ionization energy and electron affinity. Data that does NOT exist comes back as null, never as 0 — a noble gas has no electron affinity, and that is not "zero".

Input parameters:

- `element` (string, required): Atomic number ("26") or symbol ("Fe")

### `element_config` (~95 tokens)

Electron configuration of a neutral element, full and noble-gas abbreviated, with its shells and valence. Flags whether the element is one of the 20 real ANOMALIES (Cr, Cu, Nb, Ru, Pd...) — exactly where the Madelung rule fails and a language model tends to get the rule right and the element wrong.

Input parameters:

- `element` (string, required): Atomic number ("24") or symbol ("Cr")

### `element_ion_config` (~105 tokens)

Electron configuration of an ION. Electrons leave from the HIGHEST n shell, not from the last orbital that was filled: Fe2+ is [Ar]3d6, not [Ar]3d4 4s2. This is the classic mistake and the one seen most often in generated answers.

Input parameters:

- `charge` (integer, required): Charge: +2 for Fe2+, -1 for Cl-
- `element` (string, required): Atomic number or symbol

### `hydrogen_spectrum` (~125 tokens)

Hydrogen spectral lines for a series (nLow=1 Lyman, 2 Balmer, 3 Paschen...). Gives the wavelength IN VACUUM and IN AIR, which are different numbers: H-alpha is 656.47 nm in vacuum and 656.28 in air, and confusing them is common. Uses the reduced-mass Rydberg constant (R_H), not R-infinity.

Input parameters:

- `count` (integer)
- `nLow` (integer, required): Landing level: 1=Lyman, 2=Balmer, 3=Paschen

### `semiconductor_carriers` (~107 tokens)

Carrier concentrations in a doped semiconductor at a given temperature: n, p, band gap (Varshni), intrinsic concentration and Fermi level. The minority carrier is computed as ni^2/majority to avoid the catastrophic cancellation that destroys precision when subtracting nearly equal dopings.

Input parameters:

- `acceptors` (number): Na in cm^-3
- `donors` (number): Nd in cm^-3
- `material` (string)
- `temperatureK` (number)

### `bond_energy` (~151 tokens)

Energy curve between the two atoms of a measured diatomic molecule: bond length, well depth (De), REAL dissociation energy (D0) and zero-point energy. D0 is NOT De — the molecule is never at rest at the bottom of the well, not even at 0 K, and in H2 the difference is 0.27 eV. Covalent bonds use Morse, noble gases use Lennard-Jones.

Input parameters:

- `molecule` (string, required): H2, N2, O2, F2, Cl2, HF, HCl, Li2, Na2, He2, Ne2, Ar2, Kr2, Xe2
- `temperatureK` (number)

### `band_formation` (~131 tokens)

A tight-binding chain of N atoms: the N levels it produces, the bandwidth, and the spacing between levels. Shows where a band COMES FROM — with 2 atoms the level splits in two (alpha +/- beta), and with many the spacing falls as 1/N until it drops below k_B*T, which is when talking about individual levels stops making sense.

Input parameters:

- `alpha` (number): Energy of the isolated atomic orbital (eV)
- `atoms` (integer)
- `beta` (number): Integral de salto β (eV, negativa)
- `electronsPerAtom` (number)

### `coulomb_blockade` (~159 tokens)

Single-electron transistor: charging energy E_C, whether Coulomb blockade occurs, and why it does not when it fails. Checks BOTH conditions — E_C >> k_B*T and tunnel barriers above the resistance quantum R_K = h/e^2 ~ 25.8 kOhm. The second is almost never mentioned, and without it a design with perfect energy still does not blockade.

Input parameters:

- `epsR` (number): Permittivity of the surroundings: 1 vacuum, 3.9 SiO2, 11.7 Si
- `gateFraction` (number)
- `radiusNm` (number)
- `temperatureK` (number)
- `tunnelKOhm` (number): Resistance of each tunnel barrier

### `gate_geometry` (~129 tokens)

Why the transistor changed shape: natural length lambda and minimum gate length (5*lambda) for each architecture — planar, FD-SOI, FinFET, GAA nanosheet, nanowire, forksheet and CFET — at the SAME dimensions, which is what isolates the effect of geometry alone. It does not tabulate real process-node dimensions, because those are not public.

Input parameters:

- `bodyNm` (number): Channel thickness (fin width or sheet thickness)
- `gateLengthNm` (number)
- `oxideNm` (number): EOT
- `temperatureK` (number)

### `sram_noise_margin` (~300 tokens)

Static noise margin (SNM) of a 6T SRAM cell by the butterfly method: two cross-coupled transfer curves and the side of the largest inscribed square. Returns the margin per mode (hold/read/write), the per-lobe split (which side would flip) and, optionally, the margin expressed in sigmas and the array failure probability. NOT the diagonal shortcut, which returns twice the correct value. First-order Shichman-Hodges: no body effect, no process variation, no parasitics — it shows why the margin moves, it is not a silicon signature.

Input parameters:

- `cellRatio` (number): Pull-down / access width ratio. Rules read stability
- `cells` (number): Array size, with sigmaMv, for the probability that at least one cell fails
- `lambda` (number): Channel-length modulation (1/V)
- `mode` (string): read opens the word line with both bit lines precharged (read disturb); in write, 0 is the correct result
- `pullUpRatio` (number): Pull-up / access width ratio. Too high and the cell refuses to be written
- `sigmaMv` (number): Cell-to-cell spread of the margin (mV), to express the SNM in sigmas
- `vdd` (number): Supply voltage (V)
- `vth` (number): Threshold voltage, same for nMOS and pMOS (V)

### `sram_read_path` (~240 tokens)

SRAM read timing from dV = I*t/C: bit-line capacitance, signal needed, and how long before a 1 can be told from a 0. The signal needed is the amplifier sensitivity PLUS several sigmas of its offset, which usually dominates. Also returns the time for 1/2/4/8 banks. First-order: constant cell current, capacitance linear in cell count, no line resistance or column coupling. The reads-per-second figure is signal development only — a real read adds precharge, decoding and amplification.

Input parameters:

- `banks` (integer): How many banks the column is split into
- `cPerCellFf` (number): Capacitance each cell adds (fF)
- `cellCurrentUa` (number): Current with which the cell discharges the line
- `cellsPerColumn` (number): Cells hanging off each bit line: this sets the capacitance
- `offsetSigmaMv` (number): Amplifier offset, one sigma
- `sensitivityMv` (number): Smallest difference the amplifier resolves nominally
- `sigmas` (number): Sigmas of offset demanded as margin

### `ir_drop` (~239 tokens)

IR drop across a power delivery grid: worst and mean voltage lost, and where the worst is. Solves the 2D resistive network (GV=I) with sparse conjugate gradient. Use it to compare frontside delivery (entry points further apart) against backside (spread out, lower-resistance metal) at the SAME load, which is the only comparison that means anything. First-order: uniform single-layer mesh, static and equal load per region, no inductive coupling, no switching. Real designs are signed off at 0.5-2.5 % of Vdd.

Input parameters:

- `n` (integer): Mesh side: n x n nodes. Each node is a REGION of the block, not one cell
- `nodeCurrentMa` (number): Load of each region
- `segmentOhm` (number): Metal resistance between two neighbouring nodes
- `sourcePitch` (integer): Spacing between entry points in grid mode. The lever that matters most
- `sources` (string): edge = current enters only around the perimeter; grid = entry points every `sourcePitch` nodes
- `vdd` (number)

### `standard_cell` (~264 tokens)

Standard-cell geometry from its height in TRACKS: height, area, tracks left free for routing, fins per transistor, density and power-rail resistance — plus what you gain and lose against another height. The rail resistance it returns is what ir_drop consumes. Warns when the height does not land on the routing grid, which misaligns pins when alternate rows are flipped to share a rail. Idealised geometry: no real design rules, no vias, no parasitic extraction.

Input parameters:

- `compareWithTracks` (number): Compare against a cell of that height and return what is gained and lost
- `cppNm` (number): Contacted poly pitch
- `finPitchNm` (number)
- `pitchNm` (number): Routing-layer pitch: what one track is worth
- `rSheetOhmSq` (number): Sheet resistance of the rail metal (ohm/square)
- `railTracks` (number): Tracks consumed by BOTH rails together (VDD and VSS)
- `tracks` (number): Height in routing tracks. Real libraries run ~6 to ~12; half tracks (7.5T) are legitimate
- `widthCpp` (number): Cell width in CPP: an inverter is 2, a NAND2 is 3

### `timing_path` (~259 tokens)

Synchronous path analysis: setup and hold slack, and maximum frequency. The clock period appears ONLY in the setup check, so a setup failure is fixed by lowering the frequency and a hold failure is not — no speed makes it work. Skew enters both with opposite signs. With irDropV+vdd+vth it also derates the logic by voltage (alpha-power law), connecting power delivery to the clock. First-order: ONE path, delays as numbers, no process variation, no jitter, no temperature derating.

Input parameters:

- `irDropV` (number): With vdd and vth: slows the logic down by that voltage drop
- `tclkNs` (number): Clock period
- `tcqNs` (number): Launch flop delay, edge to output
- `tholdNs` (number)
- `tlogicMinNs` (number): Logic, SHORT path. Rules hold
- `tlogicNs` (number): Logic, LONG path. Rules setup
- `tsetupNs` (number)
- `tskewNs` (number): Positive = the clock reaches the capturing flop LATER: gives setup, takes hold
- `vdd` (number)
- `vth` (number)

### `make_log_diff` (~254 tokens)

Compare the output of a REAL `make` run with what the simulation predicted, matching each command in the log to the Makefile rule that produced it. **What makes this useful, rather than any log analyzer, is the diff:** if make rebuilt something the simulation considered cached, that is the signature of an UNDECLARED DEPENDENCY — it raises no error, it just makes the build slower than it should be, or occasionally fails to rebuild what it should. Line-to-rule matching is APPROXIMATE and each match carries its confidence: recipes are echoed after variable expansion, a leading `@` suppresses them entirely, implicit rules produce commands that are not in the file, and with `-j` the output interleaves. make emits no timestamps, so nothing is said about how long anything took.

Input parameters:

- `log` (string): make's output, pasted
- `logFile` (string): Path to a file with make's output
- `makefile` (string): The Makefile pasted, if no folder is given
- `project` (string): Project folder: its Makefile and real mtimes are read
- `targets` (array): What was asked to be built, if known

### `test_cases` (~188 tokens)

From a TYPE to the cases worth testing, with no model involved: equivalence partitions and boundary values derived from a TypeScript signature or a JSON Schema. For each parameter it returns the TECHNIQUE that applies and why — boundary values only mean something where there is an ordering, so they are NOT applied to a boolean or an enum. It adds the properties that can be asserted without knowing the domain, plus a fast-check test ready to paste. Use it BEFORE writing the tests, so you do not miss the cases everyone misses.

Input parameters:

- `name` (string): Function name for the generated code. Inferred from the signature if you pass one.
- `schema` (string): JSON Schema (an object with `properties`). Alternative to `signature`.
- `signature` (string): TypeScript signature, e.g. function calculate(price: number, kind: 'A' | 'B'): number

### `test_debt` (~148 tokens)

A project's DISABLED-test debt, WITH ITS AGE. Walks the folder, finds every `it.skip`, `xit`, `@Ignore`, `@pytest.mark.skip` or `t.Skip`, and dates it with `git blame`. None of those cases appears in a coverage report, because as far as the runner is concerned they do not exist: this is the debt nobody measures and the one that lasts longest — disabled 'to fix later', and later never comes. Sorted oldest first, which is what makes it actionable.

Input parameters:

- `folder` (string, required): Root of the project (or subtree) to review.
- `maxFiles` (integer): Cap on how many test files to read.

### `api_collection_convert` (~129 tokens)

Convert an API collection between formats, entirely offline. Reads Postman v2.1, Insomnia, Bruno .bru, OpenAPI 3.x / Swagger 2.0 (JSON or YAML), a browser HAR, or curl commands - the format is detected. Writes Postman, Bruno (as a file tree) or curl. Reports what cannot be translated (Postman/Bruno scripts, file fields, Insomnia templates) instead of dropping it silently.

Input parameters:

- `input` (string, required): The collection, specification or curl commands, as text
- `to` (string): Output format

### `api_collection_secrets` (~97 tokens)

List the credentials hidden inside an API collection before you share it: tokens, cookies, API keys and passwords, with their location and a MASKED sample. An exported collection carries its secrets with it, and this is the file people attach to tickets. Heuristic by name: it masks what it recognises, it never claims a file is clean.

Input parameters:

- `input` (string, required): The collection, specification or curl commands, as text

### `api_code_generate` (~134 tokens)

Turn a request into pasteable code in one of eleven targets: curl, fetch, axios, Python requests, HTTPie, Go, Java, C#, PHP, PowerShell or Rust. Emits the import lines and escapes per language, and gets right the things that are habitually wrong (in C# the Content-Type belongs to the content, not the headers; in Go an unused import does not compile).

Input parameters:

- `index` (integer): Which request, if the input has several
- `input` (string, required): A curl command, or any supported collection (the first request is used)
- `language` (string)

### `api_breaking_changes` (~139 tokens)

Compare two OpenAPI specifications and say which changes BREAK a client that already exists - which is the question you actually ask before deploying, and the one a colour diff does not answer. Tells apart pairs that look identical in a diff: adding an OPTIONAL parameter breaks nothing, adding a REQUIRED one does; ADDING an enum value is safe, REMOVING one is not; dropping a query parameter is ignored, dropping a path one changes the URL. Every finding says why.

Input parameters:

- `after` (string, required): The one you want to publish
- `before` (string, required): The published specification (JSON or YAML)
- `format` (string)

### `api_cors_preflight` (~114 tokens)

Will the browser send an OPTIONS preflight before this request, and WHY? Answers without touching the network. Half of "it works in curl but not in my page" is a preflight the server does not answer, and knowing which of the three things triggers it (the method, the Content-Type or a custom header) changes where to look. Also lists the headers the browser refuses to let a page set.

Input parameters:

- `headers` (object): Request headers, as an object
- `method` (string)

### `access_check` (~336 tokens)

Evaluate "can this principal do this action on this scope, and WHY?" against a vendor-neutral identity/RBAC model that mirrors Azure RBAC, AWS IAM/Organizations, GCP Resource Manager or Kubernetes RBAC — each rule verified against the official docs (access.md). Returns a three-valued verdict — allowed / denied / indeterminate (an unmodelled condition would decide it) — with a step-by-step trace of which rule decided and why. Nothing is looked up online: you must pass the scenario data yourself in "world".

Input parameters:

- `action` (string, required): e.g. "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read" (Azure), "s3:GetObject" (AWS), "storage.objects.get" (GCP), "get:pods" (Kubernetes: "verb:resource")
- `plane` (string): Azure only: control-plane or data-plane action (Azure keeps them as separate grant sets; ignored for the other providers).
- `principalId` (string, required)
- `provider` (string, required)
- `scopeId` (string, required)
- `world` (object, required): Scenario data. Shape depends on "provider" — azure: {ambitos, pertenencias?, roles?, asignaciones?, denegaciones?}; aws: {ambitos, cuentasGestion?, identidades?, recursos?, scps?, boundaries?}; gcp:…

### `access_who_can` (~196 tokens)

The dual of access_check: given a list of candidate principals, returns which of them can do this action on this scope — each with its own verdict and trace, same shape as access_check.

Input parameters:

- `action` (string, required)
- `plane` (string)
- `principalIds` (array, required)
- `provider` (string, required)
- `scopeId` (string, required)
- `world` (object, required): Scenario data. Shape depends on "provider" — azure: {ambitos, pertenencias?, roles?, asignaciones?, denegaciones?}; aws: {ambitos, cuentasGestion?, identidades?, recursos?, scps?, boundaries?}; gcp:…

### `access_diff` (~224 tokens)

"What if" access diff: compares two versions of the same scenario (e.g. before/after removing a role assignment, or offboarding a principal) against a list of (principal, action, scope) checks, and reports who gains access and who loses it. A check that flips to/from "indeterminate" counts as neither a gain nor a loss — only a genuine allowed<->denied flip does.

Input parameters:

- `checks` (array, required)
- `provider` (string, required)
- `worldAfter` (required)
- `worldBefore` (object, required): Scenario data. Shape depends on "provider" — azure: {ambitos, pertenencias?, roles?, asignaciones?, denegaciones?}; aws: {ambitos, cuentasGestion?, identidades?, recursos?, scps?, boundaries?}; gcp:…

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp#diagnostics

## Score history

- 2026-09-20: 65
- 2026-09-19: 65
- 2026-09-18: 49
- 2026-09-17: 64
- 2026-09-16: 48
- 2026-09-15: 61
- 2026-09-14: 61
- 2026-09-13: 61
- 2026-09-12: 46

## Common questions

### What is the Jarroba Tools MCP server?

Jarroba Tools is an MCP server listed in the public MCP registry as io.github.Invarato/jarroba-tools. 104 deterministic tools for your AI: logs, tests, SQL, diagrams, SPARQL. Local, no network. This page covers its npm package (@jarroba/mcp).

### Is the Jarroba Tools MCP server safe to use?

Jarroba Tools scores 65 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Jarroba Tools MCP server expose?

Jarroba Tools exposes 104 tools: cidr_info, cidr_contains, cidr_vlsm, count_tokens, hash_text, and 99 more. Their descriptions and schemas cost roughly 13,916 tokens of context every time the server is loaded.

### Is the Jarroba Tools MCP server still maintained?

Jarroba Tools is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Jarroba Tools MCP server under?

Jarroba Tools declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/@jarroba/mcp
- Socket report: https://socket.dev/npm/package/@jarroba/mcp
- Changelog RSS feed: https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp.json
- HTML version of this page: https://verifymcp.io/servers/invarato-jarroba-tools/jarroba-mcp
