Python — 144 Operations for AI Agents

This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Python code through the act MCP server. 144 operations available: 70 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.

18Query
70Refactor
42Analysis
14Verify

Worked Python examples

act101 follows Python's own conventions instead of imposing generic ones. An else clause that survives only because its if branch already returns gets removed and de-indented, and an else: block holding nothing but a single nested if flattens into an elif — in a tail position or mid-chain alike. Both rewrites reduce indentation or line count without changing what the function returns, matching PEP 8's own preference for the flatter, more direct form. Each example below is the verbatim output of the command shown, run against the file shown.

Flatten a mid-chain else-if into elif

sign.py classifies x with if x > 0: … else: if x < 0: … else: … — the inner if is the only statement in its else block.

$ act refactor-lang move_else_to_elif --file sign.py --params '{"line":3,"column":1}'

Before

if x > 0:
    result = "positive"
else:
    if x < 0:
        result = "negative"
    else:
        result = "zero"

After

if x > 0:
    result = "positive"
elif x < 0:
    result = "negative"
else:
    result = "zero"

The else: line and its nested if x < 0: collapse into elif x < 0:, keeping the final else for the zero case; the assignments themselves do not move.

Remove an else clause that only survives because if already returns

get_label always returns from the if branch, so the trailing else is dead weight.

$ act refactor-lang remove_unnecessary_else --file labels.py --params '{"line":3,"column":5}'

Before

def get_label(value):
    if value is None:
        return "empty"
    else:
        return str(value)

After

def get_label(value):
    if value is None:
        return "empty"
    return str(value)

The else: is removed and return str(value) de-indents to the function body — same behavior, one line shorter.

Flatten a nested else-if into elif

categorize's else: block holds nothing but a single nested if n > 10: ... else: ..., one indentation level deeper than it needs to be.

$ act refactor-lang move_else_to_elif --file categorize.py --params '{"line":4,"column":5}'

Before

def categorize(n):
    if n > 100:
        category = "large"
    else:
        if n > 10:
            category = "medium"
        else:
            category = "small"
    return category

After

def categorize(n):
    if n > 100:
        category = "large"
    elif n > 10:
        category = "medium"
    else:
        category = "small"
    return category

The else: line and its nested if n > 10: collapse into a single elif n > 10:, dropping one level of nesting; the large/medium/small branches and the trailing return category are unchanged.

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-decorator Add decorator to function/class
add-import Add an import statement for a fully-qualified class path
add-return-statement Add a return statement to a function
add-type-annotation Add type annotation to parameter or return type
add-type-hints Add type hints to function parameters
change-signature Change function signature: parameters and return type
change-visibility Change visibility/access modifier
combine Combine statements
convert-comprehension Convert between loop and comprehension
convert-for Convert for loop patterns
convert-fstring Convert to f-string formatting
convert-if-else Convert between if-else patterns
convert-if-to-ternary Convert if-else statement to ternary expression
convert-is-operator Convert an instanceof-style check using the is operator
convert-sync Convert async function to synchronous
convert-ternary Convert ternary expressions and conditionals
convert-ternary-to-if-else Convert ternary expression to if-else statement
convert-to-async Convert synchronous code to async
convert-to-dataclass Convert class to dataclass
convert-var-to-const Convert variable to constant
delete Delete unused symbol
encapsulate Encapsulate field with getter/setter
extract-class Extract methods/fields to new class
extract-constant Extract value to named constant
extract-function Extract code into a new function
extract-interface Create interface from class
extract-variable Extract expression to variable
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)]
generate-accessors Generate getters/setters for fields
generate-builder Generate builder class for target class
generate-constructor Generate constructor from fields
generate-docstring Generate docstring for function/class
generate-equals Generate __eq__ method
generate-hash Generate __hash__ method
generate-init Generate __init__ method
generate-repr Generate __repr__ method
generate-tests Generate test function stubs
generate-to-json Generate JSON serialization from fields
generate-to-string Generate __str__ method
import-add Add import statement
import-alias Add or change import alias
import-organize Organize imports in PEP 8 style
import-remove Remove unused import statement
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 Inline variable or constant
inline-function Inline function call at call site
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)]
introduce-field Extract value to class field
introduce-parameter Convert local variable to parameter
introduce-variable Extract expression to local variable
merge-if-statements Merge nested if statements into one
move Move symbol to different location
move-else-to-elif Convert else-if nesting to elif
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)]
organize-imports Organize and sort imports
pull-up Pull up member to parent class
push-down Push down member to subclass
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-dead-code remove unreachable statements after return
remove-type-annotation Remove type annotation from variable declaration
remove-unnecessary-else Remove unnecessary else after return/raise
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 Rename symbol and all references
simplify-boolean-expression Simplify boolean expression
sort-imports Sort import statements alphabetically
split Split statement or declaration
wrap-if Wrap code in if statement
wrap-null-check Wrap code in null/None check guard
wrap-try-catch Wrap code in try-except block

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

← PuppetQML →