Releases: ProfessionalWiki/MediaWiki-MCP-Server
Releases · ProfessionalWiki/MediaWiki-MCP-Server
Release list
v0.16.0
Security
- A refresh token issued by the hosted OAuth sign-in can no longer be redeemed by a different client. A request presenting a
client_idother than the one the token was issued to is refused withinvalid_grantand has to sign in again. Requests that send noclient_id, and tokens issued before this release, keep working. - The HTTP transport did not validate the
Originheader on any bind other than loopback, leaving it open to DNS rebinding: an attacker who re-points a domain at a server the victim's browser can reach could call tools and read the results, without having to reach that server themselves. The Docker image binds to0.0.0.0by default, so this affected container deployments unlessMCP_ALLOWED_ORIGINSorMCP_ALLOWED_HOSTSwas set.
Breaking changes
- The HTTP transport now rate limits
tools/call: each caller signed in through hosted OAuth gets its own allowance (default 30 per second, burst 60), all callers forwarding their own wiki token share one allowance of that size between them, and anonymous callers share a third (default 100 per second). A request over the limit is refused with429and aRetry-Afterheader. RaiseMCP_RATE_LIMIT/MCP_RATE_LIMIT_BURST/MCP_RATE_LIMIT_ANONYMOUSif you run high-throughput automation, or setMCP_RATE_LIMIT=0to disable. - The HTTP transport no longer forwards a caller's
Authorization: Bearerheader to MediaWiki; such a request is refused with401. Use hosted OAuth sign-in, or setMCP_ALLOW_BEARER_PASSTHROUGH=trueto keep the old behaviour while you migrate. That option is deprecated and will be removed. - The server no longer advertises the wikis' own authorization servers, so a client can no longer discover where to mint a token to send here.
list-wikisnow reports a wiki'sauthorizationServeronly whileMCP_ALLOW_BEARER_PASSTHROUGH=true, and/.well-known/oauth-protected-resourceanswers404unless hosted OAuth sign-in is enabled. The document a hosted sign-in publishes there is unchanged. - The
Originheader is now validated on every bind, and a request carrying an unlisted origin is refused with403. If you serve a browser-based client from a public bind, setMCP_ALLOWED_ORIGINSbefore upgrading. Clients that send noOriginheader, which is most of them, are unaffected.
Added
- Metrics:
/metricsnow reportsmcp_rate_limited_total, a counter oftools/callrequests refused with429, labelled by whether the caller was authenticated.
Removed
- The server no longer sends log messages to connected MCP clients and no longer advertises the
loggingcapability, following the feature's deprecation in the 2026-07-28 MCP revision. All logging goes to stderr, unchanged;MCP_LOG_LEVELstill controls it.
Changed
- Cacheable results (tool and resource lists, wiki resource reads, discovery) now carry a 60-second freshness hint instead of
ttlMs: 0, so clients on the 2026-07-28 revision can cache them between polls. Change notifications are unaffected. - The hosted OAuth sign-in's approval page is shorter and now names the address you will be returned to, including for a local application, where it previously said only "an application on this device". It no longer promises a permissions step the wiki does not always show.
- The HTTP transport's own
401,503and413replies carry new JSON-RPC error codes:-31001,-31002and-31003. Clients read the HTTP status for these conditions, so no change is expected; anything matching on the old codes-32001and-32000needs updating.
Fixed
- A tool result that renders a long or multi-line value, such as a page's wikitext, now closes it with a blank line before the next field. Previously the next field's label was the only cue the value had ended, so content containing a line like
Summary: …read as a field of the result. - An error during hosted OAuth sign-in is now reported back to the application that started it, instead of only shown on a page the application never sees, so a client no longer waits indefinitely for a callback that never arrives. This covers a missing or non-S256 PKCE challenge and a
resourcenaming another server. - A sign-in request asking for a response type this server does not support is now refused, instead of being answered with an authorization code it did not ask for.
- Cancelling a tool call, or disconnecting while one is still running, now stops the request the server had in flight to the wiki, instead of letting it run to completion. Cancelling a write is not an undo: an edit already committed by the wiki stays committed. Cancelled calls are logged as
cancelledrather than counted as wiki failures. - Reading an
mcp://wikis/{wikiKey}resource for a wiki that is not configured now fails with a JSON-RPC-32602error naming the URI, as the protocol requires. It previously returned an empty document, which a client could not tell from a wiki with nothing to report. - Wiki keys are now percent-encoded in the
mcp://wikis/URIs the server publishes, and decoded when one is read or passed as awikiargument, so a key containing a character that needs escaping, such as%, a comma or a non-ASCII letter, is now reachable. A key that is already a plain hostname, with or without a port, keeps the URI it had. - A wiki key beginning with
mcp://wikis/is refused at startup instead of being accepted and then resolving to the wrong wiki. - The HTTP transport now answers errors with JSON, in the JSON-RPC or OAuth dialect the path calls for, instead of an HTML page that could carry a stack trace when
NODE_ENVis notproduction. This covers a body that is not valid JSON, an unsupported charset or content encoding, and any error raised while serving a request. - The HTTP transport's
401and503replies now echo the id of the request they answer. Replies to a request whose id could not be read omit the field rather than sendingnull, which this protocol revision does not admit.
v0.15.0
Security
- Reading an
mcp://wikis/{wikiKey}resource no longer discloses the wiki's OAuth 2.0 client secret, previously served in plaintext to any client allowed to read resources. If you run the HTTP transport with a confidential OAuth consumer, rotate that secret. The resource now publishes onlysitename,server,articlepath,scriptpath,privateandreadOnly.
Breaking changes
- The HTTP transport no longer creates sessions: no session id is issued and
GET /mcpanswers405. Clients on protocol revisions before 2026-07-28 no longer receive notifications between requests, so a tool-list change afteradd-wikiorremove-wikireaches them on their next connection. Tool calls are unaffected, and stdio is unchanged. MCP_SESSION_IDLE_TIMEOUTis obsolete; remove it from the environment. The server warns while it is still set.- The
mcp_active_sessionsmetric is replaced bymcp_inflight_requestsandmcp_subscription_streams. - Reading NeoWiki subjects now requires NeoWiki from 2026-07-27 or later, which renamed a Statement's property type to
propertyType(ProfessionalWiki/NeoWiki#1169). Against an earlier NeoWiki the type now reads as empty, so update the wiki before upgrading the server.
Added
- The server now speaks MCP protocol revision 2026-07-28 on both transports. Clients on earlier revisions are served as before.
- Plugin installs can now be pointed at your own wiki: Claude Code prompts for a configuration file, and the Codex plugin forwards
CONFIGfrom the shell it is launched from. Previously both were stuck on English Wikipedia. - The server now warns at startup when
CONFIGpoints at a file that does not exist, instead of silently falling back to English Wikipedia.
Changed
- The server now runs on version 2 of the MCP TypeScript SDK. No configuration changes are needed. Tool input schemas are now published as JSON Schema 2020-12 instead of draft-07, which matters only to a client that validates against a draft-07-only validator.
- Over HTTP, event streams now carry a keep-alive every 15 seconds, so a reverse proxy that drops idle connections no longer cuts a waiting client's notification stream.
- Calling a tool the server is not offering now fails the call outright, instead of returning the error as the tool's result. Clients that call only what the server advertises are unaffected.
MCP_ALLOWED_ORIGINSis now matched on hostname rather than whole origin, sohttps://wiki.example.orgalso admits other schemes and ports on that host; enforce those at your reverse proxy if you need to. In exchange, a trailing slash, a path, an explicit:443or a bare hostname all work now, where each previously rejected every browser request.tool_calltelemetry lines no longer carrysession_id, and shutdown events no longer reportsessions_at_signal/sessions_closed. The hashedcallerfield remains.
Fixed
- The HTTP server no longer exits when a
GET /readyprobe finds the default wiki slow or unreachable; it answers the documented503 not_readyinstead. - Readiness probes arriving while an earlier one is still running now share its result, so a slow wiki is asked once rather than once per waiting probe.
- A wiki added with
add-wikito a deployment where every wiki is read-only is now read-only itself. It was previously writable, which revealed all the write tools.
v0.14.0
Breaking changes
- Hosted OAuth proxy: the upstream OAuth consumer must now be confidential. Set
oauth2ClientSecret(or theMCP_OAUTH2_CLIENT_SECRETenvironment variable) for the default wiki; the proxy refuses to start without it. A confidential consumer is what lets the proxy refresh the upstream token, so users stay signed in past the wiki's OAuth2 access-token lifetime (one hour by default). A deployment using a public or PKCE consumer must register a confidential one and supply its secret.
Added
- Edit attribution can now be turned off per wiki. Set
"attributeEdits": falsein a wiki'sconfig.jsonentry to drop the(via <tool> on MediaWiki MCP Server)suffix from page and file edit summaries. It stays on by default. - Claude Code and Codex can now install the server as a plugin. Add the repository as a plugin marketplace once, then install from it, instead of writing configuration by hand. See the README install section.
- Hosted OAuth proxy: verified first-party MCP clients now work out of the box. Their OAuth callbacks are trusted by default, with no
MCP_OAUTH_ALLOWED_REDIRECTSconfiguration. - Hosted OAuth proxy: the
MCP_OAUTH_ALLOWED_REDIRECTSenvironment variable lets a deployment admit further MCP clients beyond the trusted defaults. List exact redirect URIs, or use anhttps://…/*prefix pattern. Loopback, claude.ai, and the verified first-party clients always remain allowed. - Hosted OAuth proxy: support for Client ID Metadata Documents (CIMD). A CIMD-capable client connects using a stable, vendor-hosted identity, so there is no per-client redirect entry to curate. The proxy trusts the verified first-party document hosts by default; add more with
MCP_OAUTH_CIMD_ALLOWED_HOSTS. - Hosted OAuth proxy: the consent page now shows where the user will be sent after approving, either the client's callback host or "an application on this device" for a local client.
- Hosted OAuth proxy: IPv6 loopback (
http://[::1]:…) redirect URIs are now accepted at client registration, per RFC 8252. - Metrics: the
/metricsendpoint now reports the hosted OAuth proxy store's size and flush cost, so operators can watch the store grow, see how long each persistence write takes, and alert when one fails. The new series are themcp_proxy_store_upstream_tokensandmcp_proxy_store_clientsgauges, anmcp_proxy_store_flush_duration_secondshistogram, and anmcp_proxy_store_flush_failures_totalcounter.
Changed
- The documented install configurations and one-click install badges now pass
-yto npx, matching the bundled plugin manifests. This avoids an install-confirmation step for anyone whose npm is configured to require one. - Hosted OAuth proxy: sign-in state now survives server restarts and deploys. Registered clients and upstream tokens are persisted to a local, encrypted file, so users are no longer signed out on every upgrade. In Docker, mount a volume at the store path (
/app/data); see the deployment guide.
Removed
- The Gemini CLI extension has been retired, because Gemini CLI stopped serving consumer Google AI tiers in June 2026. Use Antigravity instead, which offers to import an existing Gemini CLI configuration. If your licence keeps Gemini CLI (for example a Code Assist Standard or Enterprise licence), add the standard configuration to its
~/.gemini/settings.json.
Fixed
- Clients no longer show a spurious
Expected ',' or ']' after array element in JSONwarning next to otherwise successful requests. - The HTTP server now logs a clear message and exits cleanly when it cannot bind its port, for example because the port is already in use or permission is denied, instead of terminating with an uncaught exception and a raw stack trace.
- Hosted OAuth proxy: a client that identifies by a vendor-hosted URL (Client ID Metadata Document) is now rejected if any redirect URI in its document is not an
https, loopback-http, or custom-scheme (for examplevscode://) URL. A cleartexthttpredirect to a non-loopback host would let a network attacker on that path intercept the authorization code. - Hosted OAuth proxy: clients that use a loopback callback on a variable port, including those that register a portless
http://127.0.0.1/URI, now complete the flow instead of failing with "redirect_uri not registered", per RFC 8252. - Hosted OAuth proxy: an upstream token refresh the wiki rejects with
invalid_client(client authentication failed) is now reported as an authentication failure, so the client prompts for sign-in again instead of looping on a retryable "temporarily unavailable". - Hosted OAuth proxy: a momentary wiki outage while refreshing a near-expiry token on an active connection no longer forces the client to sign in again. The request continues with the still-valid token, or gets a retryable response, instead of a sign-in challenge triggered by a transient failure. Concurrent requests that both trigger a refresh now share one upstream refresh rather than racing.
v0.13.1
Fixed
- Trying to create, edit, or move a page in a protected namespace without the required right is now reported as a permission error rather than a generic upstream failure.
- An expired or invalid OAuth access token is now reported as an authentication error rather than a generic upstream failure, so an OAuth-aware client can tell the token needs to be refreshed.
v0.13.0
Added
- Hosted OAuth proxy (HTTP transport). Opt-in mode in which the server signs each user into MediaWiki as themselves, so an OAuth-aware client pointed at
https://<wiki>/mcpneeds no manual tokens. Anonymous read still works; writes require sign-in. Enable it by running the HTTP transport withMCP_PUBLIC_URLandMCP_OAUTH_JWT_SIGNING_KEYset and anoauth2ClientIdon the default wiki. See docs/deployment.md — hosted OAuth sign-in. - New per-wiki
publicServerfield: the browser-facing base URL, used when it differs from the internalserver(e.g. a Docker-network alias). Defaults toserver. - New hosted-proxy environment variables:
MCP_PUBLIC_URL(the server's public URL),MCP_OAUTH_JWT_SIGNING_KEY(≥32 characters),MCP_OAUTH2_CLIENT_ID(the default wiki's OAuth2 client id — overridesconfig.json, so a deployment can supply the value its wiki generates at registration time),MCP_OAUTH_TOKEN_TTL(default55m), andMCP_OAUTH_CONSENT_TTL(default30d). Durations accept forms like55m/1h/30dor bare seconds. privatewikis require sign-in over HTTP. A wiki configuredprivate: true(its MediaWiki disallows anonymous reads) now challenges every anonymous HTTP request — including the initial connection — with a401, so an OAuth-capable client prompts for login at connect instead of failing later. Public wikis are unchanged: anonymous reads still work, and only writes prompt for sign-in.
Changed
- The OAuth sign-in and consent pages now have a styled layout instead of bare HTML, and a failed or cancelled authorization shows a readable page rather than a raw error.
Fixed
- Extension-pack write tools (NeoWiki's
create-subject,update-subject,delete-subject, andset-main-subject) are now hidden fromtools/listand rejected by the per-call guard when the active wiki is configuredreadOnly, the same as core write tools. Previously the read-only gate covered only the core writes, so a read-only endpoint still advertised and dispatched extension-pack writes; an actual write was then stopped only by the wiki's own permissions. Write tools are identified by theirreadOnlyHint: falseannotation, so future packs are covered automatically. (#411)
v0.12.0
Added
MCP_TRUSTED_HOSTSenvironment variable: a comma-separated allowlist of hosts exempt from the outbound SSRF guard's public-IP check, letting you deliberately point the server at an internal destination — such as a Docker-network alias likemediawiki.svcbehind a reverse proxy. Without it, the anonymous siteinfo probe to a private address is refused, so extension-gated tools (Cargo, Semantic MediaWiki, Bucket, NeoWiki) never register andget-site-inforeports no extensions. A bare host matches any port andhost:portmatches only that port; matching is exact, and a listed host is still DNS-resolved and pinned. Separate from the inboundMCP_ALLOWED_HOSTSHost-header allowlist. (#410)
v0.11.0
Added
- NeoWiki integration: tools to explore a NeoWiki knowledge graph — list schemas, inspect a schema's properties, search subjects by name, fetch a subject or a page's subjects, and run read-only Cypher queries. Available on wikis with the NeoWiki extension installed.
- NeoWiki write tools: create a subject on a page (as a child or the main subject), replace a subject's label and statements, delete a subject, set or clear a page's main subject, and dry-run validate a proposed subject before writing. The four write tools require the
editright on the target wiki; validation is read-only. Available on wikis with the NeoWiki extension installed. get-file-datatool: returns a wiki file's image inline (base64) so clients that can't reach the wiki host can still send the image to the model for visual analysis. Returns a scaled rendition sized bywidth. Images and files MediaWiki can rasterize (SVG, PDF, DjVu) come back as an image; non-renderable types (audio, video, binaries) error and point toget-file.MCP_FILE_DATA_MAX_BYTESenvironment variable: a hard ceiling on the encoded size of aget-file-dataresponse (default 1 MB).whoamitool: reports which account the current session is acting as on a wiki — the username, whether the session is anonymous, and the user groups it belongs to (optionally the full rights list). Use it to confirm who edits will be attributed to before writing, for example when creating a page under your own user namespace.MCP_UPLOAD_MAX_BYTESenvironment variable: caps the size the server buffers when fetching a URL forupload-file-from-url/update-file-from-url(default 100 MB). Larger files are handed to the wiki's own copy-upload.update-pageandcreate-pageaccept abotparameter that marks the edit as a bot edit. The flag takes effect only when the authenticated account has thebotright (bot group, or the high-volume grant on a bot password or OAuth consumer); the response reports whether the flag applied viabotMarked.
Changed
- List responses (
get-recent-changes,get-page-history,get-links-here,get-category-members,get-pages) now omit default and empty fields to reduce response size: boolean flags appear only whentrue, empty comments and tag lists are dropped, recent changes report the size delta without the raw old/new lengths, a category member'stypeis omitted for ordinary pages, andget-pagesomitsrequestedTitlewhen it matches the resolved title. Absent flags meanfalse. - The
list-wikistool is now hidden when only a single wiki is configured, where it has nothing to list and every call already defaults to that wiki. It appears once a second wiki is configured or added. - The timeout for an
exec-backed credential command was raised from 10 to 30 seconds, giving an interactive unlock (such as a 1Password prompt) time to be approved. If the command still times out, the error now explains that approving the prompt and retrying re-runs it. exec-backed credential commands now run one at a time instead of concurrently. Resolving secrets for several wikis at once (for example when listing wikis) previously launched every command together, so an interactive unlock such as a 1Password prompt appeared once per wiki; now the first command's unlock is reused by the rest, so a single prompt covers them all.list-wikisno longer logs into or unlocks credentials for each configured wiki. It now reads each wiki's public site data anonymously, so listing wikis never triggers a credential prompt or a login — authentication happens only when you act on a wiki.upload-file-from-urlandupdate-file-from-urlnow work on wikis without upload-by-URL enabled. The server fetches the file and uploads it directly, only asking the wiki to fetch the URL when the server cannot reach it (for example a private, server-unreachable address). Previously these tools failed unless the wiki had copy-uploads enabled and the account held theupload_by_urlright.
v0.10.0
Security
- Updated dependencies to resolve known advisories, including a high-severity issue in the HTTP client used for outbound wiki requests.
Breaking changes
- Removed the
set-wikitool. Pass thewikiargument on each tool call instead. remove-wikinow refuses to remove the configured default wiki (it previously refused to remove the wiki that was currently selected).
Added
get-site-infotool: returns a wiki's MediaWiki version, content language, title case-sensitivity, maximum page size, namespace map, installed extensions, and content license; optionally page/article/user/edit statistics.move-pagetool that renames a wiki page (and, by default, its talk page), optionally moving subpages and suppressing the redirect left at the old title.get-links-heretool that lists the pages referencing a target page — pages that link to it, embed it as a template, or display it as a file — including pages that reach it through a redirect.list-wikistool reporting every configured wiki — its key, sitename, server, whether it is read-only or the default, whether it is reachable, which extension-gated tools work on it, and, for an OAuth-configured wiki, its authorization server.- Optional
wikiargument on every tool that operates on a wiki (all except the wiki-management and OAuth tools), naming the wiki that call acts on. Accepts a wiki key (e.g.en.wikipedia.org) or the fullmcp://wikis/{wikiKey}URI. - Tool responses now report the wiki the call ran against.
MCP_SESSION_IDLE_TIMEOUTenv var (default1800seconds) closes HTTP sessions that have been idle for the configured window. Any request resets the timer; setting it to0disables expiry.
Changed
- URLs returned by the server — page links, and the
serverreported bylist-wikisand themcp://wikisresource — now use the wiki's own public address rather than the address configured for API access. This corrects links when the wiki is reached over an internal or Docker hostname. Links fall back to the configured address when the wiki is unreachable. - Tool calls target a wiki named per call, defaulting to the configured default wiki, instead of a server-side selection that had to be set first.
- Extension-gated tools (
cargo-*,smw-*,bucket-query) and the write tools are now offered whenever any configured wiki supports them, instead of only when the default wiki does. A call targeting a wiki that lacks the capability returns a clear error. - Wiki credentials backed by an
execcommand are now fetched the first time that wiki is used, instead of when the server starts. A slow or failing credential command no longer delays startup or prevents the server from starting — the error now appears only when that wiki is used. - The HTTP transport's OAuth discovery now covers every configured wiki: the
/.well-known/oauth-protected-resourcedocument advertises every OAuth wiki's authorization server, and a tokenless client is challenged only when no configured wiki is usable without a token — a deployment that mixes OAuth and non-OAuth wikis still serves tokenless clients. - An HTTP client may now send a different
Authorization: Bearertoken per request, so one session can work with wikis on different authorization servers. A call targeting an OAuth wiki with no usable token returns a clear authentication error.
v0.9.1
Changed
- Documented the
/mcpendpoint path explicitly indocs/deployment.md.
Fixed
- Startup failures (e.g. config-loading errors) now exit with code 1 instead of leaking a Node unhandled-rejection warning on stderr.
- Bot-password sessions are now renewed automatically when the MediaWiki session expires (default
$wgObjectCacheSessionExpiry= 1 hour). Previously, write tools (e.g.update-page,create-page) failed withpermissiondeniedafter the expiry and only a server restart recovered.
v0.9.0
Breaking changes
- Bumped
engines.nodeto>=22.12.0(was>=18). Node 20 reached EOL in April 2026; Node 22 LTS is supported through April 2027. Downstream consumers pinned to Node 18 or 20 must upgrade.
Added
- Browser-based OAuth 2.0 login. Set
oauth2ClientId(and, for MediaWiki,oauth2CallbackPort) on a wiki entry to opt in. HTTP transport uses standard OAuth discovery (RFC 9728) plusWWW-Authenticateheaders so OAuth-aware MCP clients can drive auth-code+PKCE flows. On stdio, the server opens a browser the first time a tool needs a token, stores the result in~/.config/mediawiki-mcp/credentials.json, and refreshes it before expiry. Static credentials inconfig.jsoncontinue to work for wikis that don't opt in.- Two new stdio-only tools:
oauth-status(lists wikis with stored tokens, scopes, and expiry — never the values) andoauth-logout(removes stored tokens, one wiki or all). - Three new env vars:
MCP_OAUTH_CREDENTIALS_FILEoverrides the token-store path;MCP_OAUTH_NO_BROWSER=1skips the browser launch and logs the auth URL to stderr (useful in headless environments);MCP_PUBLIC_URLoverrides the request-derived public URL for awkward proxy setups. - Two new per-wiki config fields:
oauth2ClientId(public-client identifier fromSpecial:OAuthConsumerRegistration/propose/oauth2) andoauth2CallbackPort(loopback port for the OAuth callback URL — required for MediaWiki's Extension:OAuth, which exact-matches the redirect URI).
- Two new stdio-only tools:
MCP_LOG_LEVELenv var (defaultdebug) sets the minimum severity for logger output, filtering both stderr telemetry and thesendLoggingMessagebroadcast. Accepts the eight RFC 5424 levels plussilent.smw-queryandsmw-list-propertiestools for Semantic MediaWiki — runs#askqueries and discovers SMW properties with copy-paste templates. Auto-detected fromsiteinfo; only registered on wikis that have SMW installed.bucket-querytool for the Bucket extension — runs Lua-style queries and returns row-shaped results. Same gating.cargo-query,cargo-list-tables, andcargo-describe-tabletools for the Cargo extension. Each calls one Cargo API action (cargoquery/cargotables/cargofields); same gating, and also recognised under the rebranded nameLIBRARIANused by wiki.gg-hosted wikis.- Optional
GET /metricsPrometheus endpoint on the HTTP transport, enabled withMCP_METRICS=true. Exposes tool-call counters, duration histograms, upstream status totals, active sessions, and readiness-probe failures. - Graceful shutdown —
SIGTERMandSIGINTdrain in-flight/mcpcalls and close active StreamableHTTP sessions before exit, emittingevent: "shutdown"/event: "shutdown_complete"on stderr. Configurable viaMCP_SHUTDOWN_GRACE_MS(default10000). Stdio transport closes its single transport on the same signals. MCP_MAX_REQUEST_BODYenv var (default1mb) caps HTTP request body size, replacing body-parser's silent 100 kB default that was rejecting long-form wikitext edits. Oversize requests return a JSON-RPC 413; the resolved value appears in the startup banner.- Published Docker image at
ghcr.io/professionalwiki/mediawiki-mcp-server. Multi-arch (linux/amd64,linux/arm64); release builds carry SLSA provenance, SPDX SBOM, and a cosign keyless signature; edge builds (mastertip) carry attestations only. Tag conventions and verification command indocs/deployment.md.
Changed
- Reorganised user-facing docs: extracted
docs/operations.mdfor day-2 concerns (logs,/health//ready, metrics, graceful shutdown); moved per-request bearer and reverse-proxy documentation fromdocs/configuration.mdintodocs/deployment.md; slimmed the README's authentication section; consolidated manual-token and bot-password instructions indocs/configuration.md; converted blockquote callouts to GitHub admonitions. - Hardened the Docker image. Build context is now an allow-list (
src/,package.json,package-lock.json,tsconfig.json,server.json) rather than the entire repo. Image labels follow OCI image-spec: dropped the deprecatedmaintainerand hand-maintainedimage.version; addedimage.title,image.url,image.source,image.licenses, and a per-buildimage.revisionpopulated from aGIT_SHAbuild arg. Both build stages now install dependencies withnpm ci --ignore-scriptsso third-party postinstall scripts can't run during the SLSA-attested build. Thenode:lts-alpinebase is pinned by digest, with Dependabot tracking digest updates so base-image patches reach published builds via auditable git history. - Switched the dev toolchain to compiled tooling for substantially faster iteration:
tsgo(Go-based TypeScript 7 native compiler) drives build/watch/type-check; oxlint and oxfmt (Rust-based) replace ESLint and Prettier. The new lint pipeline also runs type-aware checks, catching unawaited Promises, unbound methods used as callbacks, and accidental stringification of non-plain objects. Published packages are unaffected.
Fixed
- The dispatcher OAuth gate no longer fires for
add-wiki,set-wiki,remove-wiki,oauth-status, oroauth-logout. These tools operate on server-local state (the wiki registry, the OAuth token store) and don't need a token for the active wiki. Without this fix, a wiki whose OAuth had gone stale would render those five tools unreachable — leaving no way to switch away from it or clear its tokens. - Read-only wikis now hide the
update-fileandupdate-file-from-urltools. They were previously left enabled because the read-only gate's tool list was missing the twoupdate-file*entries. - Markdown payload formatter no longer renders class instances and other non-plain objects as the bare
[object Object].