{
  "status": "ok",
  "protocol": "mcp",
  "protocolVersion": "2024-11-05",
  "server": {
    "name": "nine",
    "title": "Nine — AI Financial Secretary & Workspace Platform",
    "description": "Native Model Context Protocol (MCP) server for Nine (ninehoang.com). Enables AI agents (Gemini, Claude, ChatGPT, Cursor) to manage workspace expenses, track group funds, log income and payouts, and search member directories.",
    "version": "1.0.0"
  },
  "tools": [
    {
      "name": "create_expense",
      "description": "Record a new expense in Nine (e.g. coffee, meals, groceries, local transport, travel, shopping). Automatically records amount, category, payment method, and timestamps into the workspace ledger.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Title or vendor of the expense (e.g. 'Coffee with team', 'Lunch at Pho 24', 'Grab taxi to office')"
          },
          "amount": {
            "type": "number",
            "description": "Expense amount as a positive whole number of VND (e.g. 65000 for 65,000 ₫). Every row here is an expense, so there is no negative side and no decimals."
          },
          "category_id": {
            "type": "string",
            "enum": [
              "beauty-care",
              "clothing",
              "credit-repayment",
              "entertainment",
              "essentials",
              "family-support",
              "fixed-expenses",
              "food-drinks",
              "installment-payment",
              "investments",
              "local-transport",
              "other",
              "sports",
              "travel",
              "work-expenses"
            ],
            "description": "Expense category classification"
          },
          "method_id": {
            "type": "string",
            "enum": [
              "bank-transfer",
              "cash",
              "credit-card",
              "installment",
              "mobile-wallet"
            ],
            "description": "Payment method used for the expense"
          },
          "occurred_at": {
            "type": "string",
            "description": "ISO timestamp (e.g. 2026-08-25T15:00:00Z). Defaults to current timestamp if omitted."
          },
          "note": {
            "type": "string",
            "description": "Optional extra notes, receipts, or context"
          }
        },
        "required": [
          "name",
          "amount",
          "category_id",
          "method_id"
        ]
      }
    },
    {
      "name": "list_expenses",
      "description": "Retrieve recent expense records from Nine with total amounts, categories, and date filters for financial tracking, spending analytics, and budget reviews. Supports querying up to 1,000 records per call, date ranges, search, and pagination.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "number",
            "description": "Maximum number of expenses to retrieve (default: 50, max: 1000)"
          },
          "offset": {
            "type": "number",
            "description": "Offset for pagination (default: 0)"
          },
          "category_id": {
            "type": "string",
            "description": "Filter expenses by category slug (e.g. 'food-drinks', 'local-transport')"
          },
          "method_id": {
            "type": "string",
            "description": "Filter expenses by payment method slug (e.g. 'cash', 'bank-transfer')"
          },
          "start_date": {
            "type": "string",
            "description": "Filter expenses occurred on or after this date (ISO or YYYY-MM-DD, e.g. '2026-08-01')"
          },
          "end_date": {
            "type": "string",
            "description": "Filter expenses occurred on or before this date (ISO or YYYY-MM-DD, e.g. '2026-08-31')"
          },
          "search": {
            "type": "string",
            "description": "Search keyword matching expense title or notes"
          }
        }
      }
    },
    {
      "name": "update_expense",
      "description": "Update an existing expense in Nine by its UUID (modify amount, category, title, payment method, date, or notes).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "UUID of the expense to update"
          },
          "name": {
            "type": "string",
            "description": "Updated title or vendor"
          },
          "amount": {
            "type": "number",
            "description": "Updated expense amount"
          },
          "category_id": {
            "type": "string",
            "enum": [
              "beauty-care",
              "clothing",
              "credit-repayment",
              "entertainment",
              "essentials",
              "family-support",
              "fixed-expenses",
              "food-drinks",
              "installment-payment",
              "investments",
              "local-transport",
              "other",
              "sports",
              "travel",
              "work-expenses"
            ],
            "description": "Updated expense category"
          },
          "method_id": {
            "type": "string",
            "enum": [
              "bank-transfer",
              "cash",
              "credit-card",
              "installment",
              "mobile-wallet"
            ],
            "description": "Updated payment method"
          },
          "occurred_at": {
            "type": "string",
            "description": "Updated ISO timestamp"
          },
          "note": {
            "type": "string",
            "description": "Updated note or context"
          }
        },
        "required": [
          "id"
        ]
      }
    },
    {
      "name": "delete_expense",
      "description": "Delete an expense record from Nine by its UUID.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "UUID of the expense to delete"
          }
        },
        "required": [
          "id"
        ]
      }
    },
    {
      "name": "list_recurring_expenses",
      "description": "List configured recurring expense schedules, subscriptions, and loop rules in Nine with amounts, periods, and next due dates.",
      "inputSchema": {
        "type": "object",
        "properties": {}
      }
    },
    {
      "name": "create_recurring_expense",
      "description": "Create a scheduled recurring expense rule (loop logic date) in Nine (e.g. monthly rent, weekly groceries, streaming subscriptions).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Title of the recurring expense (e.g. 'Apartment Rent', 'Netflix', 'Internet')"
          },
          "amount": {
            "type": "number",
            "description": "Expense amount as a positive whole number of VND (e.g. 5000000 for 5,000,000 ₫)"
          },
          "category_id": {
            "type": "string",
            "enum": [
              "beauty-care",
              "clothing",
              "credit-repayment",
              "entertainment",
              "essentials",
              "family-support",
              "fixed-expenses",
              "food-drinks",
              "installment-payment",
              "investments",
              "local-transport",
              "other",
              "sports",
              "travel",
              "work-expenses"
            ],
            "description": "Expense category classification"
          },
          "method_id": {
            "type": "string",
            "enum": [
              "bank-transfer",
              "cash",
              "credit-card",
              "installment",
              "mobile-wallet"
            ],
            "description": "Payment method used"
          },
          "period": {
            "type": "string",
            "enum": [
              "Daily",
              "Weekly",
              "Monthly",
              "Yearly"
            ],
            "description": "Recurrence frequency ('Daily', 'Weekly', 'Monthly', 'Yearly')"
          },
          "day_of_month": {
            "type": "number",
            "description": "Day of the month for monthly recurring expenses (1–31)"
          },
          "start_date": {
            "type": "string",
            "description": "Start date in YYYY-MM-DD format (defaults to current date)"
          },
          "note": {
            "type": "string",
            "description": "Optional notes or details"
          }
        },
        "required": [
          "name",
          "amount",
          "category_id",
          "method_id",
          "period"
        ]
      }
    },
    {
      "name": "post_due_recurring_expenses",
      "description": "Post all overdue recurring expense rules into the personal transactions ledger and advance their next due dates.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "until_date": {
            "type": "string",
            "description": "Cutoff date (YYYY-MM-DD). Defaults to today if omitted."
          }
        }
      }
    },
    {
      "name": "list_funds",
      "description": "List all collective group funds, travel pools, event budgets, target savings goals, and real-time fund balance totals in Nine.",
      "inputSchema": {
        "type": "object",
        "properties": {}
      }
    },
    {
      "name": "get_fund",
      "description": "Retrieve full details of a specific group fund including budget targets, status, participants, and recent ledger entries.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fund_id": {
            "type": "string",
            "description": "UUID of the target fund"
          }
        },
        "required": [
          "fund_id"
        ]
      }
    },
    {
      "name": "create_fund",
      "description": "Create a new collective group fund in Nine (e.g. 'Da Nang Summer Trip', 'Badminton Season Q3', 'Office Party Fund').",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the group fund"
          },
          "kind": {
            "type": "string",
            "enum": [
              "Travel",
              "Badminton"
            ],
            "description": "Fund type/kind (default: 'Travel')"
          },
          "status": {
            "type": "string",
            "enum": [
              "Upcoming",
              "In Progress",
              "Completed"
            ],
            "description": "Fund lifecycle status (default: 'Upcoming')"
          },
          "start_date": {
            "type": "string",
            "description": "Date the fund starts (YYYY-MM-DD)"
          },
          "end_date": {
            "type": "string",
            "description": "Date the fund ends (YYYY-MM-DD)"
          }
        },
        "required": [
          "name"
        ]
      }
    },
    {
      "name": "update_fund",
      "description": "Update a group fund's name, kind, lifecycle status ('Upcoming', 'In Progress', 'Completed'), or start/end dates.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fund_id": {
            "type": "string",
            "description": "UUID of the fund to update"
          },
          "name": {
            "type": "string",
            "description": "Updated fund name"
          },
          "status": {
            "type": "string",
            "enum": [
              "Upcoming",
              "In Progress",
              "Completed"
            ],
            "description": "Updated fund lifecycle status"
          },
          "kind": {
            "type": "string",
            "enum": [
              "Travel",
              "Badminton"
            ],
            "description": "Updated fund type"
          },
          "start_date": {
            "type": "string",
            "description": "Updated start date (YYYY-MM-DD)"
          },
          "end_date": {
            "type": "string",
            "description": "Updated end date (YYYY-MM-DD)"
          }
        },
        "required": [
          "fund_id"
        ]
      }
    },
    {
      "name": "create_fund_transaction",
      "description": "Record an income contribution or expense payout in a shared group fund (e.g. group travel outlays, sports dues, party contributions).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fund_id": {
            "type": "string",
            "description": "UUID of the target group fund"
          },
          "name": {
            "type": "string",
            "description": "Transaction title or description (e.g. 'Monthly fund contribution', 'Court rental fee')"
          },
          "amount": {
            "type": "number",
            "description": "Signed amount in VND. The sign follows the CATEGORY, not the wording of the request: `fund-income` and `fine` are money in and take a positive amount (+500000); every other category, INCLUDING `refund`, is money out and takes a negative one (-200000)."
          },
          "category_id": {
            "type": "string",
            "enum": [
              "clothing",
              "currency-exchange",
              "entertainment",
              "fine",
              "flight-tickets",
              "food-drinks",
              "fund-income",
              "hotel",
              "local-transport",
              "other",
              "refund"
            ],
            "description": "Transaction category slug. `fund-income`, `fine` and `refund` are about a specific participant and should carry contact_id; every other category is about a vendor and leaves it unset."
          },
          "contact_id": {
            "type": "string",
            "description": "UUID of the participant this row is about — required in practice for `fund-income`, `fine` and `refund`, which are otherwise incomplete. Must be somebody already in this fund."
          },
          "note": {
            "type": "string",
            "description": "Optional extra context the title does not already say"
          },
          "method_id": {
            "type": "string",
            "enum": [
              "bank-transfer",
              "cash",
              "credit-card",
              "installment",
              "mobile-wallet"
            ],
            "description": "Payment method used"
          },
          "occurred_at": {
            "type": "string",
            "description": "ISO timestamp (e.g. 2026-08-25T18:00:00Z)"
          }
        },
        "required": [
          "fund_id",
          "name",
          "amount",
          "category_id",
          "method_id"
        ]
      }
    },
    {
      "name": "list_fund_transactions",
      "description": "List transactions, incomes, dues, or expense payouts for group funds with optional filters by fund_id, category_id, and date range.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fund_id": {
            "type": "string",
            "description": "Optional fund UUID to filter transactions for a specific group fund"
          },
          "limit": {
            "type": "number",
            "description": "Maximum number of transactions to retrieve (default: 50, max: 1000)"
          },
          "offset": {
            "type": "number",
            "description": "Offset for pagination (default: 0)"
          },
          "category_id": {
            "type": "string",
            "description": "Filter by transaction category slug (e.g. 'hotel', 'fund-income')"
          },
          "start_date": {
            "type": "string",
            "description": "Filter occurred_at on or after this date (e.g. '2026-08-01')"
          },
          "end_date": {
            "type": "string",
            "description": "Filter occurred_at on or before this date (e.g. '2026-08-31')"
          }
        }
      }
    },
    {
      "name": "delete_fund_transaction",
      "description": "Delete a fund transaction record by its UUID.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "UUID of the fund transaction to delete"
          }
        },
        "required": [
          "id"
        ]
      }
    },
    {
      "name": "list_contacts",
      "description": "Look up workspace members, participants, phone numbers, and contact directories in Nine.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "search": {
            "type": "string",
            "description": "Optional search query to find member by name, nickname, or phone"
          }
        }
      }
    },
    {
      "name": "create_contact",
      "description": "Add a new contact or participant to the workspace directory in Nine (e.g. for group fund splitting and member tracking).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Full name of the contact"
          },
          "nickname": {
            "type": "string",
            "description": "Short display name or nickname"
          },
          "phone": {
            "type": "string",
            "description": "Domestic phone number (e.g. '0901234567')"
          },
          "email": {
            "type": "string",
            "description": "Email address"
          },
          "gender": {
            "type": "string",
            "enum": [
              "Male",
              "Female",
              "LGBT"
            ],
            "description": "Gender option"
          },
          "nationality": {
            "type": "string",
            "enum": [
              "Vietnam",
              "Japan"
            ],
            "description": "Nationality"
          }
        },
        "required": [
          "name"
        ]
      }
    },
    {
      "name": "update_contact",
      "description": "Update contact information, name, nickname, phone, or email for a contact in the directory.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "UUID of the contact to update"
          },
          "name": {
            "type": "string",
            "description": "Updated full name"
          },
          "nickname": {
            "type": "string",
            "description": "Updated nickname"
          },
          "phone": {
            "type": "string",
            "description": "Updated phone number"
          },
          "email": {
            "type": "string",
            "description": "Updated email address"
          }
        },
        "required": [
          "id"
        ]
      }
    }
  ]
}