Wikantik

Wikantik is a Markdown-native knowledge base for people and AI agents. It is a Java wiki engine that stores every page as Markdown with YAML frontmatter, serves a React single-page app and a REST API to humans, and exposes two Model Context Protocol (MCP) servers and an OpenAPI tool server to agents. Search is hybrid (Lucene BM25 fused with dense vectors), and the same content is also projected into a Page Graph, an LLM-extracted Knowledge Graph and a queryable RDF/OWL ontology.

Wikantik is a fork of Apache JSPWiki. The project started in early 2026 as an experiment to see whether a legacy enterprise wiki could become an agent-ready knowledge base. Most of the visible surface has since been replaced (JSP rendering became a React app, XML security policy became database-backed grants, and the knowledge layer was added), while the page-provider foundations, the plugin and filter interfaces and the Lucene core remain. The full story is in History and Evolution: From JSPWiki to Wikantik. The repository directory is still called jspwiki; the product, the Maven modules and the Java packages are all named Wikantik.

What it does

Module map

The root pom.xml lists these Maven modules in its default reactor. The React frontend lives in wikantik-frontend, which is not a Maven module: wikantik-war runs its npm build and bundles the output. A further module, wikantik-coverage-report, is added only under -Pcoverage.

ModuleWhat it is
wikantik-wikipagesDefault wiki pages shipped with a fresh install.
wikantik-utilShared helpers and crypto utilities.
wikantik-jdbcThe one data-access primitive (Jdbc, JdbcSupport); its test-jar provides the pgvector test database.
wikantik-eventThe decoupled WikiEvent bus.
wikantik-apiPublic contracts: manager interfaces, frontmatter, Page Graph, Knowledge Graph and bundle types.
wikantik-cacheEhCache-based caching layer.
wikantik-cache-memcachedOpt-in Memcached adapter for multi-node deployments; not wired into the WAR.
wikantik-httpServlet filters: CSRF, CORS, CSP, security headers, session-cookie policy.
wikantik-ingestApache Tika document extraction for derived pages, isolated from the engine.
wikantik-connectorsExternal-source connector runtime and sync orchestration.
wikantik-mainThe engine: WikiEngine, rendering, providers, auth, search, entity extraction, Obsidian import.
wikantik-mcp-coreShared MCP substrate: tool interface, endpoint bootstrap, access filter.
wikantik-admin-mcpAdmin MCP server at /wikantik-admin-mcp.
wikantik-toolsOpenAPI 3.1 tool server at /tools/*.
wikantik-scimSCIM 2.0 provisioning server at /scim/v2/*.
wikantik-knowledgeKnowledge MCP server at /knowledge-mcp, the Knowledge Graph service, the hybrid retriever and the context-bundle assembler.
wikantik-ontologyJena RDF/OWL ontology, SHACL shapes and the Postgres-to-RDF projectors.
wikantik-observabilityHealth checks, Prometheus metrics, request correlation and admission filters.
wikantik-insightsContent Intelligence: search-visibility facts, content-opportunity rules and effect measurement.
wikantik-restREST API under /api/*, admin API under /admin/*, and the public RDF servlets.
wikantik-extract-cliOffline entity-extractor, derived-page batch ingester and corpus-divergence tools.
wikantik-warWAR packaging: bundles the React build and wires every servlet and filter.
wikantik-it-testsIntegration suites (Selenide browser, REST, SSO, custom JDBC, knowledge-disabled, dense retrieval, opt-in SCIM full loop). Only built with -Pintegration-tests.
wikantik-bomBill of materials pinning shared dependency versions.

For layering rules and data flow, see Wikantik System Architecture.

Requirements

ToolVersionNotes
Java (JDK)25 or newerEnforced by the build; the JVM that runs Tomcat must also be 25+.
Maven3.9 or newer recommendedThe build enforces a floor of 3.5.
Node.js and npm20.19+ or 22.12+Needed by Vite 8; the WAR build runs npm ci and npm run build (Vite) for you.
PostgreSQL15 or newer, with the pgvector extensionThe Docker path uses the pgvector/pgvector:pg18 image.
Docker with ComposeAny recent versionRequired for the container path and for the integration tests. The unit tests that touch the database also start a pgvector container, and skip locally without Docker.
Ollama (optional)n/aSupplies embeddings (the default model is qwen3-embedding:0.6b, 1024 dimensions) and, if you enable it, entity extraction. Without an embedder search falls back to BM25 only.

Quick start

Fastest: Docker Compose

cp .env.example .env              # then set POSTGRES_PASSWORD (it must not stay CHANGEME)
bin/container.sh build            # build the wikantik image
bin/container.sh -e base up -d    # start Tomcat 11 + PostgreSQL/pgvector

On first start the container applies the database migrations, seeds the admin account and starts Tomcat. Check it with curl -fsS http://localhost:8080/api/health.

Bare metal (development)

# 1. Create the database, application role and schema (run as a PostgreSQL superuser).
#    DB_APP_USER / DB_APP_PASSWORD must match POSTGRES_USER / POSTGRES_PASSWORD in .env.
sudo -u postgres DB_NAME=wikantik DB_APP_USER=wikantik \
    DB_APP_PASSWORD='choose-a-real-password' \
    bin/db/install-fresh.sh --no-migrate-role

# 2. Build every module and the React frontend into wikantik-war/target/Wikantik.war
mvn clean install -DskipTests

# 3. First run copies .env.example to .env and stops; set POSTGRES_PASSWORD, then run again.
bin/deploy-local.sh
bin/deploy-local.sh

bin/deploy-local.sh downloads Tomcat 11 into the gitignored tomcat/ directory, renders the Tomcat context and wikantik-custom.properties from .env, deploys the WAR, applies migrations, seeds the admin account and starts Tomcat. Unless you set WIKANTIK_LOCAL_EMBEDDINGS=false in .env, it also starts a local Ollama embedder container through Docker; the first run pulls a model of roughly 600 MB, which is a download, not a hang. Afterwards, stop and start Tomcat with tomcat/tomcat-11/bin/shutdown.sh and tomcat/tomcat-11/bin/startup.sh, and use bin/redeploy.sh for the fast rebuild-and-swap loop.

Use -DskipTests rather than -Dmaven.test.skip for the build: the latter also skips the test-jar that other modules depend on.

First login

Open http://localhost:8080/ and sign in as admin with the seeded password admin123. The account is flagged so that you must choose a new password immediately (NIST 800-63B rules, so admin123 itself is rejected); until you do, API calls answer 403 PASSWORD_CHANGE_REQUIRED. The full walkthrough, with troubleshooting, is Getting Started with Wikantik.

Configuration

wikantik-main/src/main/resources/ini/wikantik.properties declares every wikantik.* key with its default, type and description (MCP and tool-server keys are in wikantik-mcp.properties and wikantik-tools.properties). Override keys in wikantik-custom.properties or with -D system properties. The generated listing is Wikantik Configuration Reference. Database schema changes exist only as numbered, idempotent migrations in bin/db/migrations/, applied by bin/db/migrate.sh.

Testing

bin/run-tests.sh --parallel 4          # canonical pre-commit gate: all unit tests, then the IT modules 4-wide
mvn clean install -T 1C -DskipITs      # unit tests only
mvn test -pl wikantik-main -Dtest=MarkdownRendererTest   # one test class

The gate needs Docker: it starts a pgvector container per integration module and one shared CPU Ollama embedder for the dense-retrieval suite. See Wikantik Testing Guide.

Deployment and releases

The Dockerfile builds a self-contained image (Tomcat 11 on a Java 25 runtime) and bin/container.sh wraps Docker Compose for the build, run, logs, psql, migrate, backup and restore steps. The prod overlay adds a backup sidecar. Pushing a version tag runs .github/workflows/release.yml, which builds the WAR and publishes ghcr.io/jakefearsd/wikantik:X.Y.Z; bin/cut-release.sh X.Y.Z prepares that tag, and bin/deploy-release.sh X.Y.Z pulls the image and ships it to a remote host (with automatic rollback if the health check fails). For container, remote and cloud details see Wikantik on Docker, Cloud Deployment, Backup and Recovery and Release and Deploy Process.

License

Wikantik is licensed under the Apache License, Version 2.0; the full text is in LICENSE. It descends from Apache JSPWiki, so the NOTICE file preserves the Apache Software Foundation copyright notice and the attributions for bundled third-party components. See SECURITY.md for how to report a vulnerability and CONTRIBUTING.md and CODE_OF_CONDUCT.md for how to contribute.

Where to go next

In the repository, docs/README.md indexes the user, admin and developer documentation, CHANGELOG.md records every release and ROADMAP.md lists planned work.