Changelog
The notable changes in each release. Every release on GitHub also carries auto-generated notes listing every merged pull request, and Upgrading covers the steps an existing deployment has to take. Entries start at 0.17.0; see GitHub for earlier releases.
1.0.0
Upgrade actions. Some of these changes stop an install from starting, or change answers, unless you act first:
- Set
ENCRYPTION_SECRET_KEYto your own value before upgrading a multi-user install. Migration0040_connectionsencrypts stored service credentials with the key it sees. See Connectors: set ENCRYPTION_SECRET_KEY first. SCIM_ENABLED=truenow needsSCIM_TOKEN; without it the API and the worker fail at start instead of answering SCIM calls with 503.- Agentless chats and agents that don’t set a chunk count now retrieve 6 chunks per search instead of 2. Answers draw on more context and use more tokens.
LLM_PROVIDERalone now picks the default model; it no longer also needsAPI_KEY. An install that set only a provider key (sayLLM_PROVIDER=anthropicandANTHROPIC_API_KEY) used to fall back to the hosted DocsGPT model and now calls, and is billed by, that provider.LLM_PROVIDER=openaiwith the key inAPI_KEYnow really uses OpenAI instead of the hosted API. SetLLM_NAME=docsgpt-localto keep the hosted model. See Default model.- Each API key now goes only to the endpoint it was configured for.
API_KEYbelongs toLLM_PROVIDERalone, and an unsetFALLBACK_LLM_API_KEYnow means the fallback provider’s own key (sayANTHROPIC_API_KEY) instead ofAPI_KEY. A request whose model DocsGPT cannot resolve to its own endpoint now fails withModel '<id>' is not availableinstead of going to OpenAI. See API keys stay with their provider. LLM_PROVIDER=llama.cppandLLM_PROVIDER=huggingfaceare gone; neither ever answered. Reach llama.cpp through its OpenAI-compatible server withOPENAI_BASE_URLandLLM_NAME.VECTOR_STORE=lancedbcould never start and is gone from the setup scripts.- The checkout Compose files publish on
127.0.0.1only. A server others reach needsDOCSGPT_BIND=0.0.0.0(see below). - A connector sign-in started from a frontend origin that is not allowed now fails with
origin_not_allowed. Allowed origins come only from configuration (CONNECTOR_REDIRECT_BASE_URI,OIDC_FRONTEND_URL,CONNECTOR_ALLOWED_ORIGINS); list any other frontend origin or host name there. See Connector sign-ins finish in the app. LLM_PATH,HUGGINGFACE_API_KEY,LANCEDB_*,RETRIEVERS_ENABLEDandDEFAULT_MAX_HISTORYare no longer read; delete them from.env.SAGEMAKER_*still works as the S3 credentials fallback but is deprecated in favour ofS3_*.- The code sandbox image grew (LibreOffice, Chromium, OCR, ffmpeg, Node.js): rebuild the runner
image and raise a hand-set
SANDBOX_MEMORYto4g. On Daytona, build the newdocsgpt-sandbox-py312-v3snapshot and pointDAYTONA_SNAPSHOTat it. See Daytona snapshot.
Connectors
Service credentials (OAuth tokens for Google Drive, SharePoint, Confluence and MCP servers, and API keys for tools) now live on encrypted connections that an admin governs in Admin > Connectors, and synced sources run as their connection without a browser session. See Connectors.
Roles, quotas and tokens
- Resource sharing was reworked: agents and the sources, prompts and tools they use can be shared with a team, with sponsors keeping shared agents working. See Access Control, Roles & Teams.
- Usage quotas let an instance admin cap the tokens each user spends, or what they cost.
- Personal access tokens let scripts call the API as a user.
docsgpt grant-admincreates the first admin from the Docker image or a pip install, wherescripts/grant_admin.pywas not available. See Bootstrapping the first admin.- The admin dashboard gained an activity feed and a usage export, and execution traces record GenAI spans.
Chat
Answers render math, and the chat widget is published at 0.8.0.
- A turn waiting on a tool approval no longer stays “streaming” when you send a new message instead of answering, or when the approval expires. The turn is saved with its text and the calls that ran; the calls it waited on show as not run, the model reads them that way on the next turn, and the approval clears in your other tabs. Approving it later from a stale tab does nothing and reloads the chat. See Tools that need approval. On later turns the model reads that turn’s text before its tool results, as it was written, so it no longer takes the calls it made for a plan that never ran. A call that didn’t run is labelled by its tool and action (“Memory · Create”) instead of as done (“Saved … to memory”), so the label no longer contradicts its not run note.
- A tool call the server refuses (a secret reference a tool can’t take, a write an admin turned
off, an API caller’s write on the owner’s account) stays on the message as a failed call with its
reason after a reload, and is no longer worded as a headless run in an interactive chat. On the
API its
tool_callevent now reports"status": "error"(it was"denied"), still with"error_type": "tool_not_allowed".
Tools and list settings
DEFAULT_CHAT_TOOLS,GUARDRAILS_CHECKS_ENABLEDandQUOTA_UNPRICED_RATE_PER_MILLIONaccept a JSON list or comma-separated values; a comma-separated value used to stop the API and the worker from starting. An empty value keeps the default, andDEFAULT_CHAT_TOOLS=noneturns the default chat tools off.noneis not special forGUARDRAILS_CHECKS_ENABLED; useGUARDRAILS_ENABLED=falseto turn guardrails off.- One custom tool without a class docstring no longer empties the Add Tool list for every user; a tool that can’t describe itself is skipped and logged.
- A new Code Execution Sandbox page covers running the sandbox the Artifact and
Code Executor tools need, and
scripts/build_daytona_snapshot.pypins the runner image’s render library versions. - The runner image and the Daytona snapshot are built from one package list and now carry PDF,
HTML and YAML libraries (pypdf, pdfplumber, requests, beautifulsoup4, PyYAML), tesseract OCR,
poppler, ffmpeg, headless LibreOffice and Chromium with
office-convert,html-to-pdfandhtml-screenshothelpers, Node.js 24, and fonts for Arabic, Devanagari and CJK text.pip installinside the self-hosted runner now works; its read-only filesystem made it fail. See What the sandbox has installed. - The Code Executor’s description is shorter and states what each backend keeps between calls,
where files must go to reach the user, and which library makes each format. A new session’s
first result lists the environment, results carry
hintlines for common mistakes (a missing import,apt-get, files written to/tmp, the app’s own URLs, missing fonts, the same error twice), and output tails drop colour codes and pip noise. See Hints in results.
API
- The Swagger UI moved from
/to/api/docs, so the bundled web UI no longer hides it;/swagger.jsonis unchanged, and/on an API without the web UI redirects to/api/docs. - Agent import accepts
curl --data-binary @file.agent.yamlwithout a Content-Type header (it used to read an empty body and return 400). - Docs: new API section with an overview and a REST API reference generated from the Swagger document, including the token scope for each endpoint.
- DocsGPT’s MCP server now answers at
/mcpas well as/mcp/. Before,/mcpwithout the slash returned 404 to a POST. - An agent webhook run stops after
WEBHOOK_RUN_TIMEOUT(default 600 seconds) and its task ends with"status": "timeout"; before, nothing bounded it. A run that raises an error is no longer retried, since each retry ran the agent again, tool actions included: the task endsFAILURE. See Webhooks.
Schedules
- The Schedules tab no longer pre-approves every tool. Tools with actions that need approval are listed unticked under Tools that need approval, and a scheduled run performs those actions without asking only for the tools you tick. Existing schedules keep their approvals; see Upgrading.
- Editing a one-time task’s date or time in the Schedules tab now moves the task; the change used
to be ignored.
PUT /api/schedules/<id>acceptsrun_atfor one-time tasks, and the schedule dialog shows why a save was refused. - A scheduled run no longer writes a
source='schedule'row with its total tokens totoken_usagenext to the rows its LLM calls already wrote, so queries that sum the table no longer count scheduled spend twice. Older rows stay out of every DocsGPT total, now including the admin overview’s 30-day token count.
Documentation
New docs pages: Agent Schedules, MCP Server, Background Jobs and Data Retention, Custom Models, and a Using DocsGPT section (web app, sharing conversations, teams and sharing, analytics and logs).
Integrations
- Chatwoot extension: verifies Chatwoot’s timestamped webhook signature, sends a valid
history, returns 502 when DocsGPT or Chatwoot fails, and reads optionalaccount_id/assignee_idfilters from.env. - Chatwoot extension:
python app.pylistens on port 5000 (orPORT) instead of 80, and.envis read from the extension’s folder instead of the working directory. See Upgrading. - Chatwoot extension: optional, insecure
chatwoot_allow_unsigned=truefor Chatwoot versions that don’t sign webhooks. - Reddit connector: comma-separated search queries and the post count from the connector form are now parsed correctly.
- Widget docs: the CDN bundle is
dist/legacy/browser.js. .env-templateno longer enables SharePoint with placeholder values.- Compose files drop the unused
VITE_CONFLUENCE_CLIENT_IDandVITE_SHARE_POINT_CLIENT_ID.
Deployment files
deployment/docker-compose-azure.yamlanddeployment/docker-compose-local.yamlare removed. Neither was documented, and both had drifted: the Azure file’s worker had no data volumes, no scheduler and noCACHE_REDIS_URL. Usedocker-compose-hub.yamlfor pre-built images,docker-compose.yamlto build from the checkout, ordocker-compose-dev.yamlin place of-local. The database moves to a new volume; see Upgrading.- The Mongo to Postgres backfill (
scripts/db/backfill.py) applies the migrations before it copies, so it works against an empty database, and takes--mongo-dbfor a database not nameddocsgpt.
A development loop in one command
docsgpt dev runs this checkout’s API and worker as children of one terminal, both restarting when
you save, with their output interleaved and Ctrl-C stopping them together. --ui adds the Vite dev
server and --mock-llm runs the bundled mock model, so a working loop needs no API key.
docsgpt doctor checks PostgreSQL, its schema version, Redis, the model provider and the port;
docsgpt restart bounces the services without touching settings; docsgpt logs -f now follows a
native install; and docsgpt env set applies itself to a running native install instead of asking
you to run docsgpt up again. See
Setting up a development environment.
Run DocsGPT without Docker
docsgpt up --native runs the API and the worker as services on the machine itself, launchd on
macOS and systemd user units on Linux, against a PostgreSQL and Redis you already have
(--postgres-uri, --redis-url). status, logs, down and uninstall work on such an install
the same way they do on a Docker one, and never touch the database or Redis. See
Run it as services, without Docker.
New WORKER_API_URL sets where the worker sends its own calls into the API, and falls back to
API_URL. docsgpt up --native sets it to http://127.0.0.1:<port>, so an API_URL pointed at a
public reverse proxy no longer routes the worker’s calls out and back. docsgpt up also records the
API_URL it wrote and updates it when the machine’s network address changes, still keeping any
value you set yourself.
Back up and restore an install
docsgpt backup writes a dump of the database and a tar of each data volume into one archive, and
docsgpt restore <archive> puts them back. The settings file is left out unless
--with-settings asks for it, since it holds the install’s secrets, and a backup from a newer
DocsGPT is refused unless you pass --force. The archive is written readable only by its owner,
and the backend and the worker pause while it is made so the dump and the volume tars match. A
restore loads the dump into an empty database, keeping the current one aside until it succeeds, so an
older backup also restores over a database a newer release migrated. See
Backups.
The checkout stack answers on this machine only
The checkout Compose files (deployment/docker-compose.yaml, -hub and -dev),
which setup.sh and setup.ps1 run, published Postgres (password docsgpt), Redis (no password)
and the API on every interface. Postgres and Redis are now published on 127.0.0.1 only, and the
API (7091) and UI (5173) on DOCSGPT_BIND, 127.0.0.1 by default. The setup scripts ask whether
other machines should reach DocsGPT, write DOCSGPT_BIND=0.0.0.0 if so, and offer to set
AUTH_TYPE, whose options they now describe as what they are. An install that other machines
use has to set DOCSGPT_BIND=0.0.0.0 to keep working: see
Upgrading.
Kubernetes manifests that work
The manifests in deployment/k8s are rebuilt. The migration Job runs the packaged migrate command,
and the API and worker wait for it. Uploads go to an S3-compatible bucket and vectors to pgvector in
the bundled Postgres, so every pod sees the same files. The worker runs the beat scheduler, and
CACHE_REDIS_URL points at the in-cluster Redis. The Services are ClusterIP, with an Ingress
example for publishing over TLS, and the API serves the web UI, so the frontend Deployment is gone.
docsgpt-secrets.yaml holds plain-text placeholders, including ENCRYPTION_SECRET_KEY and
POSTGRES_PASSWORD (which was a shared docsgpt), and the pods refuse to start until they are replaced. Images are pinned to the release. An existing cluster has to
carry its keys over, reindex its database (the new Postgres image sorts text differently), re-encrypt
stored secrets and upload its documents again: see
Upgrading and the
Kubernetes guide.
Secrets and security defaults
- Connector OAuth sign-ins finish in the app, on its
/connectors/callbackpage, with the signed-in user’s own login, and only the user who started a sign-in can finish it. The OAuthstateis a one-time random value kept on the server. The API callback (/api/connectors/callback) forwards to that page, so redirect URIs registered with providers keep working; registering the app page directly also works. docsgpt up,setup.shandsetup.ps1generateENCRYPTION_SECRET_KEYon a fresh install, so a networked install can create connections and no longer seals tool, MCP and custom-model secrets with the public default key. An existing value is never replaced, and an existing Docker install gets no new key;docsgpt upsays how to rotate onto one.docsgpt up --nativeadds one on its first run and keeps the default readable throughENCRYPTION_SECRET_KEY_PREVIOUS.ENCRYPTION_SECRET_KEY_PREVIOUSnow also opens secrets saved on tools and custom models, not only connections, anddocsgpt connectors reencryptrewrites those secrets too, so the previous key can be removed after one run. Secrets neither key opens are left unchanged and counted.- Testing or saving an MCP server on a blocked address now says why (
Invalid server URL: <reason>) instead of a generic configuration error. - Rerunning
setup.shorsetup.ps1keeps the existingINTERNAL_KEY,JWT_SECRET_KEYandENCRYPTION_SECRET_KEY, and a fresh install always gets aJWT_SECRET_KEY. Their authentication menu now offers OIDC. - The optional Ollama overlays publish port 11434 on
127.0.0.1only. docsgpt up --domainand--expose networksetAPI_URLto the address they print, and the setup scripts ask for it when they expose DocsGPT, so agent images, webhook URLs, device pairing and MCP OAuth callbacks no longer point athttp://localhost:7091for everyone else. A value you set is kept. With a hand-written.env, setAPI_URLyourself: see Opening it from other machines.- Without
JWT_SECRET_KEY, the generated.jwt_secret_keynow lives in the data home instead of the directory the API was started from. A key left in that directory is copied there, so tokens stay valid. LLM_CACHE_ENABLEDandLLM_CACHE_TTLcontrol the Redis cache of LLM answers, which was always on for 30 minutes. The defaults keep that behaviour; see LLM Response Cache.- Changes in Admin > Connectors are recorded in the audit log as
connector_policy_set, with each setting’s old and new value. - The URL check for MCP servers, S3 endpoints and imported agents also refuses carrier-grade NAT
addresses (
100.64.0.0/10). - A provider’s API key could reach another provider. Right after a restart, two requests at once
could find the model registry empty; one then fell back to
LLM_PROVIDERwith no model and the OpenAI client sent the configured key toapi.openai.com(a DeepSeek key, in the case seen). The registry now loads once under a lock, a request whose model has no endpoint of its own is refused, and an LLM client refuses a configured key for any host it was not configured for. The Anthropic and Gemini clients are pinned to the endpoint that check sees, soANTHROPIC_BASE_URL,GOOGLE_GEMINI_BASE_URLandGOOGLE_GENAI_USE_VERTEXAIno longer redirect them. A configured key goes over plainhttponly to a host on your own network;LLM_ALLOW_PLAINTEXT_ENDPOINTSallows other internal names. See Plain http and your API key. See Keys stay with their provider. - The sandbox manager and the embedding models are also built once per process under a lock, so concurrent first requests no longer create a second sandbox session registry or load a model twice.
- Backend dependencies are updated, clearing the known vulnerabilities in pypdf, werkzeug, urllib3,
PyJWT, oauthlib, multidict and docling. JWTs are now signed and checked with PyJWT instead of
python-jose, which has an unfixed algorithm-confusion advisory and pulled in
ecdsa. Existing tokens stay valid. AJWT_SECRET_KEYshorter than 32 bytes now logs a warning. The code sandbox libraries move to Pillow 12.3, pypdf 6.19, pdfplumber 0.11.10, pandas 2.3 and matplotlib 3.11, so the Daytona snapshot is nowdocsgpt-sandbox-py312-v3. - A new security checklist covers bind addresses, the choice of
AUTH_TYPE, the secrets to set, outbound URL checks, prompt templates, the LLM cache and the version check.
0.21.0
Install with one command
curl -fsSL https://docs.ac/install | bash on macOS and Linux, or irm https://docs.ac/install.ps1 | iex
in Windows PowerShell, installs uv and the docsgpt package and runs docsgpt up. Running it again
upgrades and keeps your settings. On Linux it offers to install Docker when it is missing. Both
scripts are attached to every release. See the Quickstart.
docsgpt up runs DocsGPT on Docker
The Python package now sets up and runs the Docker stack: uv tool install docsgpt, then
docsgpt up. The first run asks who should reach DocsGPT (this computer, the network with an
access token, or a domain with HTTPS) and which model provider to use, writes the settings and
secrets to ~/.docsgpt/server/.env, and starts the images of the installed version. docsgpt status,
logs, token, upgrade, down and uninstall manage it afterwards. See
Run it with docsgpt up.
An installed package keeps its data in ~/.docsgpt/server
Outside a source checkout, the data home (.env, uploads, indexes, models) was the directory
the command ran from, so starting docsgpt api from another folder silently used other
settings. It is now ~/.docsgpt/server, or /opt/docsgpt for root on Linux; DOCSGPT_HOME
still overrides it. See Upgrading.
The standalone Docker stack runs on one port
The arc53/docsgpt image now serves the web UI next to the API, the way docsgpt api does from
the Python package. docker-compose-standalone.yaml no longer runs a frontend container: the UI
and the API share port 7091, published on 127.0.0.1 by default. The UI takes its API address
from the page it was loaded from, so opening the stack from another machine works without
setting VITE_API_HOST. New Compose settings: DOCSGPT_BIND and DOCSGPT_PORT for where the
port is published, POSTGRES_PASSWORD, and an https profile that puts Caddy with an automatic
certificate in front of a public domain. The arc53/docsgpt-fe image is still published for the
checkout Compose files and Kubernetes. See
Upgrading from an earlier standalone file.
0.20.0
DocsGPT installs from PyPI
The backend is published as docsgpt: the API server, the
web UI, the Celery worker and the maintenance scripts in one package, behind a single docsgpt
command. pip install docsgpt then docsgpt api serves the API and the UI on one port, and
docsgpt worker runs the worker. The optional engines are extras, docsgpt[docling] and
docsgpt[milvus]. See Install with pip.
The Python package is now docsgpt
The import package was renamed from application to docsgpt, the name it has on PyPI. Entry
points move with it: celery -A docsgpt.app.celery worker and
uvicorn docsgpt.asgi:asgi_app. The old spellings still run for this release and print a
FutureWarning, and Celery tasks queued under the old names are still consumed. The
upgrade guide has the details.
Smaller default install and images
The document and vector-store engines that pulled the heaviest dependencies are now extras
rather than defaults, so a stock install no longer carries PyTorch or the CUDA stack. The
published image follows the same split: the default arc53/docsgpt image is the slim one, and
arc53/docsgpt:<version>-docling bakes in the docling parser engine, its models and tesseract
for OCR.
Faster embeddings, pinned to your installation
Embeddings run through FastEmbed on ONNX Runtime. Query
embedding now happens on the Celery worker rather than in the API process, which keeps the API
small; a worker consuming the embeddings queue is required for search. The embedding model is
pinned to the installation instead of following the release, so an upgrade never silently
changes the model behind an existing index, and a query against an index built with a different
model is now warned about. New installs default to
ibm-granite/granite-embedding-311m-multilingual-r2, which is multilingual with a 32k-token
context. The reembed script rebuilds vectors in place from the chunk text already stored.
If you start your worker with an explicit -Q, add the embeddings queue. See
Upgrading for the one-line change and what happens without it.
Broader document support
Parsing gained support for more document, spreadsheet, presentation, EPUB, XHTML and image formats, along with a reworked OCR path. Parsing behaviour is configurable: markdown conversion, structured output, table reconstruction and improved PDF handling.
Agents and workflows
Agents no longer require a source. The synthetic “Default” source is gone, and an agent with no source or retriever is a valid agent that lists and answers normally. Workflow agents can be exported and imported as files, so a workflow can move between deployments or into version control.
Artifact and tool-call handling was hardened throughout: durable tasks retry rather than lose work on resume, tool calls are validated more strictly, and sandbox sessions are steadier.
Chat and attachments
Cross-turn chaining against the Responses API is now bounded, conversation compression persists across turns instead of being recomputed, and requests carry prompt-cache hints. Attachments carry provenance through parsing, unparseable chat attachments are refused at upload rather than failing mid-answer, and the composer guards against sending while an attachment is still processing.
Widget
The React widget got a UI refresh and an expand and collapse toggle, and was brought back in
line with the current API contract. The npm packages docsgpt and docsgpt-react are published
at 0.7.1.
Also in this release
- The code-execution sandbox runner is published as
arc53/docsgpt-sandbox, so the Kubernetes manifest no longer needs an image you build yourself. - Releases publish the Docker images and the PyPI package from the release workflow.
- The architecture guide was rewritten.
- Markdown code spans are no longer corrupted by citation rendering.
setup.ps1runs on Windows PowerShell 5.1 again.
0.19.0
Artifacts and sandboxed code execution
Agents can generate files and run code in a sandbox, from chat and from workflows, and read and write documents along the way. The runner is opt-in. See Artifacts and Code Execution.
Guardrails
A first version of guardrails: per-agent checks on the question, the retrieved documents, tool results and the answer, with an audit journal.
Also in this release
- Agent API keys can be rotated.
- Workflows gained undo and redo, and chat shows reasoning and tool calls inline while an answer streams.
- Sources can be previewed chunk by chunk.
- Token usage is counted per call, and oversized contexts are guarded against before they reach the model.
- The frontend targets Node 22.
0.18.0
This section also covers the 0.17.1 to 0.17.3 releases.
Single sign-on, roles and teams
OIDC single sign-on, an admin role with an admin dashboard, and teams for sharing agents and sources.
Retrieval
- Per-source configuration of retrieval strategy, chunking and exposure.
- Semantic chunking, and a hybrid BM25 plus vector retriever on pgvector.
- GraphRAG: a knowledge graph per source, used at retrieval time.
- Wiki sources that an agent can edit.
Also in this release
- Agents can be exported and imported.
- OpenAI models can run through the Responses API (a per-model setting), and model reasoning is passed through to the answer stream.
- Prompt presets, conversation visibility, and the logs and analytics pages were reworked.
0.17.0
User data moves to PostgreSQL
Conversations, agents, prompts, sources, attachments, workflows, logs and token usage are stored in PostgreSQL instead of MongoDB. MongoDB is no longer required, except as an optional vector store. A 0.16.x deployment has to migrate its data before it upgrades; do not pull the new images first. See PostgreSQL for User Data.
Also in this release
- The worker checks for new versions and prints security advisories;
VERSION_CHECK=0turns it off. See Observability. - The repository gained a threat model, an incident response plan and a CI security scan of its GitHub Actions workflows.