Kaneme — Your writing identity, measured and portable
Server Details
Build a voice from your own texts, measure whether a text still sounds like you, then write in it.
- Status
- Healthy
- Uptime
- 37.7% over 34 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 2 tools
The two tools target clearly different jobs: authorship attribution (measure_authorship) versus editorial passage detection (read_observatory_signals), and each description explicitly contrasts itself with the other. However, both descriptions heavily reference tools not in this set (verify_authorship, improve_in_voice), which could still make an agent misselect or attempt unavailable calls.
Both names follow a verb_noun pattern (measure_authorship, read_observatory_signals), which is consistent and readable. The second is noticeably longer and more domain-specific, a minor deviation from the parallel structure of the first.
Two tools is thin for a server whose stated purpose ('writing identity, measured and portable') implies measurement plus portability/verification workflows. It is borderline but workable for a no-account surface, since the descriptions imply additional account-gated tools exist elsewhere.
The anonymous surface covers measurement and editorial reading, but the descriptions repeatedly point to absent operations (verify_authorship, improve_in_voice, account-based voice storage), creating dead ends relative to the advertised 'portable identity' scope. This is a notable gap rather than full CRUD/lifecycle coverage.
Available Tools
2 toolsmeasure_authorshipTrial measurement, no accountAInspect
Measures whether a text is by the SAME HAND as three reference texts pasted in the call. No account, no credits, nothing stored. Exactly 3 references of 100+ words each, in DIFFERENT registers, and a text of 50+ words (150 to leave low confidence). Returns a calibrated PROBABILITY, its label and four stylometric dimensions (not a breakdown of the probability). probability: null with unavailable is a measured abstention; only embedding_layer is an outage on our side. Not verify_authorship, which uses the account’s saved voice. For that, a Kaneme account at https://kaneme.com and the authenticated MCP connection.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to attribute (50+ words), not taken from the references (self_overlap). | |
| samples | Yes | Exactly 3 texts by the person, 100+ words each, different registers. | |
| question | No | human = this person vs an AI (default) · author = this person vs another human. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description says no account, no credits, and nothing stored, which implies no side effects, but the annotations declare readOnlyHint=false. That is a direct contradiction because readOnlyHint=false signals the tool is not read-only, while the description claims nothing is stored.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loads the core function before routing constraints and return behavior. It is longer than most definitions, but nearly every sentence carries operational information, with only minor tightening possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and three parameters, the description carries the full burden and explains the return shape: calibrated probability, label, four stylometric dimensions, null/unavailable abstention, and the embedding_layer outage. It also covers prerequisites and alternatives, making it complete for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds useful semantic detail beyond the schema, especially the 150-word threshold for leaving low confidence. It also reinforces the exact sample count, word minimums, and register diversity, though it does not discuss the question enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: measures whether a text is by the same hand as three pasted reference texts. It also names the sibling it is not (verify_authorship), so an agent can distinguish it without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the trial/no-account use case and contrasts it with verify_authorship, which requires an account and saved voice. It also states the conditions for the call: exactly 3 references, 100+ words each, different registers, and 50+ words for the target text.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_observatory_signalsObservatory reading (free)ARead-onlyInspect
Reads a text with the Observatoire method (frozen copy, methodVersion returned): passages to reread, each with its criterion (G01 generic phrasing, S01 announced conclusion, V01 claim without visible evidence, R01 near-repeated vocabulary, S02 repeated opening, D01 long sentence), UTF-16 positions, the quoted passage and editorial advice. No account, no credits, nothing stored. It is NOT an AI detector, NOT a proof of authorship and has NO score: never turn the number of passages into a verdict, and never merge it with a Kaneme measurement. Labels and advice are in French: relay them in the user’s language. Language is detected when omitted; English rules are experimental. To rewrite the text in the user’s own voice, use improve_in_voice (account required).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to read (12,000 characters max). | |
| language | No | Text language (detected when omitted). | |
| documentType | No | Kind of text; tunes the advice (default: general). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and closed-world, but the description adds substantive context beyond them: frozen copy with methodVersion returned, nothing stored, no account or credits, labels in French, English rules experimental. It also warns against misuse (turning passage counts into a verdict), which annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Opens with the core operation and its output, then layers constraints and routing. It is dense and somewhat long, but nearly every clause carries distinct information; only minor tightening would be possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so thoroughly: passage list, per-passage criterion code, UTF-16 offsets, quoted passage and advice, plus methodVersion. An agent has enough to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: language is detected when omitted and English rules are experimental, and documentType tunes the advice. This goes beyond the schema's own parameter text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Reads a text with the Observatoire method') and immediately enumerates what the output contains (passages, criteria codes, UTF-16 positions, quoted text, advice). It explicitly distinguishes itself from the sibling measure_authorship ('NOT a proof of authorship... never merge it with a Kaneme measurement').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-not conditions (not an AI detector, no score, never convert passage counts into a verdict) and routes to the alternative ('To rewrite the text in the user's own voice, use improve_in_voice'). Prerequisites (no account, no credits) are also stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Added
read_observatory_signals
1 tool update
- Removed
verify_certificate
2 tool updates
- Changed
measure_authorship4 fields changed- changed
Input schema / properties / question / descriptionPrevious value: -"human = cette personne contre une IA (défaut) ; author = cette personne contre un autre humain."New value: +"human = this person vs an AI (default) · author = this person vs another human." - changed
Input schema / properties / samples / descriptionPrevious value: -"Exactement 3 textes de la personne, 100 mots minimum chacun, dans des registres différents."New value: +"Exactly 3 texts by the person, 100+ words each, different registers." - changed
Input schema / properties / text / descriptionPrevious value: -"Le texte à attribuer (50 mots minimum). Ne le prends PAS dans les références : la mesure s’abstiendrait (self_overlap)."New value: +"Text to attribute (50+ words), not taken from the references (self_overlap)." - changed
Output schema / (root)Previous value: -{ - "additionalProperties": {}, - "properties": { - "confidence": { - "enum": [ - "none", - "low", - "medium", - "high" - ], - "type": "string" - }, - "dimensions": { - "description": "Sur quoi le texte s’écarte des références : rythme, lexique, structure, signature. Ce n’est PAS la décomposition de `probability` — ces quatre-là lisent la couche stylométrique, qui pèse 20 % du score fusionné. Servies même en abstention : ce sont des faits mesurés, pas un verdict.", - "items": { - "additionalProperties": {}, - "properties": { - "detail": { - "type": "string" - }, - "id": { - "enum": [ - "rythme", - "lexique", - "structure", - "signature" - ], - "type": "string" - }, - "label": { - "type": "string" - }, - "measured": { - "type": "boolean" - }, - "passages": { - "items": { - "additionalProperties": false, - "properties": { - "basis": { - "enum": [ - "reference", - "preference", - "observation" - ], - "type": "string" - }, - "end": { - "type": "number" - }, - "observation": { - "type": "string" - }, - "quote": { - "type": "string" - }, - "start": { - "type": "number" - } - }, - "required": [ - "start", - "end", - "quote", - "observation", - "basis" - ], - "type": "object" - }, - "type": "array" - }, - "score": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "id", - "label", - "measured", - "score", - "detail" - ], - "type": "object" - }, - "type": "array" - }, - "dimensionsVersion": { - "type": "string" - }, - "explanation": { - "additionalProperties": {}, - "properties": { - "caveat": { - "type": "string" - }, - "factors": { - "items": { - "additionalProperties": {}, - "properties": { - "detail": { - "type": "string" - }, - "gap": { - "anyOf": [ - { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - { - "type": "null" - } - ] - }, - "id": { - "enum": [ - "cadence", - "registre", - "structure", - "lexique" - ], - "type": "string" - }, - "label": { - "type": "string" - }, - "status": { - "enum": [ - "aligned", - "mixed", - "different", - "unmeasured" - ], - "type": "string" - } - }, - "required": [ - "id", - "label", - "status", - "gap", - "detail" - ], - "type": "object" - }, - "type": "array" - }, - "summary": { - "type": "string" - }, - "version": { - "type": "string" - } - }, - "required": [ - "version", - "summary", - "caveat", - "factors" - ], - "type": "object" - }, - "label": { - "description": "Attribution en clair, dérivée de `probability`. Absent quand `unavailable` est présent.", - "type": "string" - }, - "language": { - "type": "string" - }, - "measurement": { - "additionalProperties": false, - "properties": { - "axis": { - "enum": [ - "q1", - "q2" - ], - "type": "string" - }, - "calibrationLanguage": { - "enum": [ - "fr", - "en" - ], - "type": "string" - }, - "calibrationSource": { - "type": "string" - }, - "calibrationVersion": { - "type": "string" - }, - "candidateLanguage": { - "type": "string" - }, - "contrast": { - "type": "string" - }, - "display": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "limitation": { - "type": "string" - }, - "model": { - "type": "string" - }, - "scoreVersion": { - "type": "string" - }, - "version": { - "const": "kaneme.measurement.v1", - "type": "string" - } - }, - "required": [ - "version", - "axis", - "contrast", - "display", - "calibrationLanguage", - "candidateLanguage", - "model", - "scoreVersion", - "calibrationVersion", - "calibrationSource", - "limitation" - ], - "type": "object" - }, - "passages": { - "description": "Présent uniquement avec `unavailable: \"mixed_language\"` : les phrases écrites dans l’autre langue, avec leurs positions (`start`, `end`) dans le texte jugé. Les corriger ou les retirer, puis relancer.", - "items": { - "additionalProperties": {}, - "properties": { - "end": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "language": { - "enum": [ - "fr", - "en" - ], - "type": "string" - }, - "start": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "text": { - "type": "string" - } - }, - "required": [ - "text", - "start", - "end", - "language" - ], - "type": "object" - }, - "type": "array" - }, - "probability": { - "anyOf": [ - { - "maximum": 1, - "minimum": 0, - "type": "number" - }, - { - "type": "null" - } - ] - }, - "question": { - "enum": [ - "author", - "human" - ], - "type": "string" - }, - "referenceLimited": { - "type": "boolean" - }, - "unavailable": { - "description": "self_overlap — Le texte à juger est déjà, pour l’essentiel, dans la référence qui le juge : la mesure porterait sur elle-même. Juge un texte que la référence ne contient pas — ou retire-le du corpus de cette voix. · unsupported_language — Le texte ne se lit ni en français ni en anglais, même en départageant ces deux seules langues : le verdict n’est calibré que sur elles, chacune avec son propre moteur. Lis le champ `language` de la réponse avant d’appeler : hors du français et de l’anglais, ne demande pas de verdict. · voice_language_mismatch — Le texte et la voix de référence ne sont pas écrits dans la même langue : chaque moteur ne compare un texte qu’à une voix de sa langue. Juge ce texte avec une voix écrite dans sa langue — crée-la si elle n’existe pas. Ne le traduis pas pour contourner ce refus. · mixed_language — Le texte est dans la langue de la voix, mais au moins une phrase entière est dans l’autre langue servie : la mesure mêlerait deux moteurs. Corrige ou retire les passages renvoyés dans `passages` (positions dans le texte), puis relance. Les mots isolés — anglicismes, marques — et les citations entre guillemets ne déclenchent pas ce refus. · embedding_layer — La couche de mesure profonde n’a pas répondu ; sans elle, aucune probabilité n’est calibrée. Réessaie dans un instant si la couche de mesure redevient disponible. · out_of_distribution — Le panel de contraste ne couvre pas le registre de cette voix : la marge existerait, elle ne voudrait rien dire. Verse dans la voix des textes de référence plus proches du registre mesuré. · calibration_mismatch — La version du moteur ne correspond pas à une calibration validée. Attends la correction de la configuration du moteur. Ne modifie ni ne traduis le texte pour contourner ce refus.", - "enum": [ - "self_overlap", - "unsupported_language", - "voice_language_mismatch", - "mixed_language", - "embedding_layer", - "out_of_distribution", - "calibration_mismatch" - ], - "type": "string" - }, - "version": { - "type": "string" - } - }, - "required": [ - "question", - "probability", - "referenceLimited", - "version", - "dimensions", - "dimensionsVersion" - ], - "type": "object" -}New value: +null
- Changed
verify_certificate2 fields changed- changed
Input schema / properties / token / descriptionPrevious value: -"Le token du certificat (UUID) — extrait d’une URL /certificat/… ou d’un badge."New value: +"Certificate token (UUID)." - changed
Output schema / (root)Previous value: -{ - "oneOf": [ - { - "additionalProperties": {}, - "properties": { - "error": { - "type": "string" - }, - "verified": { - "const": false, - "type": "boolean" - } - }, - "required": [ - "verified", - "error" - ], - "type": "object" - }, - { - "additionalProperties": {}, - "properties": { - "certificateUrl": { - "type": "string" - }, - "claims": { - "additionalProperties": {}, - "properties": { - "attestation": { - "anyOf": [ - { - "additionalProperties": {}, - "properties": { - "band": { - "type": "string" - }, - "claim": { - "type": "string" - }, - "composition": { - "type": "string" - }, - "compositionLabel": { - "type": "string" - }, - "label": { - "type": "string" - } - }, - "required": [ - "band", - "label", - "claim", - "composition", - "compositionLabel" - ], - "type": "object" - }, - { - "additionalProperties": {}, - "properties": { - "calibrationLevel": { - "type": "number" - }, - "maturityLevel": { - "type": "string" - }, - "maturityPercent": { - "type": "number" - }, - "signalCount": { - "type": "number" - }, - "strandsActive": { - "type": "number" - }, - "strandsTotal": { - "type": "number" - }, - "topFormat": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "maturityLevel", - "maturityPercent", - "calibrationLevel", - "signalCount", - "strandsActive", - "strandsTotal", - "topFormat" - ], - "type": "object" - } - ] - }, - "engine": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "issuedAt": { - "type": "string" - }, - "issuer": { - "const": "kaneme.com", - "type": "string" - }, - "kind": { - "enum": [ - "text", - "voice" - ], - "type": "string" - }, - "subject": { - "additionalProperties": {}, - "properties": { - "displayName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "title": { - "type": "string" - }, - "wordCount": { - "type": "number" - } - }, - "required": [ - "displayName" - ], - "type": "object" - }, - "token": { - "type": "string" - } - }, - "required": [ - "issuer", - "kind", - "token", - "issuedAt", - "engine", - "subject", - "attestation" - ], - "type": "object" - }, - "disclaimer": { - "type": "string" - }, - "trust": { - "anyOf": [ - { - "additionalProperties": {}, - "properties": { - "keyUrl": { - "type": "string" - }, - "model": { - "const": "signed-ed25519", - "type": "string" - }, - "signature": { - "additionalProperties": {}, - "properties": { - "alg": { - "const": "Ed25519", - "type": "string" - }, - "canonicalization": { - "const": "sorted-keys-json", - "type": "string" - }, - "keyId": { - "type": "string" - }, - "signature": { - "type": "string" - } - }, - "required": [ - "alg", - "keyId", - "signature", - "canonicalization" - ], - "type": "object" - } - }, - "required": [ - "model", - "signature", - "keyUrl" - ], - "type": "object" - }, - { - "additionalProperties": {}, - "properties": { - "model": { - "const": "origin", - "type": "string" - }, - "note": { - "type": "string" - } - }, - "required": [ - "model", - "note" - ], - "type": "object" - } - ] - }, - "verified": { - "const": true, - "type": "boolean" - } - }, - "required": [ - "verified", - "claims", - "certificateUrl", - "disclaimer", - "trust" - ], - "type": "object" - } - ], - "type": "object" -}New value: +null
2 tool updates
- First observed
measure_authorship - First observed
verify_certificate
Related MCP Connectors
Loads your personal writing voice into any AI and scores how closely a draft matches it.
Write in the user's own voice, fitted to the occasion. Learns from the text they actually send.
A personal RAG database you build from chat, so AI creates work that sounds like you.
Find AI-isms with evidence and fingerprint a writing voice from samples. 3 of 5 free.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceAllows AI assistants to measure your writing style across 45 attributes, create a voice profile from your samples, generate drafts matching that voice, and score any text for voice consistency.MIT
- FlicenseNot gradedqualityDmaintenanceA local-first MCP server that builds compact voice profiles from writing samples, then compares, rewrites, or generates new text in that voice.-
- AlicenseAqualityBmaintenanceMCP server that analyzes your writing style to generate personal voice rules, scores drafts for AI slop, and verifies authorship, enabling LLMs to write in your specific voice.7MIT
- AlicenseNot gradedqualityDmaintenanceLoads your personal writing voice into any AI and scores how closely a draft matches it. Also rewrites and drafts in your voice, backed by the hosted Idiolect AI connector at https://idiolect.app/api/mcp.6 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.