Koskamo

Zovo Spreadsheet Checker MCP

This MCP server validates spreadsheet data by detecting errors such as invalid dates, emails, duplicates, and format inconsistencies. It supports custom rules for required columns, unique values, and numeric ranges, returning a detailed issue list and an Excel copy with highlighted problems.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Zovo Spreadsheet Checker MCP logo, by ZovoCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-08Published by Zovo
MCP endpoint (Streamable HTTP)
https://sheet-validate.zovo.one/mcp
Vendor documentation

What its tools do

2 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

2 of 2 have a description · 2 of 2 declare behavior hints · 2 of 2 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Check a spreadsheet for errors before importing it into a CRM
  • Find duplicates in an Excel file and identify impossible dates
  • Validate CSV data with specific status and age constraints

Source and maintenance

Community listingRegistry 1.0.0

Protocol and capabilities

Server
sheet-validate 1.0.0
MCP protocol negotiated in check
2025-11-25
Tools
2 advertised
Resources
1 advertised
Resource templates
1 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Zovo Spreadsheet Checker checks a spreadsheet for data errors before import or sending: impossible and mixed-format dates, invalid emails, phone digit counts, duplicate IDs and rows, blanks, numbers stored as text, mixed decimal marks, extra spaces, IDs that lost leading zeros or became 1.2E+15, and totals that do not add up. Use check_spreadsheet for the issue list and the highlighted Excel copy; list_spreadsheet_columns to see detected column types and suggested rules first. Report the counts per check and the first issues with row, column and the cell value, then the download links. It does not edit the data.

Tools

2 advertised

check_spreadsheet — Check spreadsheet for errors
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to check a spreadsheet for errors or validate data before importing or sending it: "check spreadsheet for errors", "data validation excel", "find duplicates in excel", "check this csv for errors", "find invalid dates", "are there bad emails in this list". Attach a CSV, TSV or .xlsx file or paste the table. With no rules it detects column types from the values and checks impossible, ambiguous and mixed-format dates, invalid emails and email typos, phone digit counts, duplicate IDs and duplicate rows, blank cells in mostly filled columns, text in number columns, numbers stored as text, mixed decimal marks, leading/trailing spaces, IDs that lost leading zeros or became 1.2E+15, formula errors and row totals that do not add up. Optional rules: required_columns, unique_columns, allowed_values, ranges, total_rules. Returns each issue with row, column and cell value, counts per check, a column health score, an Excel copy with problem cells highlighted plus an Issues sheet, and an issues CSV. Does not edit or clean the data, does not verify that mailboxes or phone lines exist, and does not compare two files (use a comparison tool for that).

check_spreadsheet input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "download_url",
        "file_id"
      ],
      "properties": {
        "file_id": {
          "type": "string",
          "description": "ChatGPT file id, e.g. file_abc123."
        },
        "file_name": {
          "type": "string",
          "description": "Original file name if known, e.g. statement.pdf."
        },
        "mime_type": {
          "type": "string",
          "description": "Media type if known, e.g. application/pdf."
        },
        "download_url": {
          "type": "string",
          "description": "Temporary download link for the file, supplied by ChatGPT."
        }
      },
      "description": "The spreadsheet to check: CSV, TSV or Excel .xlsx, e.g. customers.xlsx."
    },
    "sheet": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 100
        },
        {
          "type": "number"
        }
      ],
      "description": "Sheet name or number in an Excel workbook, e.g. Orders or 2. Default: the first sheet with data."
    },
    "table": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 400000
        },
        {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2000
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "maxItems": 200
          },
          "maxItems": 5000
        },
        {
          "type": "array",
          "items": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2000
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "maxItems": 5000
        }
      ],
      "description": "Only when no file is attached: the table pasted as CSV, tab-separated or a Markdown table with its header row, e.g. \"id,date,email\\n1,2026-02-30,ana@example.com\". A list of rows also works."
    },
    "ranges": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2000
        },
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "number"
              },
              {
                "type": "object",
                "properties": {
                  "max": {
                    "type": [
                      "number",
                      "string"
                    ]
                  },
                  "min": {
                    "type": [
                      "number",
                      "string"
                    ]
                  }
                }
              }
            ]
          }
        }
      ],
      "description": "Numeric limits per column, e.g. {\"Age\":\"0-120\",\"Discount\":{\"min\":0,\"max\":50}} or \"Age: 0-120; Qty: >= 1\"."
    },
    "date_order": {
      "type": "string",
      "maxLength": 30,
      "description": "Day/month order for dates like 03/04/2026: auto (default), MDY (US, month first) or DMY (day first)."
    },
    "header_row": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "string",
          "maxLength": 10
        }
      ],
      "description": "Only if the headings were detected wrongly: the row number of the header, e.g. 3."
    },
    "skip_checks": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 4000
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 200
          },
          "maxItems": 200
        }
      ],
      "description": "Checks to turn off, e.g. [\"extra_spaces\"]. Options: impossible_date, mixed_date_order, ambiguous_date, mixed_date_format, implausible_date, not_a_date, invalid_email, email_typo, invalid_phone, duplicate_id, duplicate_row, blank_required, not_a_number, number_as_text, mixed_decimal, extra_spaces, lost_leading_zeros, scientific_notation, total_mismatch, formula_error, inconsistent_spelling, extra_cell, impossible_time, not_allowed, out_of_range."
    },
    "total_rules": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 4000
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 200
          },
          "maxItems": 200
        }
      ],
      "description": "Totals that must add up, e.g. \"Total = Q1 + Q2 + Q3 + Q4\" or \"Amount = Qty * Price\". Default: total columns are detected and checked automatically."
    },
    "allowed_values": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 4000
        },
        {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "array",
                "items": {
                  "anyOf": [
                    {
                      "type": "string",
                      "maxLength": 200
                    },
                    {
                      "type": "number"
                    }
                  ]
                },
                "maxItems": 500
              }
            ]
          }
        }
      ],
      "description": "Allowed values per column, e.g. {\"Status\":[\"Open\",\"Closed\"]} or \"Status: Open, Closed; Region: North, South\"."
    },
    "unique_columns": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 4000
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 200
          },
          "maxItems": 200
        }
      ],
      "description": "Columns whose values must not repeat, e.g. \"Order ID\". Default: the ID column is detected from its header and values."
    },
    "required_columns": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 4000
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 200
          },
          "maxItems": 200
        }
      ],
      "description": "Columns that must never be blank, e.g. [\"Email\",\"Order ID\"] or \"Email, Order ID\". Default: columns that are almost fully filled are treated as required (blanks reported as warnings)."
    }
  }
}
check_spreadsheet output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "file",
    "summary",
    "checks",
    "columns",
    "issues_preview",
    "totals_checked",
    "rules_applied",
    "notes",
    "downloads",
    "copy"
  ],
  "properties": {
    "copy": {
      "type": "string"
    },
    "file": {
      "type": "object",
      "required": [
        "name",
        "data_rows",
        "columns",
        "header_row"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "sheet": {
          "type": "string"
        },
        "columns": {
          "type": "number"
        },
        "data_rows": {
          "type": "number"
        },
        "header_row": {
          "type": [
            "number",
            "null"
          ]
        },
        "other_sheets": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false
    },
    "kind": {
      "type": "string"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "checks": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "check",
          "label",
          "severity",
          "count"
        ],
        "properties": {
          "check": {
            "type": "string"
          },
          "count": {
            "type": "number"
          },
          "label": {
            "type": "string"
          },
          "severity": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "columns": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "letter",
          "name",
          "type",
          "health",
          "issues",
          "blank",
          "key",
          "required"
        ],
        "properties": {
          "key": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "blank": {
            "type": "number"
          },
          "health": {
            "type": "number"
          },
          "issues": {
            "type": "number"
          },
          "letter": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      }
    },
    "summary": {
      "type": "object",
      "required": [
        "issues",
        "errors",
        "warnings",
        "rows_with_issues",
        "clean_rows",
        "health_score"
      ],
      "properties": {
        "errors": {
          "type": "number"
        },
        "issues": {
          "type": "number"
        },
        "warnings": {
          "type": "number"
        },
        "clean_rows": {
          "type": "number"
        },
        "health_score": {
          "type": "number"
        },
        "rows_with_issues": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "downloads": {
      "type": "object",
      "required": [
        "xlsx",
        "csv"
      ],
      "properties": {
        "csv": {
          "type": "string"
        },
        "xlsx": {
          "type": "string"
        }
      },
      "additionalProperties": false
    },
    "rules_applied": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "issues_preview": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "row",
          "column",
          "cell",
          "value",
          "check",
          "severity",
          "problem"
        ],
        "properties": {
          "row": {
            "type": "number"
          },
          "cell": {
            "type": "string"
          },
          "check": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "column": {
            "type": "string"
          },
          "problem": {
            "type": "string"
          },
          "severity": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    },
    "totals_checked": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "additionalProperties": false
}
check_spreadsheet annotations
{
  "title": "Check spreadsheet for errors",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_spreadsheet_columns — List spreadsheet columns
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to see what is in a spreadsheet before validating it, or asks which columns, types or values it has: "what columns are in this file", "profile this csv", "which column is the ID", "suggest validation rules". Attach a CSV, TSV or .xlsx file or paste the table. Returns each column's letter, name, detected type (date, email, phone, ID, ZIP, number, money, percent, text), filled and blank counts, unique values, examples, min/max for numbers, short value lists, and suggested rules to pass to check_spreadsheet. Does not report errors (use check_spreadsheet) and does not change the file.

list_spreadsheet_columns input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "download_url",
        "file_id"
      ],
      "properties": {
        "file_id": {
          "type": "string",
          "description": "ChatGPT file id, e.g. file_abc123."
        },
        "file_name": {
          "type": "string",
          "description": "Original file name if known, e.g. statement.pdf."
        },
        "mime_type": {
          "type": "string",
          "description": "Media type if known, e.g. application/pdf."
        },
        "download_url": {
          "type": "string",
          "description": "Temporary download link for the file, supplied by ChatGPT."
        }
      },
      "description": "The spreadsheet to check: CSV, TSV or Excel .xlsx, e.g. customers.xlsx."
    },
    "sheet": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 100
        },
        {
          "type": "number"
        }
      ],
      "description": "Sheet name or number in an Excel workbook, e.g. Orders or 2. Default: the first sheet with data."
    },
    "table": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 400000
        },
        {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2000
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "maxItems": 200
          },
          "maxItems": 5000
        },
        {
          "type": "array",
          "items": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2000
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "maxItems": 5000
        }
      ],
      "description": "Only when no file is attached: the table pasted as CSV, tab-separated or a Markdown table with its header row, e.g. \"id,date,email\\n1,2026-02-30,ana@example.com\". A list of rows also works."
    },
    "header_row": {
      "anyOf": [
        {
          "type": "number"
        },
        {
          "type": "string",
          "maxLength": 10
        }
      ],
      "description": "Only if the headings were detected wrongly: the row number of the header, e.g. 3."
    }
  }
}
list_spreadsheet_columns output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "file",
    "columns",
    "suggested_rules",
    "notes"
  ],
  "properties": {
    "file": {
      "type": "object",
      "required": [
        "name",
        "data_rows",
        "columns",
        "header_row"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "sheet": {
          "type": "string"
        },
        "columns": {
          "type": "number"
        },
        "data_rows": {
          "type": "number"
        },
        "header_row": {
          "type": [
            "number",
            "null"
          ]
        },
        "other_sheets": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false
    },
    "kind": {
      "type": "string"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "columns": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "letter",
          "name",
          "type",
          "filled",
          "blank",
          "unique",
          "examples",
          "key"
        ],
        "properties": {
          "key": {
            "type": "boolean"
          },
          "max": {
            "type": "number"
          },
          "min": {
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "blank": {
            "type": "number"
          },
          "filled": {
            "type": "number"
          },
          "letter": {
            "type": "string"
          },
          "unique": {
            "type": "number"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "examples": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      }
    },
    "suggested_rules": {
      "type": "object",
      "required": [
        "required_columns",
        "unique_columns",
        "allowed_values",
        "ranges"
      ],
      "properties": {
        "ranges": {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        },
        "allowed_values": {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "unique_columns": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "required_columns": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
list_spreadsheet_columns annotations
{
  "title": "List spreadsheet columns",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

sheet-validate-widget — Zovo Spreadsheet Checker view

Advertised by the server during the last successful anonymous check.

Interactive view for Zovo Spreadsheet Checker.

sheet-validate-widget URI
ui://widget/sheet-validate-v1-1.0.0-5449021f2b2bb33f36a4aeff7cc4f8e4dec2a442758df0576a22a0245c9ea8ec.html

MIME type: text/html;profile=mcp-app

sheet-validate-widget-legacy — Zovo Spreadsheet Checker view (previous versions)

Advertised by the server during the last successful anonymous check.

sheet-validate-widget-legacy URI template
ui://widget/sheet-validate-{version}.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
366 ms
95th percentile latency
366 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 366 ms · metadata changed · 2 tool(s), 1 resource(s), 1 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http zovo-spreadsheet-checker-mcp https://sheet-validate.zovo.one/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add zovo-spreadsheet-checker-mcp --url https://sheet-validate.zovo.one/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable zovo-spreadsheet-checker-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "zovo-spreadsheet-checker-mcp": {
      "url": "https://sheet-validate.zovo.one/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "zovo-spreadsheet-checker-mcp": {
      "type": "streamableHttp",
      "url": "https://sheet-validate.zovo.one/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start zovo-spreadsheet-checker-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "zovo-spreadsheet-checker-mcp": {
      "type": "http",
      "url": "https://sheet-validate.zovo.one/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http zovo-spreadsheet-checker-mcp https://sheet-validate.zovo.one/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://sheet-validate.zovo.one/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "zovo-spreadsheet-checker-mcp": {
      "serverUrl": "https://sheet-validate.zovo.one/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Zovo Spreadsheet Checker MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.