Skip to main content
Glama

insert_data

Add single or multiple records to MSSQL database tables using SQL INSERT statements with proper column mapping and data type validation.

Instructions

Inserts data into an MSSQL Database table. Supports both single record insertion and multiple record insertion using standard SQL INSERT with VALUES clause. FORMAT EXAMPLES: Single Record Insert: { "tableName": "Users", "data": { "name": "John Doe", "email": "john@example.com", "age": 30, "isActive": true, "createdDate": "2023-01-15" } } Multiple Records Insert: { "tableName": "Users", "data": [ { "name": "John Doe", "email": "john@example.com", "age": 30, "isActive": true, "createdDate": "2023-01-15" }, { "name": "Jane Smith", "email": "jane@example.com", "age": 25, "isActive": false, "createdDate": "2023-01-16" } ] } GENERATED SQL FORMAT:

  • Single: INSERT INTO table (col1, col2) VALUES (@param1, @param2)

  • Multiple: INSERT INTO table (col1, col2) VALUES (@param1, @param2), (@param3, @param4), ... IMPORTANT RULES:

  • For single record: Use a single object for the 'data' field

  • For multiple records: Use an array of objects for the 'data' field

  • All objects in array must have identical column names

  • Column names must match the actual database table columns exactly

  • Values should match the expected data types (string, number, boolean, date)

  • Use proper date format for date columns (YYYY-MM-DD or ISO format)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYes
tableNameYesName of the table to insert data into

Implementation Reference

  • The main handler function `run` that executes the insert_data tool logic, handling both single and multiple record insertions into an MSSQL table using parameterized queries.
    async run(params: any) {
      try {
        const { tableName, data } = params;
        // Check if data is an array (multiple records) or single object
        const isMultipleRecords = Array.isArray(data);
        const records = isMultipleRecords ? data : [data];
        if (records.length === 0) {
          return {
            success: false,
            message: "No data provided for insertion",
          };
        }
        // Validate that all records have the same columns
        const firstRecordColumns = Object.keys(records[0]).sort();
        for (let i = 1; i < records.length; i++) {
          const currentColumns = Object.keys(records[i]).sort();
          if (JSON.stringify(firstRecordColumns) !== JSON.stringify(currentColumns)) {
            return {
              success: false,
              message: `Column mismatch: Record ${i + 1} has different columns than the first record. Expected columns: [${firstRecordColumns.join(', ')}], but got: [${currentColumns.join(', ')}]`,
            };
          }
        }
        const columns = firstRecordColumns.join(", ");
        const request = new sql.Request();
        if (isMultipleRecords) {
          // Multiple records insert using VALUES clause - works for 1 or more records
          const valueClauses: string[] = [];
          records.forEach((record, recordIndex) => {
            const valueParams = firstRecordColumns
              .map((column, columnIndex) => `@value${recordIndex}_${columnIndex}`)
              .join(", ");
            valueClauses.push(`(${valueParams})`);
            // Add parameters for this record
            firstRecordColumns.forEach((column, columnIndex) => {
              request.input(`value${recordIndex}_${columnIndex}`, record[column]);
            });
          });
          const query = `INSERT INTO ${tableName} (${columns}) VALUES ${valueClauses.join(", ")}`;
          await request.query(query);
          return {
            success: true,
            message: `Successfully inserted ${records.length} record${records.length > 1 ? 's' : ''} into ${tableName}`,
            recordsInserted: records.length,
          };
        } else {
          // Single record insert (when data is passed as single object)
          const values = firstRecordColumns
            .map((column, index) => `@value${index}`)
            .join(", ");
          firstRecordColumns.forEach((column, index) => {
            request.input(`value${index}`, records[0][column]);
          });
          const query = `INSERT INTO ${tableName} (${columns}) VALUES (${values})`;
          await request.query(query);
          return {
            success: true,
            message: `Successfully inserted 1 record into ${tableName}`,
            recordsInserted: 1,
          };
        }
      } catch (error) {
        console.error("Error inserting data:", error);
        return {
          success: false,
          message: `Failed to insert data: ${error}`,
        };
      }
    }
  • Input schema definition for the insert_data tool, specifying tableName and data (either single object or array of objects).
    inputSchema = {
      type: "object",
      properties: {
        tableName: { 
          type: "string", 
          description: "Name of the table to insert data into" 
        },
        data: { 
          oneOf: [
            { 
              type: "object", 
              description: "Single record data object with column names as keys and values as the data to insert. Example: {\"name\": \"John\", \"age\": 30}" 
            },
            { 
              type: "array", 
              items: { type: "object" },
              description: "Array of data objects for multiple record insertion. Each object must have identical column structure. Example: [{\"name\": \"John\", \"age\": 30}, {\"name\": \"Jane\", \"age\": 25}]" 
            }
          ]
        },
      },
      required: ["tableName", "data"],
    } as any;
  • src/index.ts:90-90 (registration)
    Instantiation of the InsertDataTool instance.
    const insertDataTool = new InsertDataTool();
  • src/index.ts:115-119 (registration)
    Registration of the insert_data tool in the list of available tools returned by ListToolsRequestSchema handler.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: isReadOnly
        ? [listTableTool, readDataTool, describeTableTool] // todo: add searchDataTool to the list of tools available in readonly mode once implemented
        : [insertDataTool, readDataTool, describeTableTool, updateDataTool, createTableTool, createIndexTool, dropTableTool, listTableTool], // add all new tools here
    }));
  • src/index.ts:126-127 (registration)
    Dispatch case in CallToolRequestSchema handler that routes calls to insert_data to the tool's run method.
    case insertDataTool.name:
      result = await insertDataTool.run(args);
Behavior4/5

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

With no annotations provided, the description carries full burden and does well by disclosing important behavioral traits: it explains the SQL generation format, specifies important rules about data structure consistency, column name matching, and data type requirements. It also clarifies the single vs. multiple record distinction. The main gap is lack of information about permissions, transaction behavior, or error handling.

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?

The description is well-structured with clear sections (purpose statement, format examples, generated SQL format, important rules). While comprehensive, it could be more concise by eliminating some redundancy between the format examples and rules. Every sentence adds value, but the examples are quite detailed.

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

Completeness4/5

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

For a mutation tool with no annotations and no output schema, the description provides substantial context about behavior, parameters, and constraints. It covers the core functionality thoroughly but lacks information about return values, error conditions, or performance characteristics. Given the complexity of database operations, some additional context about what happens on success/failure would be beneficial.

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

Parameters5/5

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

The description adds significant value beyond the 50% schema coverage. While the schema only describes basic structure, the description provides detailed format examples for both single and multiple records, explains the 'data' field's dual nature with clear rules, specifies column name matching requirements, and provides data type guidance. This fully compensates for the schema's limited coverage.

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

Purpose5/5

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

The description clearly states the specific action ('inserts data'), target resource ('MSSQL Database table'), and scope ('supports both single record insertion and multiple record insertion'). It distinguishes from siblings like 'update_data' by focusing on insertion rather than modification, and from 'create_table' by operating on existing tables rather than creating new ones.

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool (inserting data into tables) and implicitly distinguishes it from alternatives like 'update_data' (for modifying existing records) and 'create_table' (for creating table structures). However, it doesn't explicitly state when NOT to use this tool or name specific alternative tools for related operations.

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/Nirmal123K/mssql-mcp'

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