Koskamo

Zovo Word Counter MCP

An MCP server that provides exact word, character, sentence, and paragraph counts, along with readability scores, keyword density, and social media limit checks for platforms like X, LinkedIn, and Instagram. It supports essay mode to exclude citations and references, and handles word segmentation for Japanese, Chinese, and Thai.

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 Word Counter MCP logo, by ZovoCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-01Published by Zovo
MCP endpoint (Streamable HTTP)
https://word-counter.zovo.one/mcp
Vendor documentation

What you can do with it

  • Count words and characters in essays excluding citations
  • Check if text fits X or LinkedIn character limits
  • Estimate reading and speaking time for speeches
  • Analyze keyword density and readability scores

Source and maintenance

Community listingRegistry 1.0.0

Protocol and capabilities

Server
word-counter 1.0.0
MCP protocol
2025-06-18
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 Word Counter gives exact, rule-based counts of words, characters, sentences, and platform limits. Always pass the user's text verbatim (never summarise, fix, or retype it before counting). Use count_text for counts and reading time, and check_length_limits for essay word targets and platform limits (X, Threads, Bluesky, LinkedIn, Instagram, SEO title and description, SMS). Do not paste the full text back in your reply; quote the numbers.

Tools

2 advertised

count_text — Count words and characters
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants a word count, character count (with or without spaces), sentence or paragraph count, reading or speaking time, readability, or keyword density for text they provide, including essay counts without citations, quotes, headings, or the reference list. Pass the text exactly as written. Handles up to 100,000 characters and Japanese, Chinese, and Thai word splitting. Does not rewrite, shorten, translate, or grade the text, and does not read files or URLs.

count_text input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "text"
  ],
  "properties": {
    "text": {
      "type": "string",
      "maxLength": 100000,
      "description": "The exact text to count, copied verbatim from the user without edits (up to 100,000 characters). Example: The quick brown fox jumps over the lazy dog."
    },
    "language": {
      "type": "string",
      "maxLength": 20,
      "description": "Optional BCP 47 language code, e.g. ja. Improves word splitting for Japanese, Chinese, and Thai; readability scores are only given for English."
    },
    "exclude_quotes": {
      "type": "boolean",
      "description": "Leave out passages inside double quotation marks (\"...\", curly quotes, guillemets). Example: false."
    },
    "exclude_headings": {
      "type": "boolean",
      "description": "Leave out headings: Markdown # lines and short title lines directly above a paragraph. Example: true."
    },
    "exclude_citations": {
      "type": "boolean",
      "description": "Leave out in-text citations: APA (Smith, 2020), (Lee et al., 2019, p. 12), MLA (Smith 23), page refs (p. 4), and numeric [3]. Example: true."
    },
    "exclude_reference_list": {
      "type": "boolean",
      "description": "Leave out everything from a References, Works Cited, or Bibliography heading to the end. Example: true."
    }
  }
}
count_text output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "words",
    "characters",
    "characters_no_spaces",
    "letters",
    "sentences",
    "paragraphs",
    "lines",
    "unique_words",
    "avg_word_length",
    "avg_sentence_words",
    "reading_time",
    "speaking_time",
    "readability",
    "keywords",
    "longest_sentence",
    "long_sentences",
    "options",
    "privacy"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "const": "count"
    },
    "lines": {
      "type": "number"
    },
    "words": {
      "type": "number"
    },
    "letters": {
      "type": "number"
    },
    "options": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "privacy": {
      "type": "string"
    },
    "excluded": {
      "type": "object",
      "properties": {
        "quotes": {
          "type": "object",
          "required": [
            "count",
            "words",
            "examples"
          ],
          "properties": {
            "count": {
              "type": "number"
            },
            "words": {
              "type": "number"
            },
            "examples": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false
        },
        "headings": {
          "type": "object",
          "required": [
            "count",
            "words",
            "examples"
          ],
          "properties": {
            "count": {
              "type": "number"
            },
            "words": {
              "type": "number"
            },
            "examples": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false
        },
        "citations": {
          "type": "object",
          "required": [
            "count",
            "words",
            "examples"
          ],
          "properties": {
            "count": {
              "type": "number"
            },
            "words": {
              "type": "number"
            },
            "examples": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false
        },
        "reference_list": {
          "type": "object",
          "required": [
            "count",
            "words",
            "examples"
          ],
          "properties": {
            "count": {
              "type": "number"
            },
            "words": {
              "type": "number"
            },
            "examples": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "keywords": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "word",
          "count",
          "density"
        ],
        "properties": {
          "word": {
            "type": "string"
          },
          "count": {
            "type": "number"
          },
          "density": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "sentences": {
      "type": "number"
    },
    "characters": {
      "type": "number"
    },
    "paragraphs": {
      "type": "number"
    },
    "readability": {
      "type": "object",
      "required": [
        "available"
      ],
      "properties": {
        "note": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "reason": {
          "type": "string"
        },
        "available": {
          "type": "boolean"
        },
        "flesch_reading_ease": {
          "type": "number"
        },
        "flesch_kincaid_grade": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "reading_time": {
      "type": "object",
      "required": [
        "seconds",
        "label",
        "wpm"
      ],
      "properties": {
        "wpm": {
          "type": "number"
        },
        "label": {
          "type": "string"
        },
        "seconds": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "unique_words": {
      "type": "number"
    },
    "speaking_time": {
      "type": "object",
      "required": [
        "seconds",
        "label",
        "wpm"
      ],
      "properties": {
        "wpm": {
          "type": "number"
        },
        "label": {
          "type": "string"
        },
        "seconds": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "cjk_characters": {
      "type": "number"
    },
    "long_sentences": {
      "type": "object",
      "required": [
        "over_25_words",
        "over_40_words",
        "examples"
      ],
      "properties": {
        "examples": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "number",
              "words",
              "snippet"
            ],
            "properties": {
              "words": {
                "type": "number"
              },
              "number": {
                "type": "number"
              },
              "snippet": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "over_25_words": {
          "type": "number"
        },
        "over_40_words": {
          "type": "number"
        }
      },
      "additionalProperties": false
    },
    "original_words": {
      "type": "number"
    },
    "avg_word_length": {
      "type": "number"
    },
    "longest_sentence": {
      "anyOf": [
        {
          "type": "object",
          "required": [
            "number",
            "words",
            "snippet"
          ],
          "properties": {
            "words": {
              "type": "number"
            },
            "number": {
              "type": "number"
            },
            "snippet": {
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "avg_sentence_words": {
      "type": "number"
    },
    "characters_no_spaces": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
count_text annotations
{
  "title": "Count words and characters",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
check_length_limits — Check length limits
Advertised by the server during the last successful anonymous check.
Advertised read-only

Use this when the user wants to know whether text fits a limit: an essay minimum or maximum word count, a custom character limit, or platform limits for X/Twitter (280 weighted), Threads, Bluesky, LinkedIn, Instagram captions, SEO title tags, meta descriptions, or SMS segments. Returns pass or fail, how far over or under, and where to cut. Pass the text exactly as written. Does not shorten or rewrite the text and does not post anything.

check_length_limits input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "text"
  ],
  "properties": {
    "text": {
      "type": "string",
      "maxLength": 100000,
      "description": "The exact text to count, copied verbatim from the user without edits (up to 100,000 characters). Example: The quick brown fox jumps over the lazy dog."
    },
    "language": {
      "type": "string",
      "maxLength": 20,
      "description": "Optional BCP 47 language code, e.g. ja. Improves word splitting for Japanese, Chinese, and Thai; readability scores are only given for English."
    },
    "max_words": {
      "type": "integer",
      "maximum": 100000,
      "minimum": 1,
      "description": "Maximum allowed word count, e.g. 2000."
    },
    "min_words": {
      "type": "integer",
      "maximum": 100000,
      "minimum": 1,
      "description": "Minimum required word count, e.g. 1500."
    },
    "platforms": {
      "type": "array",
      "items": {
        "enum": [
          "x",
          "threads",
          "bluesky",
          "linkedin",
          "instagram",
          "meta_title",
          "meta_description",
          "sms"
        ],
        "type": "string"
      },
      "maxItems": 8,
      "description": "Platforms to check, e.g. [\"x\",\"linkedin\"]. x: X/Twitter 280 weighted characters (links 23, emoji and CJK 2). threads: 500. bluesky: 300 graphemes. linkedin: 3,000. instagram: caption 2,200. meta_title: 60. meta_description: 160 (155 safer). sms: 160 GSM-7 or 70 Unicode per message. If nothing is given, x, threads, bluesky, linkedin, and instagram are checked."
    },
    "exclude_quotes": {
      "type": "boolean",
      "description": "Leave out passages inside double quotation marks (\"...\", curly quotes, guillemets). Example: false."
    },
    "max_characters": {
      "type": "integer",
      "maximum": 100000,
      "minimum": 1,
      "description": "A custom character limit (counted as user-perceived characters), e.g. 500."
    },
    "exclude_headings": {
      "type": "boolean",
      "description": "Leave out headings: Markdown # lines and short title lines directly above a paragraph. Example: true."
    },
    "exclude_citations": {
      "type": "boolean",
      "description": "Leave out in-text citations: APA (Smith, 2020), (Lee et al., 2019, p. 12), MLA (Smith 23), page refs (p. 4), and numeric [3]. Example: true."
    },
    "exclude_reference_list": {
      "type": "boolean",
      "description": "Leave out everything from a References, Works Cited, or Bibliography heading to the end. Example: true."
    }
  }
}
check_length_limits output schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "kind",
    "words",
    "characters",
    "all_pass",
    "results",
    "options",
    "privacy"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "const": "limits"
    },
    "words": {
      "type": "number"
    },
    "options": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "privacy": {
      "type": "string"
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "label",
          "metric",
          "count",
          "limit",
          "status",
          "percent"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "cut": {
            "type": "object",
            "required": [
              "keep_until",
              "next",
              "keeps_words",
              "paragraph"
            ],
            "properties": {
              "next": {
                "type": "string"
              },
              "paragraph": {
                "type": "number"
              },
              "keep_until": {
                "type": "string"
              },
              "keeps_words": {
                "type": "number"
              }
            },
            "additionalProperties": false
          },
          "min": {
            "type": "number"
          },
          "note": {
            "type": "string"
          },
          "over": {
            "type": "number"
          },
          "count": {
            "type": "number"
          },
          "label": {
            "type": "string"
          },
          "limit": {
            "type": "number"
          },
          "under": {
            "type": "number"
          },
          "metric": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pass",
              "fail",
              "warn"
            ],
            "type": "string"
          },
          "non_gsm": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "percent": {
            "type": "number"
          },
          "encoding": {
            "type": "string"
          },
          "segments": {
            "type": "number"
          },
          "remaining": {
            "type": "number"
          }
        },
        "additionalProperties": false
      }
    },
    "all_pass": {
      "type": "boolean"
    },
    "characters": {
      "type": "number"
    }
  },
  "additionalProperties": false
}
check_length_limits annotations
{
  "title": "Check length limits",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

word-counter-widget — Zovo Word Counter view

Advertised by the server during the last successful anonymous check.

Interactive view for Zovo Word Counter.

word-counter-widget URI
ui://widget/word-counter-v1-1.0.0-a7f8c4a011fc2beb72277b5ffdabc02481e68df27e12a3d3f0d9bdcaa1b7e7e6.html

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

word-counter-widget-legacy — Zovo Word Counter view (previous versions)

Advertised by the server during the last successful anonymous check.

word-counter-widget-legacy URI template
ui://widget/word-counter-{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
377 ms
95th percentile latency
377 ms

Maintenance history

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

  • · probe · passed · 377 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-word-counter-mcp https://word-counter.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-word-counter-mcp --url https://word-counter.zovo.one/mcp

Cursor

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

Cline

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

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start zovo-word-counter-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "zovo-word-counter-mcp": {
      "type": "http",
      "url": "https://word-counter.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-word-counter-mcp https://word-counter.zovo.one/mcp

Claude Desktop

Merge this into claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), then restart Claude Desktop.
Claude Desktop configuration
{
  "mcpServers": {
    "zovo-word-counter-mcp": {
      "url": "https://word-counter.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-word-counter-mcp": {
      "serverUrl": "https://word-counter.zovo.one/mcp"
    }
  }
}

Let your agent find its tools

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