Skip to main content
Glama
asachs01

Autotask MCP Server

autotask_create_quote

Create a new quote for an opportunity by providing company ID, contact ID, effective and expiration dates, and optional description.

Instructions

Create a new quote

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoQuote name
descriptionNoQuote description
companyIdYesCompany ID for the quote
contactIdNoContact ID for the quote
opportunityIdNoAssociated opportunity ID
effectiveDateNoEffective date (YYYY-MM-DD format)
expirationDateNoExpiration date (YYYY-MM-DD format)

Implementation Reference

  • Input schema definition for autotask_create_quote tool. Defines parameters: name, description, companyId, contactId, opportunityId, effectiveDate, expirationDate. Only companyId is required.
    {
      name: 'autotask_create_quote',
      description: 'Create a new quote',
      inputSchema: {
        type: 'object',
        properties: {
          name: {
            type: 'string',
            description: 'Quote name'
          },
          description: {
            type: 'string',
            description: 'Quote description'
          },
          companyId: {
            type: 'number',
            description: 'Company ID for the quote'
          },
          contactId: {
            type: 'number',
            description: 'Contact ID for the quote'
          },
          opportunityId: {
            type: 'number',
            description: 'Associated opportunity ID'
          },
          effectiveDate: {
            type: 'string',
            description: 'Effective date (YYYY-MM-DD format)'
          },
          expirationDate: {
            type: 'string',
            description: 'Expiration date (YYYY-MM-DD format)'
          }
        },
        required: ['companyId']
      }
    },
  • Handler function for autotask_create_quote. Elicits company if companyId not provided (via MCP server interaction), elicits opportunity selection based on the company, then delegates to autotaskService.createQuote() with mapped field names (companyID, contactID, opportunityID).
    ['autotask_create_quote', async (a) => {
      // Elicit company if not provided
      if (!a.companyId && this.mcpServer) {
        try {
          const companyId = await this.elicitCompanyId();
          if (companyId) a = { ...a, companyId: companyId };
        } catch { /* proceed without company */ }
      }
    
      // Elicit opportunity if not provided but company is known
      if (!a.opportunityId && a.companyId && this.mcpServer) {
        try {
          const opps = await s.searchOpportunities({ companyId: a.companyId });
          if (opps.length > 0) {
            const options: PicklistValue[] = opps
              .filter(o => o.id != null)
              .map(o => ({
                value: String(o.id),
                label: o.title || `Opportunity #${o.id}`,
              }));
            const selected = await this.elicitSelection(
              `Found ${opps.length} opportunities for this company. Which one should the quote be attached to?`,
              'opportunityId',
              options
            );
            if (selected) a = { ...a, opportunityId: Number(selected) };
          }
        } catch { /* proceed without opportunity */ }
      }
    
      const id = await s.createQuote({ name: a.name, description: a.description, companyID: a.companyId, contactID: a.contactId, opportunityID: a.opportunityId, effectiveDate: a.effectiveDate, expirationDate: a.expirationDate });
      return { result: id, message: `Successfully created quote with ID: ${id}` };
    }],
  • Service method createQuote that performs the actual API call. Auto-populates billToLocationID, shipToLocationID, and soldToLocationID from the company's first CompanyLocation if not provided (Autotask requires these). Then sends POST to 'Quotes' entity via the HTTP client.
    async createQuote(quote: Partial<AutotaskQuote>): Promise<number> {
      const http = await this.ensureClient();
      try {
        // Autotask requires location IDs on the quote. Auto-populate from the
        // company's first location if the caller didn't supply them.
        if (
          quote.companyID &&
          (!quote.billToLocationID || !quote.shipToLocationID || !quote.soldToLocationID)
        ) {
          try {
            const locations = await http.query<{ id: number }>(
              'CompanyLocations',
              [{ op: 'eq', field: 'companyID', value: quote.companyID }],
              { maxRecords: 10 }
            );
            if (locations.length > 0) {
              const defaultLocationId = locations[0].id;
              if (!quote.billToLocationID) quote.billToLocationID = defaultLocationId;
              if (!quote.shipToLocationID) quote.shipToLocationID = defaultLocationId;
              if (!quote.soldToLocationID) quote.soldToLocationID = defaultLocationId;
            }
          } catch (locError) {
            this.logger.warn('Could not auto-populate location IDs for quote:', locError);
          }
        }
    
        this.logger.debug('Creating quote:', quote);
        const id = await http.create('Quotes', quote);
        this.logger.info(`Quote created with ID: ${id}`);
        return id;
      } catch (error) {
        this.logger.error('Failed to create quote:', error);
        throw error;
      }
    }
  • TypeScript interface defining the AutotaskQuote type used by createQuote and other quote operations.
    export interface AutotaskQuote {
      id?: number;
      companyID?: number;
      contactID?: number;
      quoteNumber?: string;
      quoteDate?: string;
      title?: string;
      description?: string;
      totalAmount?: number;
      status?: number;
      [key: string]: any;
    }
  • Registration of autotask_create_quote in the 'financial' tool category within TOOL_CATEGORIES.
    financial: {
      description: 'Quotes, quote items, opportunities, invoices, and contracts',
      tools: ['autotask_get_quote', 'autotask_search_quotes', 'autotask_create_quote', 'autotask_get_quote_item', 'autotask_search_quote_items', 'autotask_create_quote_item', 'autotask_update_quote_item', 'autotask_delete_quote_item', 'autotask_get_opportunity', 'autotask_search_opportunities', 'autotask_create_opportunity', 'autotask_search_invoices', 'autotask_search_contracts']
    },
Behavior2/5

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

With no annotations, the description carries full burden for behavioral disclosure. It fails to mention permissions, side effects, idempotency, or error cases. Only states basic creation.

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

Conciseness4/5

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

Very concise at one sentence, but could front-load key constraints or prerequisites. No wasted words, but lacks structure for quick parsing.

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 7 parameters, no output schema, and no annotations, the description is too minimal. It does not explain return type, confirmation behavior, or dependencies like company existence.

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

Parameters3/5

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

Schema has 100% description coverage, so baseline is 3. The description adds no extra meaning beyond the schema; it does not explain relationships between parameters or provide format details beyond what is in the schema.

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

Purpose4/5

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

Description clearly states the action ('Create') and resource ('quote'), with a specific verb and resource. However, it lacks differentiation from sibling create tools (e.g., autotask_create_company) beyond the resource name.

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?

No guidance on when to use this tool versus alternatives like autotask_search_quotes or autotask_update_quote. No prerequisites or context for usage provided.

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

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/asachs01/autotask-mcp'

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