ai.etincel/etincel-nonfiction
NPM · ETINCEL · 2 COMPONENTS
Trainable non-fiction writing voice, presets, and an anti-AI-tells audit for Claude, via MCP.
Available components
Last scanned (5 hours ago)
Scores higher than 70% of npm servers
Category Developer Tools
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security86
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Install-script check failed: the install command fetches or executes arbitrary code (inline_eval). An install hook runs on every machine, in CI, and on transitive installs, whether or not you ever run the server. View diagnostics → Fail
- 30 of 92 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency48
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 70 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability73
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3308 tokens (~165/item across 20 items; 20 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management97
- Stability observed for 29 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 21 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 25 Oct 26 −1
- Stability: pass → 0.97 functional
- 19 Oct 26 +1
- Stability: 0.97 → pass security
- 17 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
- 15 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 13 Oct 26 −2
- Security disclosure: unverified → pass ▲ functional
- Stability: pass → 0.80 functional
- 12 Oct 26 +15
- Malware scan: unverified → pass ▲ security
- Stability: 0.97 → pass security
- 11 Oct 26 −14
- Malware scan: pass → unverified ▼ security
- Security disclosure: pass → unverified ▼ functional
- 8 Oct 26 −1
No change was recorded against any check on this day. Stability & Change Management went from 93 to 87.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 25 Oct 2026 · Analysed npm/etincel@0.10.1
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | npm |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| postinstall | dangerous | node -e "require('fs').existsSync('tsconfig.json')&&require('child_process').execSync('npm run build',{stdio:'inherit'})" |
Background: Why install scripts are a supply-chain risk →
Dependencies 92 packages
| Packages resolved | 92 |
|---|---|
| Stale | 30 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_banned_word Add a word to a banned-words list ~147
Add a term to this installer's own banned-words list, checked by audit_text alongside the built-in AI-tell corpus. Without styleId, this adds to the global list, which applies to every style. With styleId, it only applies when auditing against that specific style, merged on top of the global list. Use this when the user says something like 'add [word] to my banned words list' or 'never let me use [word] again'.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id to scope this ban to, from list_styles. Omit to add to the global list. |
| word | string | yes | The term or short phrase to ban. |
No output schema declared.
No examples provided.
add_custom_word Add a word to a custom (allowed) words list ~167
Add a term to this installer's own allowed-words list, so audit_text never flags it even if it matches the built-in corpus or a banned word: the 'corporate dictionary' case, e.g. an org's own acronyms or house terms. Without styleId, this adds to the global list. With styleId, it only applies to that specific style, merged on top of the global list. Use this when the user says something like 'add [word] to my custom words list' or 'stop flagging [word], it's one of ours'.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id to scope this to, from list_styles. Omit to add to the global list. |
| word | string | yes | The term or short phrase to always allow. |
No output schema declared.
No examples provided.
audit_text Audit text for AI writing tells ~395
Deterministically scan a piece of non-fiction text for common AI-writing tells: banned hype vocabulary, chatbot fingerprints, and structural patterns (uniform paragraph length, stacked transitions, em-dash overuse, rule-of-three compulsion, and more), plus this installer's own banned/custom word lists from add_banned_word/add_custom_word (the 'global' list, merged with a style's own list if styleId is given), plus a repo-local .etincelrc/.etincelrc.json/etincel.config.json if one exists at or above the current directory (dictionary as code, reviewable and versioned). Returns a tier (green/yellow/orange/red), a numeric score, specific findings with severity and location, and a strengths signal (specificity density, concrete-vs-abstract ratio, sentence-rhythm variation). Read strengths too, not just findings: it's the counter-signal against fixing every flagged word into flat, sterile prose. Never a silent rewrite. Use this to show the user what's flagged and why, so they stay in control of any change; only rewrite what they ask you to rewrite.
| Name | Type | Req | Description |
|---|---|---|---|
| register | string | – | Register to calibrate strictness against. Defaults to 'general'. |
| sourceFacts | array | – | Elicited answers from the skill's Step 0.5 (details only the user could supply, never generated): specific spans the draft was supposed to draw on. When given, checks how many actually made it into t… |
| styleId | string | – | Style id (from list_styles) whose own banned/custom word list should merge with the installer's global list. Omit to use only the global list. |
| text | string | yes | The text to audit. |
No output schema declared.
No examples provided.
check_self_repetition Check a draft for habits repeated across a voice's past pieces ~225
Compare a piece of drafted text against a trained voice's own recent training samples for two kinds of self-repetition: opening the same way ("you've opened this way in 4 of your last 6 pieces"), and reusing a characteristic phrase across several of them. This is about the writer's own recurring habits, not AI-writing tells; use audit_text for those. Only meaningful for a voice trained from real samples (train_style) with at least 3 recorded samples; dial-tuned or preset-forked voices, or ones with too little history yet, come back with an empty findings list rather than an error. Only the local install tracks sample history today, so a hosted/remote connection may always report zero history. A signal to weigh, same trust-mode spirit as audit_text: never rewrite the draft on the strength of this alone.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Deprecated alias for styleId. |
| styleId | string | – | Id of the trained voice to compare against, from list_styles. |
| text | string | yes | The drafted text to check. |
No output schema declared.
No examples provided.
check_voice_match Check a draft's rhythm against a trained voice ~312
Compare a piece of drafted text's measured sentence/paragraph rhythm and mechanics against a trained or custom voice's baseline (sentence length, rhythm variance, paragraph variance, contraction rate, em-dash use, fragment use, question use, structural entropy). Use this after drafting in a voice to check whether the draft's rhythm actually landed close to it, instead of just eyeballing it. Returns a verdict ('on rhythm' / 'some drift' / 'off rhythm'), a match score, specific dials that drifted with a plain-language note for each, and a caveat you should relay alongside the verdict: this is a rhythm/mechanics measurement, not an authorship or AI-detection check, so text merely shaped like the voice (by anyone, or any tool) can come back 'on rhythm', and a genuine off-voice draft by the target writer can still come back drifted. Confidence comes back "low" on short input, since a handful of sentences isn't enough to read rhythm reliably; treat a low-confidence verdict as provisional. Only works against trained or custom voices (from train_style, create_style_from_dials, or fork_style), not bare presets, which have no measured baseline; fork_style a preset first if you want to check a draft against one.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Deprecated alias for styleId. |
| styleId | string | – | Id of the trained or custom voice to compare against, from list_styles. |
| text | string | yes | The drafted text to check. |
No output schema declared.
No examples provided.
clear_style_instructions Clear custom instructions for a style ~53
Remove the saved instructions for a scope (global, or a specific style), leaving it empty.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id to clear, from list_styles. Omit to clear the global instructions. |
No output schema declared.
No examples provided.
create_style_from_dials Create a style from dials ~161
Build a style profile from explicit dial values instead of writing samples: for when the user wants to hand-tune a voice (or doesn't have samples handy). 3 persona dials (formality, warmth, directness, 0-10) plus 8 mechanical dials (0-100, including entropy: how much AI-typical structural regularity to break) that map onto the same measurements train_style extracts from real text, so a dial-built style and a trained voice are the same shape. Call again with the same name to overwrite.
| Name | Type | Req | Description |
|---|---|---|---|
| dials | object | yes | The 11 dial values (3 persona + 8 mechanical) that define this style's voice. |
| name | string | yes | Name for this voice. |
No output schema declared.
No examples provided.
delete_style Delete a trained voice ~56
Permanently delete a trained voice profile by id. Does not affect premade presets.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Deprecated alias for styleId. |
| styleId | string | – | Id of the trained voice to delete, from list_styles. |
No output schema declared.
No examples provided.
fork_style Fork a preset or published community style into a trained voice ~296
Copy a style into a new trained voice under the given name, seeded with its persona dials and drafting guide. Two kinds of source: a premade preset (e.g. 'pr-review', 'linkedin-post'), or another installer's style published publicly on the hosted gallery, addressed as "handle/slug" (e.g. "jpleblanc/blunt-memo", the same address shown on its public page at etincel.ai/v/handle/slug). A public-style fork also carries over its 8 mechanical dials (rhythm, sentence length, em-dash use, etc.) and any banned words, custom words, or drafting instructions the source installer set specifically for that style, never their private account-wide dictionary or instructions; a preset fork only ever has persona dials and entropy to carry, since a preset has no measured mechanics. A public-style fork makes one network call to etincel.ai to fetch it; a preset fork never leaves this install. The fork is then a normal trained voice: retrain it with train_style from real samples, or hand-tune it with update_style, without touching the original.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | yes | Name for the new trained voice. |
| presetId | string | – | Deprecated alias for styleId. |
| styleId | string | – | Id of the preset to fork (from list_styles), or a published style's "handle/slug" address. |
No output schema declared.
No examples provided.
get_style_guide Get a style guide ~167
Fetch the full drafting guide for one style (a preset id like 'direct-warm', the id of a trained voice, or 'team' for the shared style a .etincelrc in the current repo defines, if any). Returns prose instructions to follow while drafting or revising: sentence rhythm, tone dials, and (for trained voices) the writer's own measured habits. If a .etincelrc in the current repo sets team-wide instructions, those are folded into every style's instructions, not just 'team''s. Read this before drafting; it is context for you, the drafting model, not a tool that writes prose itself.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | yes | Preset id, trained voice id, or 'team', from list_styles. |
No output schema declared.
No examples provided.
get_style_instructions Get custom instructions for a style ~83
Show the saved instructions for a scope: the global instructions (default), or a specific style's own. For a style, also returns the effective merged text (global plus that style's own) that get_style_guide already folds in automatically.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id to look up, from list_styles. Omit for the global instructions. |
No output schema declared.
No examples provided.
list_dictionary List a dictionary's banned and custom words ~92
Show the banned-words and custom (allowed) words lists for a scope: the global list (default), or a specific style's list. For a style, also returns the effective merged list (that style's words plus the global ones): what audit_text actually applies when that style is selected.
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id to look up, from list_styles. Omit for the global list. |
No output schema declared.
No examples provided.
list_styles List writing styles ~85
List every available style: premade emotional-tone presets, any voices the user has trained from their own samples, and (if a .etincelrc in the current repo defines one) the shared team style, id 'team'. Call this before drafting or revising non-fiction prose if the caller hasn't been told which style to use, or if the user asks what styles exist.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
remove_banned_word Remove a word from a banned-words list ~69
Remove a term from this installer's banned-words list (global, or a specific style's list).
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id the ban was scoped to, from list_styles. Omit for the global list. |
| word | string | yes | The term to unban. |
No output schema declared.
No examples provided.
remove_custom_word Remove a word from a custom (allowed) words list ~71
Remove a term from this installer's allowed-words list (global, or a specific style's list).
| Name | Type | Req | Description |
|---|---|---|---|
| styleId | string | – | Style id the allowance was scoped to, from list_styles. Omit for the global list. |
| word | string | yes | The term to remove from the allowed list. |
No output schema declared.
No examples provided.
second_read Get a second read on a draft (hosted only) ~140
A single model call that reads a draft and reports what a careful human editor would notice: unscored, untiered, and never a rewrite. Distinct from audit_text, which is deterministic and reproducible; this is neither, so weigh it as one more opinion, not a verdict, and never gate a decision on it alone. Requires the hosted server (https://etincel.ai/api/mcp): the local (stdio) install has no account to bill a model call against, so this always fails there with a clear explanation. audit_text remains fully available locally, no account needed.
| Name | Type | Req | Description |
|---|---|---|---|
| text | string | yes | The text to read. |
No output schema declared.
No examples provided.
set_default_style Set the default style ~79
Set which style (preset or trained voice) should be used by default for this user going forward, so it doesn't need to be re-specified every time.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Deprecated alias for styleId. |
| styleId | string | – | Id of the style (preset or trained voice) to set as default, from list_styles. |
No output schema declared.
No examples provided.
set_style_instructions Set custom instructions for a style ~177
Save free-text drafting rules layered on top of a style's voice: required elements ('always include a CTA'), audience notes, forbidden topics, format constraints, anything that isn't about sentence rhythm or tone. Overwrites whatever was saved for this scope. Without styleId, this sets the global instructions, which apply to every style. With styleId, it only applies to that specific style, merged after the global instructions (get_style_guide returns the merged result automatically). Use this when the user says something like 'for this style, always end with a CTA' or 'remember: never mention pricing in emails'.
| Name | Type | Req | Description |
|---|---|---|---|
| instructions | string | yes | The full instructions text for this scope, replacing whatever was there. |
| styleId | string | – | Style id to scope this to, from list_styles. Omit to set the global instructions. |
No output schema declared.
No examples provided.
train_style Train a voice from writing samples ~304
Analyze one or more of the user's own writing samples (emails, posts, essays, memos: real finished text they wrote or approved) and persist a trained voice profile under that name. Measures sentence length and variance, paragraph rhythm, contraction rate, em-dash and semicolon habits, fragment use, structural entropy (sentence-opener variety and punctuation-mark variety), and recurring phrasing. Call again with the same name and new samples to add more training data to that voice; the new samples blend into its existing measurements rather than replacing them. If the voice may have been renamed since it was created, pass its id (from list_styles) instead so the right voice is targeted regardless of its current name. This never fabricates a voice from a description; it only learns from real text the user supplies.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Deprecated alias for styleId. |
| name | string | yes | Name for this voice, e.g. the user's name or a project name. |
| samples | array | yes | One or more raw text samples of the user's own writing, at least a few paragraphs each for a reliable read. |
| styleId | string | – | Id of an existing trained voice to train further, from list_styles. Use this to precisely target a voice you want to add more samples to, especially if it's been renamed. Omitted: falls back to match… |
No output schema declared.
No examples provided.
update_style Edit an existing custom style ~159
Rename a trained voice or adjust its dials in place, keeping its id (and default-style pointer) stable. Persona dials (formality, warmth, directness) always apply; the mechanical dials only take effect if the voice has no writing samples (was built from dials, not trained). A sample-trained voice keeps its measured mechanical stats regardless of what's passed here.
| Name | Type | Req | Description |
|---|---|---|---|
| dials | object | yes | The 11 dial values (3 persona + 8 mechanical) that define this style's voice. |
| id | string | – | Deprecated alias for styleId. |
| name | string | yes | New (or unchanged) name for this voice. |
| styleId | string | – | Id of the trained voice to edit, from list_styles. |
No output schema declared.
No examples provided.
How do I install the ai.etincel/etincel-nonfiction MCP server?
ai.etincel/etincel-nonfiction runs locally as an npm package, launched with npx -y etincel. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · etincel
claude mcp add ai-etincel-etincel-nonfiction -- npx -y etincel
What is the ai.etincel/etincel-nonfiction MCP server?
ai.etincel/etincel-nonfiction is an MCP server listed in the public MCP registry as ai.etincel/etincel-nonfiction. Trainable non-fiction writing voice, presets, and an anti-AI-tells audit for Claude, via MCP. This page covers its npm package (etincel).
Is the ai.etincel/etincel-nonfiction MCP server safe to use?
ai.etincel/etincel-nonfiction scores 80 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 25 October 2026. It declares an install script we flagged as high risk. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the ai.etincel/etincel-nonfiction MCP server expose?
ai.etincel/etincel-nonfiction exposes 20 tools: list_styles, get_style_guide, train_style, create_style_from_dials, update_style, and 15 more. Their descriptions and schemas cost roughly 3,238 tokens of context every time the server is loaded.
Is the ai.etincel/etincel-nonfiction MCP server still maintained?
ai.etincel/etincel-nonfiction is still listed as active in the MCP registry. We last reached this channel on 25 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the ai.etincel/etincel-nonfiction MCP server under?
ai.etincel/etincel-nonfiction declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.