qbo_navigate
Navigate to a QuickBooks Online domain to enable tools for managing customers, invoices, expenses, payments, or reports.
Instructions
Navigate to a specific domain in QuickBooks Online. Call this first to select which area you want to work with. After navigation, domain-specific tools will be available.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| domain | Yes | The domain to navigate to: - customers: Customer management - list, get, create, and search customers - invoices: Invoice management - list, get, create invoices and send them by email - expenses: Expense tracking - list and view purchases and bills - payments: Payment management - list, get, and create payments linked to invoices - reports: Financial reports - profit & loss, balance sheet, aged receivables/payables, customer sales |
Implementation Reference
- src/index.ts:99-125 (schema)Tool definition and input schema for 'qbo_navigate'. Defines the tool name, description, and input schema with a required 'domain' enum property (customers, invoices, expenses, payments, reports).
const navigateTool: Tool = { name: "qbo_navigate", description: "Navigate to a specific domain in QuickBooks Online. Call this first to select which area you want to work with. After navigation, domain-specific tools will be available.", inputSchema: { type: "object", properties: { domain: { type: "string", enum: [ "customers", "invoices", "expenses", "payments", "reports", ], description: `The domain to navigate to: - customers: ${domainDescriptions.customers} - invoices: ${domainDescriptions.invoices} - expenses: ${domainDescriptions.expenses} - payments: ${domainDescriptions.payments} - reports: ${domainDescriptions.reports}`, }, }, required: ["domain"], }, }; - src/index.ts:160-173 (registration)Registration of qbo_navigate via ListToolsRequestSchema handler. When state.currentDomain is null, the navigateTool is pushed into the available tools list, making it the entry point tool.
server.setRequestHandler(ListToolsRequestSchema, async () => { const tools: Tool[] = []; if (state.currentDomain === null) { // At root - show navigation tool only tools.push(navigateTool); } else { // In a domain - show domain tools plus back navigation tools.push(backTool); tools.push(...getDomainTools(state.currentDomain)); } return { tools }; }); - src/index.ts:178-249 (handler)Handler for 'qbo_navigate' tool call (line 183-198). Extracts the 'domain' argument, sets state.currentDomain to it, retrieves domain-specific tools, and returns a success message listing available tools for that domain.
server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { // Handle navigation if (name === "qbo_navigate") { const { domain } = args as { domain: Domain }; state.currentDomain = domain; const domainTools = getDomainTools(domain); const toolNames = domainTools.map((t) => t.name).join(", "); return { content: [ { type: "text", text: `Navigated to ${domain} domain. Available tools: ${toolNames}`, }, ], }; } // Handle back navigation if (name === "qbo_back") { state.currentDomain = null; return { content: [ { type: "text", text: "Returned to domain selection. Use qbo_navigate to select a domain: customers, invoices, expenses, payments, reports", }, ], }; } // Route to appropriate domain handler const toolArgs = (args ?? {}) as Record<string, unknown>; if (name.startsWith("qbo_customers_")) { return await handleCustomerTool(name, toolArgs); } if (name.startsWith("qbo_invoices_")) { return await handleInvoiceTool(name, toolArgs); } if (name.startsWith("qbo_expenses_")) { return await handleExpenseTool(name, toolArgs); } if (name.startsWith("qbo_payments_")) { return await handlePaymentTool(name, toolArgs); } if (name.startsWith("qbo_reports_")) { return await handleReportTool(name, toolArgs); } // Unknown tool return { content: [ { type: "text", text: `Unknown tool: ${name}. Use qbo_navigate to select a domain first.`, }, ], isError: true, }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error: ${message}` }], isError: true, }; } });