Skip to main content
Glama
norman-finance

Norman Finance MCP Server

Official

update_transaction

Modify details of an existing transaction, including amount, description, category, date, VAT rate, sale type, supplier country, and cashflow type, using the Norman Finance MCP Server.

Instructions

Update an existing transaction.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
amountNo
cashflow_typeNo
categoryNo
category_idNo
dateNo
descriptionNo
sale_typeNo
supplier_countryNo
transaction_idYes
vat_rateNo

Implementation Reference

  • The core handler function for the 'update_transaction' tool. Includes inline schema definitions via Pydantic Field descriptions and the execution logic that updates the transaction via the Norman API.
    @mcp.tool()
    async def update_transaction(
        ctx: Context,
        transaction_id: str = Field(description="Public ID of the transaction to update"),
        amount: Optional[float] = Field(description="Transaction amount (positive for income, negative for expense)"),
        description: Optional[str] = Field(description="Transaction description"),
        category: Optional[str] = Field(description="Transaction category"),
        date: Optional[str] = Field(description="Transaction date in YYYY-MM-DD format (defaults to today)"),
        vat_rate: Optional[int] = Field(description="VAT rate (0, 7, 19)"),
        sale_type: Optional[str] = Field(description="Sale type (GOODS, SERVICES)"),
        supplier_country: Optional[str] = Field(description="Country of the supplier (DE, INSIDE_EU, OUTSIDE_EU)"),
        cashflow_type: Optional[str] = Field(description="Cashflow type of the transaction (INCOME, EXPENSE)"),
        category_id: Optional[str] = Field(description="Category ID of the transaction (If not provided, the transaction will be categorized automatically using AI)"),
    ) -> Dict[str, Any]:
        """Update an existing transaction."""
        api = ctx.request_context.lifespan_context["api"]
        company_id = api.company_id
        
        if not company_id:
            return {"error": "No company available. Please authenticate first."}
        
        transaction_url = urljoin(
            config.api_base_url, 
            f"api/v1/companies/{company_id}/accounting/transactions/{transaction_id}/"
        )
        
        # Prepare update data
        update_data = {}
        if amount is not None:
            update_data["amount"] = abs(amount) if cashflow_type == "INCOME" else -abs(amount)
        if description is not None:
            update_data["description"] = description
        if category is not None:
            update_data["category"] = category
        if date is not None:
            update_data["valueDate"] = date
        if vat_rate is not None:
            update_data["vatRate"] = vat_rate
        if sale_type is not None:
            update_data["saleType"] = sale_type if sale_type else ""
        if supplier_country is not None:
            update_data["supplierCountry"] = supplier_country
        if cashflow_type is not None:
            update_data["cashflowType"] = cashflow_type
        if category_id is not None:
            update_data["category"] = category_id
            
        return api._make_request("PATCH", transaction_url, json_data=update_data)
  • Input schema for the update_transaction tool defined using Pydantic Fields with descriptions.
    async def update_transaction(
        ctx: Context,
        transaction_id: str = Field(description="Public ID of the transaction to update"),
        amount: Optional[float] = Field(description="Transaction amount (positive for income, negative for expense)"),
        description: Optional[str] = Field(description="Transaction description"),
        category: Optional[str] = Field(description="Transaction category"),
        date: Optional[str] = Field(description="Transaction date in YYYY-MM-DD format (defaults to today)"),
        vat_rate: Optional[int] = Field(description="VAT rate (0, 7, 19)"),
        sale_type: Optional[str] = Field(description="Sale type (GOODS, SERVICES)"),
        supplier_country: Optional[str] = Field(description="Country of the supplier (DE, INSIDE_EU, OUTSIDE_EU)"),
        cashflow_type: Optional[str] = Field(description="Cashflow type of the transaction (INCOME, EXPENSE)"),
        category_id: Optional[str] = Field(description="Category ID of the transaction (If not provided, the transaction will be categorized automatically using AI)"),
    ) -> Dict[str, Any]:
  • Registration call that invokes register_transaction_tools(server), which defines and registers the update_transaction tool along with other transaction tools.
    register_transaction_tools(server)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral disclosure. 'Update an existing transaction' implies a mutation operation, but it doesn't specify required permissions, whether updates are partial or full, what happens on failure, or any side effects. For a tool with 10 parameters and no annotation coverage, this is a significant gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with a single sentence: 'Update an existing transaction.' It's front-loaded and wastes no words, making it easy to parse quickly. However, this conciseness comes at the cost of completeness, as noted in other dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (10 parameters, 1 required, no output schema, and no annotations), the description is inadequate. It doesn't explain what a 'transaction' entails in this context, what fields are updatable, or what the tool returns. For a mutation tool with rich input schema but no supporting documentation, more detail is needed to guide effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 0%, meaning none of the 10 parameters have descriptions in the schema. The tool description adds no information about parameters beyond the generic 'update' action. It doesn't explain what 'amount', 'category', 'date', etc., represent or how they're used, leaving all parameters undocumented. This fails to compensate for the lack of schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Update an existing transaction' clearly states the verb ('update') and resource ('transaction'), but it's quite generic. It doesn't specify what aspects of a transaction can be updated or distinguish this tool from potential alternatives like 'update_client' or 'link_transaction' among the siblings. The purpose is understandable but lacks specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With siblings like 'create_transaction', 'search_transactions', and 'link_transaction', there's no indication of prerequisites (e.g., needing an existing transaction ID) or scenarios where this is preferred over other tools. It's a bare statement with no contextual usage information.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/norman-finance/norman-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server