Noir — 127 Operations for AI Agents
Noir brings zero-knowledge programs to developers who think in functions, not constraints. act101 reads Noir's structure natively, so agents navigate circuits and their proofs-in-progress like ordinary code.
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Noir code through the act MCP server. 127 operations available: 53 refactor, 18 query, 42 analysis, 14 verification. Each operation is callable from Claude Code, Cursor, Codex, OpenCode, or any MCP-compatible agent host. Click any operation for a stable anchor link suitable for citation.
Premium language. Operations on Noir require an Elite license or above. See pricing.
Worked Noir examples
act101 parses Noir with the tree-sitter grammar and edits functions, structs, and their attributes as syntax nodes, so an attribute, modifier, or generated scaffold lands on the exact construct it targets. It can insert the #[fold] attribute immediately before a function declaration. It can insert the unconstrained modifier before a function's visibility and fn keyword. It can append a new function skeleton with one private input and one output, added after the functions already in the file. It can append a #[test] function that exercises a named public entrypoint with a sample input. And it can add a new field to an existing struct Storage declaration. Each example below is the verbatim output of the command shown, run against the file shown.
Add a fold attribute to a function
compose.nr declares compose with no attributes.
$ act refactor-lang add_fold_attribute --file compose.nr --params '{"function_name":"compose","line":1,"column":1}'
Before
fn compose(x: Field) -> Field {
x
}
After
#[fold]
fn compose(x: Field) -> Field {
x
}
#[fold] is inserted immediately above fn compose.
Convert a function to unconstrained
hash.nr declares hash as an ordinary pub fn.
$ act refactor-lang convert_to_unconstrained --file hash.nr --params '{"function_name":"hash","line":1,"column":1}'
Before
pub fn hash(x: Field) -> Field {
x
}
After
unconstrained pub fn hash(x: Field) -> Field {
x
}
pub fn hash gains the unconstrained modifier, reading unconstrained pub fn hash(...).
Scaffold a new function
circuit.nr already defines one function, existing.
$ act refactor-lang gen_zk_circuit_scaffold --file circuit.nr --params '{"function_name":"prove_balance","input_name":"private_input","input_type":"Field","output_type":"Field","line":1,"column":1}'
Before
fn existing(x: Field) -> Field {
x
}
After
fn existing(x: Field) -> Field {
x
}
fn prove_balance(private_input: Field) -> Field {
private_input
}
A new prove_balance function is appended after existing, taking a private_input: Field and returning Field.
Generate an integration test for an entrypoint
entry.nr declares the public entrypoint public_entry, which returns its Field argument unchanged, with no test covering it.
$ act refactor-lang gen_integration_test --file entry.nr --params '{"test_name":"integration_public_entry","target_name":"public_entry","line":1,"column":1}'
Before
fn public_entry(x: Field) -> Field {
x
}
After
fn public_entry(x: Field) -> Field {
x
}
#[test]
fn integration_public_entry() {
let output = public_entry(1);
assert(output == 1);
}
A #[test] function, integration_public_entry, is appended that calls public_entry(1) and asserts the result equals 1.
Add a field to the storage struct
storage.nr declares struct Storage with a single owner: Field field.
$ act refactor-lang add_contract_storage --file storage.nr --params '{"field_name":"balance","field_type":"Field","line":1,"column":1}'
Before
struct Storage {
owner: Field,
}
After
struct Storage {
owner: Field,
balance: Field,
}
balance: Field is appended as a second field inside struct Storage, after owner.
Query
18 query tools, the same on every supported language. Descriptions live in the shared reference: /docs/query-tools.
callers control_flow data_flow definition diagnostics effect_closure effect_summary fix_auto get_type graph import_organize interface mutations references repo_outline skeleton symbols symbols_batch
Refactor
| Operation | Description |
|---|---|
add-contract-storage |
Add a field to Noir contract storage |
add-field |
Add a field to a Noir struct |
add-fold-attribute |
Add #[fold] to a Noir function |
add-parameter |
Add a parameter to a Noir function |
change-parameter-type |
Change a Noir function parameter type |
change-return-type |
Change a Noir function return type |
convert-comptime-to-fn |
Convert a Noir comptime function to runtime execution |
convert-private-to-public |
Convert a private Noir function to public |
convert-public-to-private |
Convert a public Noir function to private |
convert-to-comptime-fn |
Convert a Noir function to comptime execution |
convert-to-constrained |
Convert a Noir function to constrained execution |
convert-to-global-constant |
Extract a Noir value to a global constant |
convert-to-unconstrained |
Convert a Noir function to unconstrained execution |
extract-function |
Extract selected Noir code into a new function |
extract-module |
Extract top-level declarations into an inline Noir module |
extract-struct |
Extract Noir struct fields into a new struct |
extract-to-module |
Extract Noir declarations to a module file |
extract_function |
Extract a code selection into a new function — automatically infers parameters, return types, and inserts the call site. Use instead of manually cutting/pasting code. Works without LSP; LSP improves type inference. Params: file (string), new_name (string), start_line (u32), start_column (u32), end_line (u32), end_column (u32) [, preview (bool), receipt (bool)] |
extract_variable |
Extract an expression into a named variable — inserts the declaration and replaces the expression with the variable name. Works without LSP. Params: file (string), new_name (string), start_line (u32), start_column (u32), end_line (u32), end_column (u32) [, preview (bool)] |
fix-missing-import |
Add a missing Noir use statement |
fix-type-mismatch |
Fix a Noir local variable type mismatch |
fix-unconstrained-in-proof |
Fix unconstrained Noir proof logic |
fix-unused-variable |
Fix an unused Noir local variable |
gen-contract-scaffold |
Generate a Noir contract-style module scaffold |
gen-hash-function |
Generate a Noir hash function wrapper |
gen-integration-test |
Generate a Noir integration-style test |
gen-membership-proof |
Generate a Noir membership proof helper |
gen-note-scaffold |
Generate a Noir note scaffold |
gen-nullifier-check |
Generate Noir nullifier check helpers |
gen-range-proof |
Generate a Noir range proof helper |
gen-storage-layout |
Generate a Noir storage layout struct |
gen-test-function |
Generate a Noir unit test function |
gen-zk-circuit-scaffold |
Generate a Noir ZK circuit function scaffold |
inline |
Inline a variable, function, or method — replace every usage with its definition body, then remove the original. The inverse of extract. Works without LSP (single-file); LSP enables cross-file inlining. Params: file (string), symbol (string) [, line (u32), preview (bool), receipt (bool)] |
inline-function |
Inline simple Noir function calls |
inline-global-constant |
Inline a Noir global constant |
inline-module |
Inline a Noir module into its parent scope |
insert_body |
Replace a function's implementation body with new code. AST-validated — rejects if the result has parse errors, so you can't accidentally break syntax. Use instead of manual text editing for function rewrites. Params: file (string), symbol (string), code (string) [, commit (bool)] |
merge-modules |
Merge two inline Noir modules |
move_symbol |
Move a function, class, or type to a different file and automatically update all imports across the codebase. Use instead of manually cut/paste + fixing imports. Works without LSP (single-file); LSP enables cross-file import updates. Params: file (string), symbol (string), destination (string) [, preview (bool), receipt (bool)] |
recipe_run |
Run a codemod recipe: declarative match → transform → optional verify across modeled grammars. Preview lists matches; apply writes with optional E7 receipts and all-or-nothing rollback. Returns a per-site report. |
remove-contract-storage |
Remove a field from Noir contract storage |
remove-field |
Remove a Noir struct field |
remove-fold-attribute |
Remove #[fold] from a Noir function |
remove-parameter |
Remove an unused Noir function parameter |
rename |
Rename a symbol and automatically update ALL references across the codebase. Safer and faster than find-and-replace — AST-aware, won't rename strings or comments. Works without LSP (single-file); LSP enables cross-file renames. Params: file (string), old_name (string), new_name (string) [, line (u32), column (u32), preview (bool), receipt (bool)] |
rename-field |
Rename a Noir struct field and update field access syntax |
rename-function |
Rename a Noir function and update direct call targets |
rename-module |
Rename a Noir module and update module paths |
rename-struct |
Rename a Noir struct and update type and constructor references |
rename-variable |
Rename a Noir local variable inside a function |
reorder-fields |
Reorder fields in a Noir struct |
reorder-parameters |
Reorder Noir function parameters |
Analysis
42 analysis tools, the same on every supported language. Descriptions live in the shared reference: /docs/analysis-tools.
analyze_api_diff analyze_chokepoints analyze_clones analyze_clusters analyze_cohesion analyze_conformance analyze_coupling analyze_cycle_risk analyze_cycles analyze_dead_code analyze_depth analyze_entry_points analyze_export analyze_extraction analyze_fan_balance analyze_features analyze_hotspots analyze_impact analyze_inconsistencies analyze_inheritance analyze_interface_bloat analyze_interfaces analyze_layers analyze_orphan_types analyze_patterns analyze_platform_deps analyze_readiness analyze_roles analyze_seams analyze_stability analyze_surface analyze_test_gaps analyze_thickness analyze_type_completeness churn_hotspots co_change_clusters coverage_overlay ownership_map profile_overlay simulate split_module trace_overlay
Verify
14 verify tools, the same on every supported language. Descriptions live in the shared reference: /docs/verification.
bisect_regression gate generate_test_harness scan secret_surface summarize_pr taint_flow unsafe_surface verify_behavioral_equivalence verify_contract_preserved verify_diff_semantics verify_port_parity verify_side_effects verify_test_impact