Skip to content

feat/mcp-server#133

Open
LukasGold wants to merge 19 commits into
mainfrom
feat/mcp-server
Open

feat/mcp-server#133
LukasGold wants to merge 19 commits into
mainfrom
feat/mcp-server

Conversation

@LukasGold

Copy link
Copy Markdown
Contributor

providing a draft for a MCP server for osw-python

raederan and others added 19 commits July 7, 2026 13:46
Move project metadata and dependencies from setup.cfg into a PEP 621
[project] table, swap the setuptools/setuptools-scm backend for
hatchling + hatch-vcs (version_scheme preserved as no-guess-dev), and
add a committed uv.lock. setup.py and tox.ini are retained until their
replacements are proven.
Add a composite setup-python-env action (setup-uv + uv sync --frozen)
and a main.yml workflow with a quality job (make check) and an 8-leg
test matrix (ubuntu 3.10-3.13, macos/windows on 3.10+3.13) running
pytest and ty. Coverage goes to codecov via the org-level
CODECOV_TOKEN with informational statuses. ci.yml is replaced by
on-release-main.yml (interim token publish) so the workflow filename
and pypi environment already match the upcoming OIDC trusted
publisher configuration
Replace the dual sphinx (readthedocs) + mkdocs (gh-pages) stack with
zensical: new zensical.toml (material theme, mkdocstrings on src),
rewritten landing page, real docs/docs-test Makefile targets, a
check-docs CI job, and a Pages-artifact deploy workflow. Remove
conf.py, mkdocs.yml, .readthedocs.yml, docs/requirements.txt and the
sphinx-only include shim pages
Enable the mike version provider in zensical.toml and deploy docs to
the gh-pages branch: main pushes publish the dev version (docs.yml),
release tags publish X.Y.Z with the latest alias and root redirect
(on-release-main.yml). The zensical-compatible mike fork is pinned in
the dev dependency group and commit-hash locked in uv.lock
Delete setup.py, setup.cfg, tox.ini and the stray root __init__.py.
Remove eight unused runtime dependencies (ruamel.yaml, pandas, chardet,
matplotlib, scipy, sphinx, and the stdlib-shadowing pathlib/asyncio),
drop the testing extra in favor of the dev dependency group, and trim
the deptry ignores accordingly (lock: 220 to 187 packages). Update
README, CONTRIBUTING, docs/dev.md and test docstrings to the uv/make
workflow; mark CHANGELOG as release-notes-based until
python-semantic-release lands
Rebuild the site after the oold-python layout: hero landing page with
logo and call-to-action buttons, about and get-started pages (tabbed
uv/pip install, extras table, quickstart from real examples), API
reference grouped under docs/api (fixing a sphinx-era gitignore rule
that hid it), and dev.md as a tabbed make/manual mirror of the
simplified CONTRIBUTING. Slim README down to pitch, install,
quickstart and links
Give the live upload tests unique per-run file names and content so
leftover pages on the shared test wiki can no longer trigger
fileexists-no-change errors, and move the wiki-side cleanup of the
target-fpt test into a finally block so failed runs do not leak state.
CredentialManager resolves credentials from memory, an existing file
(read-only), the OSW_USERNAME/OSW_PASSWORD environment variables (e.g.
via .env), or an interactive prompt, and no longer persists them:
OswExpress drops the save-path prompt and auto-save, the prompt result
stays in memory, save_credentials_to_file becomes an explicit
deprecated opt-in and stops editing .gitignore. Update tests to the
new contract and document the resolution order.

Also keep the entity model pristine after tests and clean up warnings:
snapshot and restore src/osw/model/entity.py around integration test
sessions (fetch_schema regenerates it into the source tree by design),
remove a self-referential deprecation on StoreOntologiesParam, make
FileResult.close() a silent no-op on closed files like io streams,
mark deliberately triggered warnings as expected per test, and filter
non-actionable third-party warnings narrowly (122 -> 1 on the
integration suite).

BREAKING CHANGE: credentials are no longer written to disk
automatically; rely on OSW_USERNAME/OSW_PASSWORD (or a .env file), an
in-memory CredentialManager, or a self-managed credentials file.
Analyze conventional commits on every push to main: when a release is
due, semantic-release updates the changelog (insertion flag, history
preserved), commits, tags vX.Y.Z and creates the GitHub release; the
same workflow run then builds, publishes to PyPI via trusted
publishing and deploys the versioned docs. hatch-vcs derives the
package version from the tag, so no version file is bumped. Replaces
the manual tag-push release flow.
Add an in-repo `osw[mcp]` extra and an `osw-mcp` stdio console script that
wraps OswExpress and serves it over the Model Context Protocol for clients
such as Claude Code.

Tools: semantic/SPARQL/full-text search, category schema introspection,
entity read + JSON-LD export, create/update/delete, full page-slot access,
and file up/download.

- Delete is provenance-guarded: a local JSON ledger records pages the server
  created/modified; deleting anything untracked requires
  confirm_external_delete=true.
- Credentials resolve from env/.env and are validated up front (fail fast,
  never prompts, so stdio is never corrupted by an input() call).
- osw stdout is redirected to stderr so it never leaks onto the JSON-RPC channel.
- OSW_MCP_READ_ONLY hides all mutating tools.
Three linked defects caused store_entity() to drop a page during batch
uploads while reporting success.

Fix A (wtsite.py, WtPage.edit): the retry loop returned None after
exhausting all attempts, discarding the last exception. It now raises a
RuntimeError chained from the underlying error so callers see the failure.

Fix B1 (wtsite.py): parallel uploads share one mwclient session. Guard the
destructive session mutations (_clear_cookies, _relogin, and edit()'s
token-refresh recovery) with a per-WtSite RLock, and iterate a snapshot of
the cookie jar in _clear_cookies. A lazy _get_session_lock() accessor keeps
WtSite instances built via __new__ (tests) working.

Fix C (util.py, core.py): add return_exceptions to parallelize() (captures
per-task exceptions instead of aborting the batch on the first). store_entity
now collects per-entity outcomes for both serial and parallel paths, adds
StoreEntityResult.failed, and raises OSW.StoreEntityPartialError carrying the
partial result (stored + failed) on any failure.

Adds offline unit tests for all three fixes.

(cherry picked from commit 280838c)
@LukasGold
LukasGold requested a review from simontaurus July 20, 2026 10:59
@LukasGold LukasGold self-assigned this Jul 20, 2026
@LukasGold LukasGold added the enhancement New feature or request label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants