Atlas / MCP servers / dcondrey / Scrivener

ScrivenerBLOCK

mcp/dcondrey/scrivener

The definitive MCP server for Scrivener — connect your novels, screenplays, and manuscripts to Claude, ChatGPT, and any AI assistant. 53 tools: document management, writing analysis, content enhancement, offline semantic search, and character/plot tracking.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
81 59r · 20w · 2d
Transport
stdio
License
AGPL-3.0
Stars
65
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Scrivener MCP

MCP server for Scrivener: connect your novels, screenplays, and manuscripts to Claude, ChatGPT, and any AI assistant, with document management, writing analysis, content enhancement, offline semantic search, and character/plot tracking.

[](https://github.com/writerslogic/scrivener-mcp/actions/workflows/ci.yml) [](https://github.com/writerslogic/scrivener-mcp/actions/workflows/codeql.yml) [](https://securityscorecards.dev/viewer/?uri=github.com/writerslogic/scrivener-mcp) [](https://www.npmjs.com/package/scrivener-mcp) [](https://github.com/writerslogic/scrivener-mcp/blob/main/LICENSE)

Install · What You Can Do · All Tools · Guides · Contributing

Scrivener MCP lets your AI assistant open, read, edit, analyze, and search your Scrivener projects directly. No exporting, no copy-pasting text back and forth. Tell it which project to open and start working.

You: Open my novel and analyze the pacing in Chapter 12. Claude: Opens the .scriv project, reads Chapter 12, runs pacing analysis. The first half moves well, but the middle stalls — a three-page internal monologue starting at paragraph 14 kills the momentum you
Read from source at commit e803c52b9502OBSERVED · 2026-10-09
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add scrivener-mcp -- npx -y [email protected]
03

Exposed tools (81)

59 read · 20 write · 2 destructive. Blast radius: 2 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
add_relationshipwriteRecord a typed, directed relationship between two story entities (e.g. a character
advancedreadAsync job queue and batch operations
analysisreadAnalyze writing quality, enhance prose, check consistency, track goals, tune writing preferences
analyze_craft_localwriteRun local, deterministic prose-craft analysis on a document: readability grade levels,
analyze_dialogue_tags_localreadAudit dialogue in one document: the dialogue-to-narration ratio and every quoted line with
analyze_documentreadAnalyze the writing quality of a single document and return a summary of readability, pacing,
analyze_foreshadowing_localwriteScan the whole manuscript, in binder order, for setup/payoff pairs: recurring terms
analyze_opening_localreadAnalyze a document
analyze_rhythm_localreadMeasure sentence-length flow in one document: the distribution of sentence lengths, a
analyze_writing_stylereadAnalyze the prose style of one or more text samples — sentence variety, tone, voice,
build_vector_storereadBuild search index
cancel_jobreadCancel a queued or running background job by its type and id. Returns whether the
character_networkreadTHE default tool for
check_consistencyreadScan the whole project for continuity problems and return the issues found: character
check_continuity_localwriteScan the whole manuscript, in binder order, for local-analyzer continuity signals: a
check_plot_consistencywriteScan a set of documents for plot-level inconsistencies — timeline conflicts, contradicted
check_style_localwriteLine-edit one document with deterministic rules: -ly adverbs, filter words (felt, saw,
close_projectwriteClose the currently open project, flush any pending memory/auto-save state, and clear the
collect_feedbackreadRecord feedback on an AI operation (e.g.
compare_snapshotreadCompare a document snapshot against the current document text, or against another snapshot
compilationreadCompile manuscripts, export, statistics
compile_documentsreadCompile the project
create_documentwriteCreate a new text document or folder in the binder and return its new id. Optionally set the
create_snapshotwriteTake a Scrivener-native snapshot of a document
delete_documentdestructiveMove a document to the project trash. This is reversible: the document can be listed with
detect_open_projectreadDetect which Scrivener project the user currently has open in the desktop Scrivener app, so
discover_connectionsreadSurface previously unrecorded relationships across the project by analyzing entity
discover_projectsreadScan common locations (Documents, Desktop, and iCloud Mobile Documents) for Scrivener
documentsdestructiveRead, write, create, delete, move, and rename documents
enhance_contentreadProduce an AI-improved version of a document
export_projectreadExport the whole project to a publishing/interchange format. Markdown, HTML, and JSON
find_analogiesreadFind analogies (A:B :: C:?)
find_mentionsreadFind every occurrence of a specific name or term (a character, place, or keyword) across all
find_orphaned_entitiesreadList registered characters and locations that no document actually mentions — entities added
find_relationshipsreadQuery the story graph for entities related to a given entity, returning the connected
find_repetition_localreadFind echoes (the same word reappearing within a window of words) and repeated multi-word
generate_contentreadGenerate new prose from a natural-language prompt and return the generated text, optionally
generate_marketing_materialsreadGenerate a publishing/marketing artifact from the manuscript — a synopsis, query letter,
get_compile_settingsreadReturn the project
get_document_inforeadReturn metadata for a single document without its body text: title, type, word count,
get_entity_referencesreadTrace the reference graph between documents and registered characters/locations, in either
get_job_statusreadLook up the status and progress of a background job previously started by
get_manuscript_briefingreadOne
get_queue_statsreadGet job queue statistics
get_statisticsreadReturn project-wide statistics: total word and document counts, plus title and author. Use
get_structurereadReturn the binder hierarchy of the open project: its folders and documents in tree order,
get_writing_goalsreadList writing goals with computed progress: percent complete, words remaining, and whether each
get_writing_preferencesreadReturn the current author writing preferences plus feedback insights: how much feedback has
hhm_dreamreadCreative concept recombination
list_skillsreadList the available skills (tool groups) — project, documents, search, analysis,
list_snapshotsreadList the snapshots Scrivener has saved of a project
list_trashreadList all documents currently in the project trash, with their ids and titles. Use this to
manuscript_style_report_localwriteRun the bluepencil report over every manuscript document in binder order and tabulate per-
measure_voice_drift_localreadMeasure how a character
memoryreadStore and recall persistent project facts (characters, world, plot, style)
move_documentwriteMove a document or folder to a different parent folder in the binder, optionally at a specific
multi_agent_analysisreadMulti-agent analysis
open_projectreadOpen a Scrivener project and make it the active project for this session. Every document,
projectwriteOpen, browse, save, close, and verify Scrivener projects
queue_document_analysisreadEnqueue a background NLP analysis of one document (readability, entities, sentiment) and
queue_project_analysisreadEnqueue a background batch analysis across many documents at once and return a job id
read_annotationsreadReturn the inline comments and footnotes attached to a document, grouped by type. Use this
read_documentwriteRead the text of a single document. By default returns plain text; set format to
read_snapshotreadReturn the text of a single document snapshot. Pass the documentId and the snapshotId from
recallreadRead back the project
refresh_projectreadReload the open project from disk, discarding the in-memory cache. Use this when the project
relationshipsreadEntity relationships, character networks, story graph
rememberwriteStore or update a fact in the project
restore_documentreadRestore a trashed document back into the binder, optionally into a specific target folder
searchreadSearch the open project and return matching documents with relevance-ranked snippets. By
semantic_searchreadFind passages by meaning rather than exact words, using the local HMS index, and
set_writing_goalwriteCreate or replace the active word-count goal for a cadence (daily, weekly, or whole project),
set_writing_preferenceswriteSet the author writing preferences that shape AI writing output (enhance_content and other
store_chapter_orderwriteStore chapter sequence
suggest_connectionsreadSuggest characters or locations a document might be missing: entities it does not mention
suggest_improvementsreadGenerate AI writing suggestions for a prompt or a specific document — ideas for revision,
sync_to_neo4jwriteSync relationships to Neo4j
update_documentwriteUpdate a document
use_skillreadActivate a skill so its tools become available to call. Returns the activated skill
verify_project_integrityreadScan the open project for structural problems and return a read-only report: binder entries
write_documentwriteReplace a document
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (7 observation(s))
Network
declared (6 observation(s))
Shell
declared (1 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (18)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/services/auto-setup/keydb-installer.ts:663
const child = exec(command, (error, stdout, stderr) => {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMInventory / provenance · inv.binary · CWE-1104
.scrivener-hms.db/db
db
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
delete_document, documents
Why it matters. 2 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.binary · CWE-1104
tests/sample-project.scriv/Files/binder.autosave
binder.autosave
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.hidden_file · CWE-1104
.bestpractices.json
.bestpractices.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierrc.json
.prettierrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/handlers/database/sqlite-optimizer.ts:426
return crypto.createHash('md5').update(combined).digest('hex');
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/services/document-manager.ts:353
const hash = crypto.createHash('sha1').update(bytes).digest('hex');
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/utils/scrivener-utils.ts:766
const hash = crypto.createHash('md5').update(seed).digest('hex');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/analysis/analyzers/emotion-analyzer.ts:1
import { getLogger } from '../../core/logger.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/analysis/analyzers/emotion-analyzer.ts:2
import { splitIntoSentences } from '../../utils/text-metrics.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/analysis/analyzers/metrics-analyzer.ts:1
import { getWritingTextMetrics as getTextMetrics } from '../../utils/text-metrics.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/analysis/analyzers/metrics-analyzer.ts:2
import { simdTextProcessor } from '../../utils/simd-text-processor.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
src/analysis/analyzers/metrics-analyzer.ts:3
import { generateHash } from '../../utils/common.js';
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@anthropic-ai/sdk, @modelcontextprotocol/sdk, better-sqlite3, bluepencil-node, bullmq, chalk, cheerio, compromise
Why it matters. 48 dependency range(s) float
Fix. pin exact versions or ship a lockfile
INFOPrompt injection · prompt.authority_framing · CWE-94, CWE-1427
docs/token-optimization.md:3
Scrivener projects can be massive -- hundreds of documents, deeply nested binders, and chapters exceeding 10,000 words. Without optimization, a single tool call could consume the entire context window
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/CLIENT_SETUP.md:245
Core read/write/search tools work without API keys. See [Getting Started](./getting-started.md#environment-variables) for the full list.
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-09 · audit v0.4.1 · source sha e803c52b9502full audit observations/trust-audit/mcp-server/dcondrey__scrivener.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-09e803c52b9502BLOCKD69first audit
06

Questions

What is the Scrivener MCP server?

The definitive MCP server for Scrivener — connect your novels, screenplays, and manuscripts to Claude, ChatGPT, and any AI assistant. 53 tools: document management, writing analysis, content enhancement, offline semantic search, and character/plot tracking.

What tools does Scrivener expose?

81 in total: 59 read-only, 20 that write, and 2 that can delete or overwrite (delete_document, documents). Every one is listed on this page with its risk.

Is Scrivener safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 2 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does Scrivener need?

It reads ANTHROPIC_API_KEY, KEYDB_URL, NEO4J_PASSWORD, OPENAI_API_KEY, OPENROUTER_API_KEY and SCRIVENER_DISABLE_KEY_DISCOVERY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Scrivener run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as scrivener-mcp at 0.12.0.

How current is this page?

The grade is for one exact copy of the source (e803c52b9502), read on 2026-10-09. The repository is watched and re-audited when it changes.

Advertisement