We added some helper commands to the Makefile to
facilitate the development of the docs-mcp.
These commands allow developers to easily
connect to the docs-mcp server with your
favorite LLM.
You can start the MCP Inspector with
`make mcp-inspector` to connect to the docs-mcp server and
inspect the different endpoints and their responses.
Add a `yarn mcp-inspector` script that launches
`@modelcontextprotocol/inspector` against the local
docs-mcp server, with a checked-in config pre-filling
the URL and the `docs-mcp-client`
OAuth client and scopes so there is nothing to type
in by hand.
Add `src/frontend/servers/mcp`, a stateless TypeScript (Express +
`@modelcontextprotocol/sdk`) MCP server exposing `search_documents`,
`read_document` and `create_document` over Streamable HTTP.
It is an OAuth resource server holding no credentials of its own: it
verifies the caller's Keycloak token against the realm JWKS
(`src/auth/jwtVerifier.ts`), checks the `docs-mcp` audience, then
forwards the same token unchanged to Django's
`/api/v1.0/mcp/documents/*` endpoints (`src/docsApiClient.ts`),
which stays the sole authority on document permissions.
No token exchange.
Ship the `mcp-development` compose service, its `env.d/development/mcp`
env file, a `build-mcp` Makefile helper, and
`documentation/mcp_server.md` describing the full flow and
how to connect MCP clients.
Add to the dev realm:
- `docs-mcp-client`, the public PKCE client MCP clients authenticate
with, with optional scopes `docs:documents:{search,read,create}` and
`docs-mcp`.
- `docs-api`, the confidential client Django uses as introspection
credentials (`OIDC_RS_CLIENT_ID/SECRET`).
- the `docs:documents:*` consent scopes and a `docs-mcp` audience-mapper
scope that stamps the `docs-mcp` audience only when requested.
Point the resource-server env at the `impress` realm and the new
clients, allow the `docs-mcp-client` audience, and grant users
`offline_access` for refresh tokens.
We added a basic MCP API to the backend.
This API is designed to facilitate integration with external
systems, providing a secure and efficient way to
access document data.
API endpoints include:
- POST /api/v1.0/mcp/documents/search -> search_documents
- GET /api/v1.0/mcp/documents/<id> -> read_document
- POST /api/v1.0/mcp/documents -> create_document
We decided to move the DockerflowMiddleware higher in the middleware
list to prevent future access to the database or redis in other
middleware that can have an impact on the liveness probe.
The nb_accesses cache TTL was very short, 30 seconds. That mean that the
user will hit the cache for a very short period and the cache is
probably not be hit. This is what we can see in the slow queries from
the pg_stat_statements table. The query to compute the nb_accesses is
executed a little bit less than the number of queries to list or
retrieve documents, meaning the cache is not used.
The filtering made in the DocumentViewset.get_queryset method is not
optimal and lead to a full scan of the Document table. The heavy part is
on the filtering on what the user can access between the accesses and
the link traces. To have better performance we make an union operation
of both document_id list and the filter the id on this list. Postgresql
will use the index on the id column.
Comparing path with LEFT(value, LENGTH(path)) makes a sequential scan on
all the Document table, the more this table grow, the more the query
using it will be slow. We dediced instead to lookup on the path
extracting all ancestors path for a given document and then make a path
IN statement to use the index existing on the path column.
The ws library emits an unhandled 'error' event when a client sends a
frame with unexpected RSV bits (e.g. permessage-deflate mismatch),
which was crashing the whole y-provider process since no listener was
attached to the socket. Add an error listener to log and drop the
offending connection instead.
We want to configure other options on the redis cache. By default there
is no timeout on the connection to socket and no timeout for read/write
operations. We set default values in all caches used in production. The
settings IGNORE_EXCEPTIONS differ between the default and the session
cache. Activating it behaves like a missed cache. Enabling it for the
session should lead to unwanted side effects, by returning falsy on the
session creation, a retry mechanism of 10000 attempts is made in the
SessionStore.create method, the request can stay in this loop for a long
time.
The readiness probe should also not create a new session. A new session
will live in redis and increase the number of keys inside it for
nothing. The readiness path is isgnored in the ForceSessionMiddleware
We added a new webp image to the e2e tests and updated the export
tests to include this new image format.
This ensures that the export functionality correctly
handles webp images, maintaining compatibility and
performance across different image formats.
We increase throttles, to be sure that the e2e tests
don't hit them.
In order to ensure that complex PNG images are
exported correctly, we have added an end-to-end
test that verifies the export functionality.
This test will help catch any regressions related
to image exports in future updates.
Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
WebP format isn't supported by react-pdf/renderer and so wasn't exported
properly, and some PNG images were also not exporting.
First drawing those raster images to a canvas and providing a dataURL to
react-pdf/renderer fixes those two bugs at once.
Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
Since we migrated to uv, the venv folder does not live anymore at the
project root but inside the src/backend directory. Add a rule in the
.dockerignore to ignore it.
The ForceSessionMiddleware force the session creation, we want to
ignore it when the request is the liveness probe. The liveness probe
must not check if redis is available, this is the readiness probe job
The emoji action could reuse a stale document title while a rename was being
submitted, replacing the new title with the emoji alone.
Keep the latest submitted title in the header and cover the interaction
with a regression test.
Signed-off-by: fch-aa <21101725+fch-aa@users.noreply.github.com>
Added
- ✨(frontend) export presenter slides as PDF #2487
Fixed
- 🐛(frontend) hide Leave in the doc menu when not logged in #2626
- 🐛(backend) allow to configure settings DATA_UPLOAD_MAX_MEMORY_SIZE
We removed previously whitenoise because it was not working with asgi
application. By removing it we also removed the way to serve the static
files in the application. There is an existing fork of whitenoise,
servestatic, that manage async application and we can use it to serve
static files.
Render the slides off-screen as A4 landscape pages and print them via
the browser, one slide per page with the watermark. Add a "Download PDF"
action to the floating bar.
Closes#2446
Release 3.17.2 of DRF now takes care of DATA_UPLOAD_MAX_MEMORY_SIZE
and is checked when the body request is parsed. Before that, DRF wasn't
using it at all and we were only looking for custom settings linked to
the media and conversion file upload. We must now also configure this
setting.
Leave was shown in the document menu for anonymous visitors.
Hide it unless the current user can actually leave the doc.
Signed-off-by: Mora <razvi.morariu.mihai@gmail.com>
Added:
- ✨(frontend) Add "Copy link to block" feature
- ✨(frontend) add word count to doc header toolbox
- ✨(frontend) add find and replace feature to the editor
Changed:
- ♿️(frontend) use anchor links for interlinking sub-documents
- ✨(frontend) reset side panel state between documents
- ♿️(frontend) announce search loading state for screen readers
- ♻️(frontend) change favorite to star
- 🚚(frontend) add doc move to doc options
- ♻️(frontend) unified menu
- ♿(frontend) hide decorative emojis in document titles from SR
- ♻️(frontend) save the doc with a keepalive request when
leaving the page
Fixed:
- 🐛(frontend) fix clipped formatting toolbar in new comment
composer
- 🐛(backend) fix duplicating a document that has no content
- 📄(frontend) allowed partially export when MIT
- 🐛(backend) manage async support for Docs custom middleware
Removed:
- 🔥(backend) remove whitenoise package
Implementation of code block throws a errors when a `language` prop
is not supported by BlockNote, which crashes the whole editor.
In our case, the language is supported but flagged as an alias
(e.g. `js` instead of `javascript`),
but Blocknote does not resolve aliases and throws an error.
This file wraps the code block spec to normalize the `language`
prop before BlockNote renders it,
so a single legacy code block does not crash the whole editor.
Blocknote changed the way the side menu is positioned.
Because we are modifying the height of the heading blocks
we need to adjust the offset of the side menu to match
the new height of the heading blocks.
To do so we have to override the default offset of
the side menu with a custom offset that takes into
account the new height of the heading blocks.
Last version of Blocknote added support for math
and diagram blocks. This commit updates the
dependencies to include the necessary toolbar
items to create math and diagram blocks in
the editor.
We bumped Blocknote to 0.54.0, which introduced
some breaking changes. This commit adapts our
codebase to the new API and ensures compatibility
with the latest version of Blocknote.
Since we fix the error in the backend application coming from middleware
not managing async request lifecycle, the e2e tests were failing. This
is because the browser cancel the request when made in the beforeunload
event. To fix it, we set the keepalive property on the fetch method to
True to not abort the request when the page is unloaded.