Atlas / Skills / czlonkowski / n8n Code Tool Skill

n8n Code Tool SkillSAFE

skills/czlonkowski/n8n-code-tool

n8n skillset for Claude Code to build flawless n8n workflows

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
MIT
Stars
6,516
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Expert guidance for writing code inside the n8n Custom Code Tool (@n8n/n8n-nodes-langchain.toolCode) — the AI-agent-callable tool, not the regular Code node.

⚠️ This is NOT the Code node

Same editor UI, completely different contract:

If you carry over Code-node habits, it fails with cryptic errors. This skill teaches the Code Tool's actual contract.

What This Skill Teaches

Core Concepts

  1. Return a string — JSON.stringify() for structured output
  2. Input lives in `query` (JS) or _query (Python)
  3. No `$fromAI()` — doesn't exist in this sandbox
  4. Unstructured vs structured input — when to add a JSON Schema
  5. Tool name and description are the LLM-facing contract, not docs

Top 5 Errors This Skill Prevents

  1. "Cannot assign to read only property 'name'..." — $fromAI() misuse
  2. "Wrong output type returned" — returning [{json:{...}}]
  3. "The response property should be a string, but it is an object" — unstringified object
  4. AI never calls the tool — generic name or vague description
  5. LLM sends malformed query — no schema, no example

Skill Activation

Activates when you:

  • Build a Code Tool attached to an AI Agent
  • Get "Wrong output type returned" or "No execution data available" errors
  • Decide between unstructured query parsing and specifyInputSchema
  • Wonder why $fromAI() or $helpers.httpRequest() don't work
  • Choose between Code Tool, HTTP Request Tool, and toolWorkflow

Example queries:

  • "Why is my Code Tool throwing 'Wrong output type returned'
Read from source at commit e25b729cc88aOBSERVED · 2026-10-24
Advertisement
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: n8n-code-tool
description: "Write JavaScript or Python for the n8n Custom Code Tool (@n8n/n8n-nodes-langchain.toolCode) — the AI-agent-callable tool, NOT the workflow Code node. Use when building a Code Tool attached to an AI Agent, writing code that an LLM will invoke, parsing the `query` input, returning a string result, defining an input schema for structured arguments (specifyInputSchema, jsonSchemaExample, DynamicStructuredTool), or troubleshooting errors like \"Wrong output type returned\", \"No execution data available\", \"The response property should be a string, but it is an object\", \"Cannot assign to read only property 'name'\", or an AI agent that refuses to call the tool. Covers the critical differences between Code node and Code Tool: return format (string vs `[{json:{...}}]`), unavailability of `$fromAI`/`$input`/`$helpers` in the Code Tool sandbox, naming rules for AI invocation, and when to use `toolWorkflow`/HTTP Request Tool instead."
---

# n8n Custom Code Tool

Expert guidance for writing code inside `@n8n/n8n-nodes-langchain.toolCode` — the tool an AI Agent can invoke, **not** the regular workflow Code node.

---

## ⚠️ This is NOT the Code node

The Custom Code Tool looks like a Code node in the editor — same JavaScript editor, similar layout — but it is a **completely different node** from a different package with a **different runtime contract**.

| | Code node | Custom Code Tool |
|---|---|---|
| **Node type** | `n8n-nodes-base.code` | `@n8n/n8n-nodes-langchain.toolCode` |
| **Package** | `n8n-nodes-base` | `@n8n/n8n-nodes-langchain` |
| **Invoked by** | Previous node (workflow flow) | AI Agent (LangChain) |
| **Input** | `$input.all()` — item stream | `query` — string or object from LLM |
| **Return** | `[{json: {...}}]` (items array) | **A string** |
| **`$fromAI()`** | N/A | **Not available** (see Errors) |
| **HTTP helper** | `this.helpers.httpRequest` (auth helpers blocked) | Not exposed to the tool sandbox |
| **State** | Per-run execution data | No `getContext`, no `$getWorkflowStaticData` |

**If you treat it like a Code node, it fails.** The rest of this skill covers the Code Tool's actual contract.

---

## Quick Start

### Minimal JavaScript Code Tool

```javascript
// `query` is whatever the AI sent (a string by default)
return `You asked: ${query}`;
```

### Minimal Python Code Tool

```python
# `_query` is whatever the AI sent (a string by default)
return f"You asked: {_query}"
```

### Essential Rules

1. **Return a string.** Numbers are auto-converted. Anything else throws `"The response property should be a string, but it is an object"`.
2. **Input variable is fixed**: `query` (JS), `_query` (Python). You cannot rename it.
3. **Do NOT use `$fromAI()`** inside the Code Tool sandbox — it throws `"No execution data available"`.
4. **Do NOT use `[{json: {...}}]`** return format — that's for Code nodes. Throws `"Wrong output type returned"`.
5. **Use a descriptive tool name** (letters/numbers/underscores, v1.1+). The agent calls the tool by its name.
6. **Write a precise description** — the LLM decides whether to invoke the tool based on it.

---

## The Two Input Modes

The Code Tool has two input shapes, controlled by `specifyInputSchema`:

### Mode 1: Unstructured (default, `specifyInputSchema: false`)

The AI passes **a single string** as `query`. If you need multiple fields, the AI has to stuff them into that one string and you parse them out. In practice, LLMs will happily pass a JSON string if your description tells them to.

```javascript
// Parse a JSON string the AI sent
let params;
try {
  params = typeof query === 'string' ? JSON.parse(query) : query;
} catch (e) {
  throw new Error('Expected a JSON object. Parser said: ' + e.message);
}
const price = Number(params.price);
const months = Number(params.months);
// ...
return JSON.stringify({ monthly_payment: /* ... */ });
```

**Pros**: simplest to set up, one field to describe.
**Cons**: no schema validation — if the LLM forgets a field, the tool throws at runtime.

**Best for**: quick prototypes, tools with one natural input (a question, a URL, a text blob).

### Mode 2: Structured (`specifyInputSchema: true`)

The tool becomes a LangChain `DynamicStructuredTool`. The LLM sees a typed argument schema and passes a **validated object** as `query`. You access fields directly.

```javascript
// query is now an object matching your schema
const price = query.price;
const months = query.months;
const residual_percent = query.residual_percent;

const monthly = computeAnnuity(price, months, residual_percent);
return JSON.stringify({ monthly_payment: monthly });
```

Schema is defined via either:
- `schemaType: "fromJson"` + `jsonSchemaExample` (n8n v≥1.3) — paste an example JSON, n8n infers the schema
- `schemaType: "manual"` + `inputSchema` — write a full JSON Schema yourself

**Pros**: LLM gets type hints, invalid calls rejected before your code runs, cleaner code.
**Cons**: a little more setup; requires n8n version with schema support.

**Best for**: production tools with multiple typed parameters (calculators, API wrappers, anything with numeric fields the LLM tends to stringify).

**See**: [INPUT_SCHEMA.md](INPUT_SCHEMA.md) for complete schema setup.

---

## Return Format

**The return value must be a string.** The LLM reads it as the tool's observation.

```javascript
// ✅ String
return "42";

// ✅ Number (auto-converted to string by n8n)
return 42;

// ✅ JSON-encoded structured result (recommended for rich output)
return JSON.stringify({ result: 42, currency: "SEK" });

// ❌ Raw object → "The response property should be a string, but it is an object"
return { result: 42 };

// ❌ Workflow item format → "Wrong output type returned"
return [{ json: { result: 42 } }];

// ❌ Array → "The response property should be a string, but it is an object"
return [1, 2, 3];
```

### Best practice: JSON-stringify structured results

When your tool has more than a trivial scalar output, return
03

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (0)

No findings outside the package's declared scope.

Gates applied: no_behavioural_pass.

Audited 2026-10-24 · audit v0.4.1 · source sha e25b729cc88afull audit observations/trust-audit/skill/czlonkowski__n8n-code-tool.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-24e25b729cc88aSAFEB89first audit
05

Questions

What does the n8n-code-tool — czlonkowski/n8n-skills skill do?

n8n skillset for Claude Code to build flawless n8n workflows

Is n8n-code-tool — czlonkowski/n8n-skills safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can n8n-code-tool — czlonkowski/n8n-skills access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (e25b729cc88a), read on 2026-10-24. The repository is watched, and a new audit runs when it changes — this is the first audit.

Add this badge to your README

Shows this page's audit result and links back to it. It updates when the audit does.

ModelsAtlas audit badge

Markdown
[![ModelsAtlas audit: n8n Code Tool Skill](https://modelsatlas.com/skills/czlonkowski/n8n-code-tool/badge.svg)](https://modelsatlas.com/skills/czlonkowski/n8n-code-tool/)

Not your listing, or something out of date? Claim or update your listing.

Advertisement