eBook Doctor
This is the complete privacy policy for eBook Doctor, the app for ChatGPT operated by Global Scholar Press (a trading name of Nobtrex LLC, United States) at https://globalscholarpress.com/mcp. It states every category of data the app receives, what each tool sends back to ChatGPT, why we process it, who else sees it, how long we keep it, and how you delete it.
eBook Doctor is a set of 52 tools that ChatGPT calls on our server to inspect, repair, validate, convert and prepare EPUB files, and to help you review the writing chapter by chapter. Our server runs no AI model of its own: it executes exactly the operations ChatGPT requests, using deterministic programs (our EPUB engine, the official EPUBCheck validator and Calibre for format conversion). It is free and needs no account.
This policy covers the app endpoint /mcp, the download endpoint /dl/… and the book pages /book/…. The rest of globalscholarpress.com — the marketing site, the free online EPUB editor and the paid book-writing service — is covered by the website privacy policy.
The EPUB you attach in ChatGPT, and any cover image or replacement file you ask ChatGPT to put into the book. ChatGPT passes our server a temporary download link and we fetch the file from it; files up to 80 MB are accepted. Two fallbacks exist for the same purpose: you can give a public URL (our server then makes an ordinary web request to that address, so the site hosting it sees our server’s request, not your device) or small files can be passed inline as base64. Your original upload is stored untouched and is never modified.
ChatGPT sends the arguments each tool needs. Across the whole app these are:
book_id) of the book being worked on;Nothing else is requested. The tools ask for no profile data, no “just in case” fields and no conversation context beyond the arguments of the call.
When a book is opened we generate a random 32-character workspace identifier, and when files are delivered a random book-page token. They are not derived from you or your device, they identify one book, and they exist only as long as the workspace does.
Our web server and application record, for each request, the time, the endpoint or tool name, the HTTP status, the size of the response, the browser identification string and the network address the request came from. Tool calls arrive from OpenAI’s servers, so for the app that address is OpenAI’s infrastructure, not your device. If ChatGPT sends an MCP session header we log only its first 12 characters; at the time of writing ChatGPT sends none. Opening your book page in your own browser is an ordinary web request, so that one does carry your address.
We do not receive your OpenAI account, your name, e-mail address or phone number, your chat history, or anything you type in ChatGPT that is not an argument of a tool call. We create no account, set no cookie and store no identifier in your browser from the app. We ask for no location, no payment details, no government identifiers, no credentials and no health data. Please do not place such data in a tool call; if you do, it is deleted with the workspace.
Every tool result goes to ChatGPT, which shows or summarises it for you; OpenAI then processes it under its own privacy policy. Results are limited to what answers the call. A result can contain:
links block with three addresses on globalscholarpress.com — the free EPUB editor (carrying your workspace identifier so it opens this book), our home page and the book-writing service page. They carry a campaign tag, utm_source=chatgpt, that tells us a visit came from the app. It identifies the app, not you, and a tool result sets no cookie and no advertising identifier.The complete field-by-field list of what a result can contain is in section 4. It is enforced by our server: every result is checked against that list and any field not on it is removed before it is sent.
Results never contain: our server’s file paths or directory names, program or converter logs, process exit codes, stack traces, the network address the call came from, internal diagnostic, debug or telemetry fields (such as byte offsets, internal issue ids or editor status flags), or anything belonging to another person’s book. If you want ChatGPT to see less of your book, ask it to read only the files or chapters you name.
All 52 tools, grouped by what they do. “Receives” lists the arguments in addition to the workspace identifier.
| Tools | Receives | Returns to ChatGPT |
|---|---|---|
open_book, get_book_summary, get_book_page, close_book |
Your attached EPUB (or a URL / base64 of it) and its file name. | The workspace identifier, file name, size, EPUB version, the book’s metadata, counts of files and chapters, the issue list, the book-page link — and, for close_book, confirmation that everything was deleted. |
list_resources, read_resource, get_resource_info, find_text, get_package, get_manifest, get_spine, get_navigation, list_checkpoints, diff_book, diff_checkpoint, diff_resource |
File paths, resource kinds, line ranges, search terms or regular expressions, checkpoint ids. | The requested part of your book: file lists and sizes, file text, image dimensions, search hits with context, the package, manifest, reading order and table of contents, checkpoint lists and differences between versions. |
apply_patch, replace_text, replace_resource, create_resource, delete_resource, rename_resource |
A file path, the exact old text and the new text, or a whole replacement file (attached, URL or base64), or the new path. | Whether the edit applied, what changed, and whether the file still parses. |
update_manifest_properties, update_spine, update_navigation, rebuild_navigation, normalize_doctypes, fix_xml_entities, remove_missing_resources, ensure_identifier, repack_book |
The reading order, a table-of-contents label and target, or an identifier value; most take nothing else. | What was changed and the resulting structure — reading order, table-of-contents entries, identifier, packaging state. |
run_epubcheck, validate_resource, validate_css, kdp_check |
A file path or a severity filter. | Validation messages with code, severity, file, line and column; the EPUBCheck version; our plain-language diagnosis; before/after error counts with the time of each check; the KDP readiness checklist. |
create_checkpoint, restore_checkpoint |
A label, or the checkpoint id to roll back to. | The checkpoint id, label, kind and creation time, and the issue counts after a rollback. |
list_chapters, get_chapter, update_chapter, mark_chapter_reviewed |
A chapter number or path, how many words per part, the paragraph-addressed edits, and your review status, note and issue count. | The chapter list with titles, kinds, word and paragraph counts and review status; the chapter’s text as numbered paragraphs (or its raw markup); the result of each edit; the review note you stored and when you stored it. |
update_metadata, write_metadata_into_epub |
Title, author, language, publisher, description, rights, subjects, date, identifier. | Which fields were written into the book file, and the metadata as it now stands. |
suggest_metadata, bisac_lookup, save_metadata, get_metadata |
A category search term, and the listing metadata to save: title, subtitle, series, authors, publisher, language, description, 7 keywords, 3 BISAC codes, prices, page count, trim size, ISBNs, target audience, copyright statement, AI-disclosure answer. | Your book’s existing metadata, its headings and a sample of its text, and the store’s limits, so that ChatGPT — not our server — writes the listing; matching BISAC codes; the validation result and the list of files saved next to your book. |
cover_spec, set_cover |
The cover image you or ChatGPT produced (attached, URL or base64) and where to put it. | The current cover status, the store’s cover requirements, an image-prompt skeleton containing your title and author, and the dimensions and any warnings for the installed cover. |
export_book, convert_book |
The output format, and whether to include the readiness reports. | The validation result that had to pass first, the produced file’s name and size, the book-page link and how long it lasts. The converter’s own log is not returned. |
paperback_cover_geometry |
Trim size, page count and paper type. It touches no book and no workspace. | Spine width and full cover dimensions in inches and pixels. |
This is the complete list. Before a result leaves our server, every field that is not on it is removed, so a result can hold only these fields, nested exactly as named (a.b is field b inside a; a[] is each item of list a; a.* is a count keyed by severity or kind). There are no hidden, debug or diagnostic fields. Most fields appear only in the results of the tools that need them.
| Field | Contains |
|---|---|
book_id | the random workspace identifier of the open book |
new_book_id | the workspace identifier of a converted copy |
filename | the file name you uploaded, or the name of the produced file |
size_bytes | file size in bytes |
epub_version | EPUB version declared by the book (2.0 / 3.0) |
closed | true when the workspace and all its files were deleted |
edits_applied | how many edits were made in this workspace |
manifest_count | number of files listed in the book's package |
spine_count | number of documents in the reading order |
| Field | Contains |
|---|---|
metadata.title | title |
metadata.subtitle | subtitle |
metadata.author | author name(s) as written in the book |
metadata.authors[] | author names in a saved listing |
metadata.publisher | publisher |
metadata.language | language code |
metadata.identifier | the book's identifier (ISBN, UUID or URL) |
metadata.isbn | ISBN in a saved listing |
metadata.date | publication date |
metadata.rights | rights statement |
metadata.subject | subjects / categories |
metadata.description | description or blurb |
metadata.series | series name |
metadata[].index | position of a package metadata entry |
metadata[].kind | entry type (Dublin Core element or meta) |
metadata[].name | element name (title, creator, identifier …) |
metadata[].value | the entry's value as written in the book |
metadata[].id | the entry's XML id |
metadata[].refines | which entry it refines |
metadata[].property | meta property name |
metadata[].scheme | identifier scheme |
metadata[].role | contributor role |
metadata[].file_as | sort form of a name |
metadata[].language | language of the entry |
fields_written[] | which metadata fields were written into the book |
identifier | the identifier now set in the book |
unique_identifier | the id of the package's unique identifier |
| Field | Contains |
|---|---|
saved | whether a listing package exists for the book |
files[] | names of the files in the listing package |
bisac[].code | BISAC category code you chose |
bisac[].name | its official name |
problems[] | listing values that break a store rule |
metadata.generated_at | when the package was saved |
metadata.generated_by | the constant text “eBook Doctor (Global Scholar Press)” |
metadata.ai_disclosure | your answer to the store's AI-disclosure question |
metadata.listing.bisac_categories[].code | BISAC codes |
metadata.listing.bisac_categories[].name | BISAC names |
metadata.listing.keywords[] | the 7 store keywords |
metadata.listing.copyright | copyright statement |
metadata.listing.description_chars | length of the description |
metadata.listing.description_file | file holding the description |
metadata.listing.keywords_file | file holding the keywords |
metadata.listing.explicit_content | explicit-content answer |
metadata.listing.publication_date | publication date |
metadata.listing.target_audience | target audience |
metadata.ebook.epub_file | e-book file name |
metadata.ebook.cover_file | e-book cover file name |
metadata.ebook.price_usd | e-book list price |
metadata.paperback.interior_file | paperback interior file name |
metadata.paperback.cover_file | paperback cover file name |
metadata.paperback.isbn | paperback ISBN |
metadata.paperback.pages | page count |
metadata.paperback.trim_size | trim size |
metadata.paperback.paper | paper type |
metadata.paperback.ink | ink type |
metadata.paperback.price_usd | paperback list price |
| Field | Contains |
|---|---|
facts.title[] | title(s) found in the book |
facts.creator[] | author(s) found in the book |
facts.language[] | language(s) |
facts.description[] | existing description |
facts.subjects[] | existing subjects |
headings[] | chapter headings |
sample_text[] | a few opening paragraphs of the book |
constraints.* | the store's limits for each listing field (fixed text) |
bisac_hint | how to look up categories (fixed text) |
results[].code | matching BISAC code |
results[].name | its official name |
total_codes | size of the official BISAC list |
| Field | Contains |
|---|---|
resources[].path | path of a file inside the book |
resources[].ext | file extension |
resources[].kind | file kind (reading order, image, style …) |
resources[].size | file size |
resources[].in_spine | whether it is in the reading order |
resources[].spine_index | its position in the reading order |
path | path of the file a tool acted on |
size | its size |
is_text | whether it is a text file |
width | image width in pixels |
height | image height in pixels |
text | lines of a text file you asked to read |
start_line | first line returned |
end_line | last line returned |
total_lines | number of lines in the file |
hits[].path | file of a search hit |
hits[].line | line of a search hit |
hits[].match | the matched text |
hits[].context | text around the match |
opf | path of the package file |
opf_source | text of the package file (only when asked) |
opf_source_length | its length |
version | EPUB version in the package |
manifest.href | a file's address in the package |
manifest.id | its manifest id |
manifest.media_type | its media type |
manifest.properties | its manifest properties |
manifest.tag | its manifest entry as written in the package |
manifest[].href | package entry: file address |
manifest[].id | package entry: id |
manifest[].media_type | package entry: media type |
manifest[].properties | package entry: properties |
manifest[].tag | package entry as written in the package |
spine[] | reading-order ids |
spine[].idref | reading-order id |
spine[].href | reading-order file address |
spine[].path | reading-order file path |
nav.has_nav_doc | whether an EPUB 3 table of contents exists |
nav.has_ncx | whether an EPUB 2 table of contents exists |
nav.ncx_toc_entries | number of EPUB 2 table-of-contents entries |
entries[].label | table-of-contents label |
entries[].target | where it points |
entries[].full | file it points to |
entries[].level | nesting level |
entries[].source | which table of contents it comes from |
kdp_toc | whether the table of contents suits Kindle (PASS / REVISE / BLOCK) |
| Field | Contains |
|---|---|
chapters[].index | chapter number |
chapters[].title | chapter title |
chapters[].kind | chapter / front matter / table of contents … |
chapters[].path | chapter file |
chapters[].words | word count |
chapters[].paragraphs | paragraph count |
chapters[].review | review you recorded for the chapter |
chapters[].review.status | review status |
chapters[].review.notes | review note |
chapters[].review.issues | issue count |
chapters[].review.at | when the review was recorded |
kinds.* | how many chapters of each kind |
total_words | words in the whole book |
reviewed | chapters reviewed so far |
reviewed_total | chapters reviewed so far |
index | chapter number |
title | chapter title |
kind | chapter kind |
words | chapter word count |
part | which part of a long chapter |
total_parts | number of parts |
paragraph_count | paragraphs in the chapter |
paragraphs[].n | paragraph number |
paragraphs[].tag | paragraph element (p, h1 …) |
paragraphs[].text | paragraph text |
xhtml | the chapter's markup (only when asked) |
review | the review stored for this chapter |
review.status | review status |
review.notes | review note |
review.issues | issue count |
review.at | when the review was recorded |
report[].paragraph | paragraph an edit targeted |
report[].applied | whether it applied |
report[].mode | how it was applied |
report[].reason | why it did not apply |
| Field | Contains |
|---|---|
changed | whether anything changed |
applied | number of edits applied |
applied[] | what each edit did, in words |
verification.parse[].path | a file the edit touched |
verification.parse[].well_formed | whether that file still parses |
verification.parse[].error | the parse error, if it does not |
verification.issue_counts.* | structural issue counts after the edit |
steps[].step | repair step name |
steps[].changed | whether the step changed anything |
steps[].applied[] | what the step did |
steps[].message | step summary |
steps[].next_step | what ChatGPT should do next |
steps[].verification.issue_counts.* | issue counts after the step |
steps[].verification.parse[].path | a file the step touched |
steps[].verification.parse[].well_formed | whether it still parses |
steps[].verification.parse[].error | the parse error, if it does not |
documents_changed | number of documents changed |
fixed[].path | file in which characters were escaped |
fixed[].count | how many |
removed[] | files removed since a checkpoint |
removed[].id | manifest id of an entry removed because its file was missing |
removed[].href | address of that missing file |
added[] | files added since a checkpoint |
modified[] | files modified since a checkpoint |
repacked | whether the container was rewritten |
first_entry | first file in the container |
stored | whether that file is uncompressed (required) |
note | a remark about the operation |
| Field | Contains |
|---|---|
checkpoint.id | checkpoint id |
checkpoint.label | checkpoint label |
checkpoint.kind | original / automatic / manual |
checkpoint.created_at | creation time |
checkpoints[].id | checkpoint id |
checkpoints[].label | checkpoint label |
checkpoints[].kind | checkpoint kind |
checkpoints[].created_at | creation time |
checkpoint_id | checkpoint compared against |
restored | checkpoint rolled back to |
diff | line-by-line difference of a file |
truncated | whether a long answer was cut short |
files[].path | changed file |
files[].status | added / removed / modified |
files[].text | whether it is a text file |
files[].old_size | size before |
files[].new_size | size after |
files[].diff | difference of that file |
files[].diff_truncated | whether that difference was cut short |
summary.added | files added |
summary.modified | files modified |
summary.removed | files removed |
summary.total | files changed |
ledger[].id | change id |
ledger[].type | change type |
ledger[].summary | what the change did |
ledger[].files[] | files it touched |
ledger[].checkpoint | checkpoint taken before it |
ledger[].created_at | when it was made |
| Field | Contains |
|---|---|
valid | whether the book or file is valid |
fatal | EPUBCheck fatal count |
errors | EPUBCheck error count |
warnings | EPUBCheck warning count |
warnings[] | warnings about an installed cover |
counts.* | message counts per severity |
epubcheck_version | EPUBCheck version used |
messages[].code | EPUBCheck message code |
messages[].severity | severity |
messages[].message | the validator's message |
messages[].resource | file it refers to |
messages[].line | line |
messages[].column | column |
messages[].suggestion | the validator's suggestion |
epubcheck_messages[].code | remaining blocking message code |
epubcheck_messages[].severity | its severity |
epubcheck_messages[].message | its text |
epubcheck_messages[].resource | its file |
epubcheck_messages[].line | its line |
epubcheck_messages[].column | its column |
epubcheck_messages[].suggestion | its suggestion |
history[].at | time of an earlier check in this workspace |
history[].fatal | its fatal count |
history[].errors | its error count |
history[].warnings | its warning count |
diagnosis.headline | one-sentence verdict |
diagnosis.blocking_count | blocking problems |
diagnosis.defects[].code | defect code |
diagnosis.defects[].severity | severity |
diagnosis.defects[].count | occurrences |
diagnosis.defects[].where[] | file:line of each |
diagnosis.defects[].what_is_wrong | plain-language explanation (fixed text) |
diagnosis.defects[].what_it_breaks | consequence (fixed text) |
diagnosis.defects[].fix_with | which tools repair it (fixed text) |
diagnosis.defects[].epubcheck_says | the validator's message |
diagnosis.truncated | whether the list was cut short |
diagnosis.next_step | what ChatGPT should do next |
issue_counts.* | structural issue counts per severity |
issues[].severity | severity of a structural issue |
issues[].message | what is wrong |
issues[].location | file it concerns |
well_formed | whether a file parses |
parse.well_formed | whether a file parses |
parse.error | the parse error |
has_doctype | whether a DOCTYPE is present |
has_title | whether a title element is present |
has_xhtml_ns | whether the XHTML namespace is declared |
images_without_alt | images missing alternative text |
ok | whether the check passed |
clean | whether a style sheet has no problems |
checked_bytes | size of the style sheet checked |
error_count | style-sheet errors |
warn_count | style-sheet warnings |
info_count | style-sheet notes |
count | number of items returned |
| Field | Contains |
|---|---|
ready | whether the book passes the checklist |
fail_count | failed checks |
checks[].check | check name |
checks[].status | pass / warn / fail |
checks[].detail | the measured value and the rule |
epubcheck.valid | validation result |
epubcheck.fatal | fatal count |
epubcheck.errors | error count |
epubcheck.warnings | warning count |
epubcheck_before.fatal | fatal count when the book was opened |
epubcheck_before.errors | error count when the book was opened |
epubcheck_before.warnings | warning count when the book was opened |
kdp_rules.* | KDP's published limits (fixed numbers) |
kdp_rules.cover_min_px[] | minimum cover size |
kdp_rules.ebook_70pct_royalty_price_usd[] | 70 % royalty price band |
cover.present | whether a cover is marked |
cover.id | its manifest id |
cover.href | its address |
cover.path | its path |
cover.name | its file name |
cover.media_type | its media type |
cover.size | its size |
cover.issues[] | cover problems |
cover.images[] | images in the book |
cover.images[].id | image id |
cover.images[].href | image address |
cover.images[].path | image path |
cover.images[].name | image file name |
cover.images[].is_cover | whether it is the cover |
current_cover.present | whether a cover is marked |
current_cover.id | its id |
current_cover.issues[] | cover problems |
current_cover.images[] | images in the book |
requirements.* | the store's cover requirements (fixed text) |
requirements.min_px[] | minimum cover size |
prompt_skeleton | an image-prompt outline containing your title and author |
trim_in[] | trim size in inches |
page_count | page count |
paper | paper type |
spine_in | spine width |
bleed_in | bleed |
spine_text_allowed | whether spine text fits |
full_cover_in[] | full cover size in inches |
full_cover_px_at_300dpi[] | full cover size in pixels |
layout | cover layout (fixed text) |
safe_zone_note | safe-zone rule (fixed text) |
| Field | Contains |
|---|---|
book_page_url | the link to your book page |
expires_in_hours | hours the files remain |
verified | whether the exported EPUB re-opened and parsed |
verify_checks[].check | post-export check |
verify_checks[].ok | its result |
reports[] | names of readiness reports on the book page |
target | conversion format |
new_book_summary.epub_version | EPUB version of a converted copy |
new_book_summary.issue_counts.* | its issue counts |
new_book_summary.kdp_toc | its table-of-contents verdict |
files[].name | file on the book page |
files[].kind | its kind |
files[].size | its size |
files[].note | its description |
| Field | Contains |
|---|---|
message | a short summary of what the tool did |
next_step | what ChatGPT should do next (fixed text) |
report_to_user | how ChatGPT should report the result (fixed text) |
error | why a call failed |
links.free_epub_editor | the GSP editor link for this workspace (utm_source=chatgpt) |
links.site | the GSP home page (utm_source=chatgpt) |
links.book_writing_service | the GSP book-writing service page (utm_source=chatgpt) |
We never use your book or its content to train AI models, never sell or rent data, never use app data for advertising or profiling, and never make automated decisions about you. The app displays no advertising.
Each book gets its own private workspace on our server, readable only by our application, addressed only by its random identifier; workspaces are never listed and cannot be browsed. Everything produced for a book — the repaired EPUB, converted formats, the metadata package and the reports — is delivered from one book page, globalscholarpress.com/book/<random token>, which is marked noindex and carries no advertising code. Anyone who has that link can download those files, so treat the link like the files themselves.
| What | Kept for |
|---|---|
| Your uploaded file, the working copy, checkpoints, exports, conversions, the metadata package, the reports and the book page | 24 hours after the last activity on that book, then deleted automatically. A purge runs every hour, and also whenever a book is opened. |
| Web-server request logs (time, endpoint, status, size, browser string, network address) | Rotated daily, deleted after 14 days. |
| Application log (time, tool name, first 12 characters of a session header if one is sent) | 90 days at most. |
| Daily usage counts and visit statistics | Counts are kept indefinitely; the per-day list of visiting addresses behind them is erased after 90 days. |
All connections use HTTPS. Workspaces are stored with owner-only permissions, are isolated by unguessable identifiers, are never listed, and no login exists that could expose them. Our staff open a workspace only to investigate a problem you report to us.
When this policy changes we update the date below, and material changes are announced on the support page. The version of this policy in force is the one published here.