From d691ef428eff2735cb92f6ad0ea55363b6361c2a Mon Sep 17 00:00:00 2001 From: Lukas Gold Date: Tue, 22 Sep 2026 14:26:03 +0200 Subject: [PATCH 1/4] docs(tools): document uv tool install for osw and osw-mcp - register the installed `osw-mcp` command instead of `uvx --from` - editable install from a checkout for CLI and MCP development - extras combine, e.g. `osw[mcp,wikitext]` - when `--reinstall` is needed, and the Windows Scripts lock - keep the entity model regeneration warning and name the read-only exception --- docs/tools/index.md | 55 ++++++++++++++++++++++++++++++++++++++++----- docs/tools/mcp.md | 45 ++++++++++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/docs/tools/index.md b/docs/tools/index.md index af7ac5df..7b99372c 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -8,13 +8,28 @@ differ in exactly one way: only the CLI accepts filesystem paths. ## Setup -Install one of the two; the second includes the first: +Install one of the first two; the second includes the first. Extras combine, so +one install can carry several: ```bash -uv tool install osw # the `osw` command -uv tool install "osw[mcp]" # the same, plus the `osw-mcp` server +uv tool install osw # the `osw` command +uv tool install "osw[mcp]" # the same, plus the `osw-mcp` server +uv tool install "osw[mcp,wikitext]" # two extras in one install ``` +uv writes the console scripts to its tool bin directory, `~/.local/bin` by +default. Run `uv tool update-shell` once if that directory is not on your PATH +yet. Later, `uv tool upgrade osw` replaces the commands in place, and every +registered MCP server follows, because the command names do not change. + +Two details: + +- Quote the argument. `osw[mcp]` contains brackets, which zsh reads as a glob + pattern and then refuses to run. +- uv writes `osw-mcp` to the bin directory even without the `mcp` extra, but + that copy raises `ModuleNotFoundError` at startup. Install `osw[mcp]` before + you register the server with a client. +
Other ways to install @@ -24,14 +39,44 @@ uv add "osw[mcp]" # as a dependency of the current uv project uvx --from "osw[mcp]" osw-mcp # run the server without installing it ``` -`uvx` is what the registration examples further down use, so the server needs -no install of its own. +`uvx` needs no install of its own. The MCP page shows it and the installed +`osw-mcp` command as the two registration options.
`osw[mcp]` is also part of `osw[all]`. The other extras are listed in the [Get Started guide](../get-started.md#optional-extras). +### From a local checkout + +To work on the CLI or the MCP server, install the same two commands from a +checkout in editable mode: + +```bash +cd /path/to/osw-python +uv tool install --reinstall --editable ".[mcp,wikitext]" +``` + +`osw` and `osw-mcp` then import from `src/` in that checkout, so a source edit +takes effect the next time either command starts, with no reinstall. Both +commands follow the checked-out branch, so switching branches changes what a +registered MCP server runs. Run the install command again after a change to +`pyproject.toml`: uv re-resolves from the checkout and installs the difference. + +Three things to know: + +- `--reinstall` rebuilds the tool environment from scratch, so the command + works from any previous state. It matters most in the other direction: + returning to a released version without it keeps the editable environment and + rewrites only the tool receipt, so receipt and environment disagree. +- On Windows, an install that has to replace the tool environment fails with + `os error 5` while an `osw-mcp` server from it is running, because the running + process locks the tool's `Scripts` directory. Stop the MCP clients first. +- An editable install makes the entity model regeneration described in + [Notes for developers](mcp.md#notes-for-developers) write into your working + tree. That section names the operations that trigger it, and says when to + prefer `uvx` for the MCP server instead. + ## In this section | Page | Contents | diff --git a/docs/tools/mcp.md b/docs/tools/mcp.md index c022c234..3ae5758e 100644 --- a/docs/tools/mcp.md +++ b/docs/tools/mcp.md @@ -42,6 +42,31 @@ Notes: for every project, or `-s project` to write a shared `.mcp.json`. - List what is registered with `claude mcp list`. +### `uvx` or the installed command + +The other examples on this page run the server with `uvx`, which needs no +install of its own. If you installed `osw[mcp]` with `uv tool install` +([Setup](index.md#setup)), register the `osw-mcp` command directly instead and +drop the `--from` argument: + +```bash +claude mcp add osw-dev \ + -e OSW_DOMAIN=wiki-dev.open-semantic-lab.org \ + -e OSW_CRED_FILEPATH=/abs/path/to/accounts.pwd.yaml \ + -- osw-mcp +``` + +In JSON, that entry is `"command": "osw-mcp"` with an empty `args` array. Every +other part of an entry, `env` included, stays the same. + +Which one to pick depends on how many instances you register. With `uvx`, the +package specification is part of every entry, so pinning a version or pointing +at a checkout means editing every entry in every client. With the installed +command, an entry names only `osw-mcp`, and `uv tool install` or +`uv tool upgrade osw` decides what that runs. The trade-off is that `osw-mcp` +has to be on the PATH of the client, and that all registered servers change +version together. + ## Registering a server A server entry can carry its settings in two ways: @@ -176,10 +201,18 @@ uvx --reinstall --from "/abs/path/to/osw-python[mcp]" osw-mcp it builds. In a JSON `args` array, a Windows path needs forward slashes or doubled backslashes. -Prefer that over an editable install for the server. `create_or_update_entity` -and `export_entity_jsonld` call `fetch_schema`, which regenerates -`src/osw/model/entity.py` inside the installed package: `uvx` builds a -non-editable wheel, so the write lands in the uv cache, while under -`pip install -e` or `uv sync` it lands in your working tree. The read tools +The alternative is an editable tool install +([From a local checkout](index.md#from-a-local-checkout)). The server then +registers as plain `osw-mcp`, no client config contains the checkout path, and +edits take effect at the next server start without a `--reinstall`. + +One difference decides between the two. `create_or_update_entity` and +`export_entity_jsonld` call `fetch_schema`, which regenerates +`src/osw/model/entity.py` inside the installed package. `uvx` builds a +non-editable wheel, so the regenerated file is written into the uv cache. Under +an editable install, as under `pip install -e` or `uv sync`, it is written into +your working tree, where git tracks it. Note that `export_entity_jsonld` is +declared read-only and still triggers this. The remaining read tools (`get_entity`, `get_slot`, `get_category_schema`, ...) read raw page slots and -never trigger it. +never trigger it. So choose `uvx` whenever a client may call either of those two +operations, and the editable install otherwise. From adf50d21405cbc396491929c6faa54b3de1caf8d Mon Sep 17 00:00:00 2001 From: Lukas Gold Date: Tue, 22 Sep 2026 15:06:38 +0200 Subject: [PATCH 2/4] fix(mcp): include the wikitext extra in the mcp extra - osw.wiki_tools warns at import time without mwparserfromhell - on stdio that warning reaches every MCP client's log --- pyproject.toml | 3 +++ uv.lock | 2 ++ 2 files changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 094d9c63..83295121 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,9 @@ mcp = [ # official MCP Python SDK; provides MCPServer from mcp.server. # requires 2.x: 1.x has no MCPServer, and 2.0 removed the vendored FastMCP. "mcp>=2", + # without it osw.wiki_tools warns at import time, which is noise on the + # server's stderr and appears in every client's log. + "osw[wikitext]", ] workflow = [ "prefect>=2.20.25,<3.0", diff --git a/uv.lock b/uv.lock index 0ef50ed4..2cbdbfe3 100644 --- a/uv.lock +++ b/uv.lock @@ -2121,6 +2121,7 @@ db = [ ] mcp = [ { name = "mcp" }, + { name = "mwparserfromhell" }, ] s3 = [ { name = "boto3" }, @@ -2191,6 +2192,7 @@ requires-dist = [ { name = "opensemantic-core", specifier = ">=0.57.4" }, { name = "osw", extras = ["dataimport"], marker = "extra == 'tutorial'" }, { name = "osw", extras = ["dataimport", "db", "ui", "s3", "wikitext", "mcp"], marker = "extra == 'all'" }, + { name = "osw", extras = ["wikitext"], marker = "extra == 'mcp'" }, { name = "prefect", marker = "extra == 'workflow'", specifier = ">=2.20.25,<3.0" }, { name = "psycopg2", marker = "extra == 'db'" }, { name = "pybars3-wheel" }, From ed1817465d1e9518c9903742276ce5a2352e8066 Mon Sep 17 00:00:00 2001 From: Lukas Gold Date: Tue, 22 Sep 2026 15:06:39 +0200 Subject: [PATCH 3/4] docs(tools): streamline install and registration guidance - index.md: one install path, no developer instructions - mcp.md: name both registration options in the intro - mcp.md: "Which command to register for the MCP server", two options - mcp.md: the editable developer install now lives in Notes for developers - drop `osw[mcp,wikitext]`, since `osw[mcp]` now implies it --- docs/tools/index.md | 64 +++++++++-------------------------- docs/tools/mcp.md | 82 ++++++++++++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 76 deletions(-) diff --git a/docs/tools/index.md b/docs/tools/index.md index 7b99372c..45dd54c3 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -8,27 +8,22 @@ differ in exactly one way: only the CLI accepts filesystem paths. ## Setup -Install one of the first two; the second includes the first. Extras combine, so -one install can carry several: +Install `osw` as a uv tool. The `mcp` extra adds the server to the same install: ```bash -uv tool install osw # the `osw` command -uv tool install "osw[mcp]" # the same, plus the `osw-mcp` server -uv tool install "osw[mcp,wikitext]" # two extras in one install +uv tool install osw # the `osw` command +uv tool install "osw[mcp]" # the same, plus the `osw-mcp` server ``` -uv writes the console scripts to its tool bin directory, `~/.local/bin` by +uv writes both console scripts to its tool bin directory, `~/.local/bin` by default. Run `uv tool update-shell` once if that directory is not on your PATH -yet. Later, `uv tool upgrade osw` replaces the commands in place, and every -registered MCP server follows, because the command names do not change. +yet, and `uv tool upgrade osw` to update them later. Quote the argument: +`osw[mcp]` contains brackets, which zsh reads as a glob pattern and then refuses +to run. -Two details: - -- Quote the argument. `osw[mcp]` contains brackets, which zsh reads as a glob - pattern and then refuses to run. -- uv writes `osw-mcp` to the bin directory even without the `mcp` extra, but - that copy raises `ModuleNotFoundError` at startup. Install `osw[mcp]` before - you register the server with a client. +Without the `mcp` extra, uv still writes `osw-mcp` to the bin directory, but +that copy raises `ModuleNotFoundError` at startup. Install `osw[mcp]` before you +register the server with a client.
Other ways to install @@ -39,43 +34,14 @@ uv add "osw[mcp]" # as a dependency of the current uv project uvx --from "osw[mcp]" osw-mcp # run the server without installing it ``` -`uvx` needs no install of its own. The MCP page shows it and the installed -`osw-mcp` command as the two registration options. +`uvx` needs no install of its own. +[Which command to register](mcp.md#which-command-to-register-for-the-mcp-server) +explains when to prefer it over the installed command.
-`osw[mcp]` is also part of `osw[all]`. The other extras are listed in the -[Get Started guide](../get-started.md#optional-extras). - -### From a local checkout - -To work on the CLI or the MCP server, install the same two commands from a -checkout in editable mode: - -```bash -cd /path/to/osw-python -uv tool install --reinstall --editable ".[mcp,wikitext]" -``` - -`osw` and `osw-mcp` then import from `src/` in that checkout, so a source edit -takes effect the next time either command starts, with no reinstall. Both -commands follow the checked-out branch, so switching branches changes what a -registered MCP server runs. Run the install command again after a change to -`pyproject.toml`: uv re-resolves from the checkout and installs the difference. - -Three things to know: - -- `--reinstall` rebuilds the tool environment from scratch, so the command - works from any previous state. It matters most in the other direction: - returning to a released version without it keeps the editable environment and - rewrites only the tool receipt, so receipt and environment disagree. -- On Windows, an install that has to replace the tool environment fails with - `os error 5` while an `osw-mcp` server from it is running, because the running - process locks the tool's `Scripts` directory. Stop the MCP clients first. -- An editable install makes the entity model regeneration described in - [Notes for developers](mcp.md#notes-for-developers) write into your working - tree. That section names the operations that trigger it, and says when to - prefer `uvx` for the MCP server instead. +`osw[mcp]` includes `osw[wikitext]`, and is itself part of `osw[all]`. The other +extras are listed in the [Get Started guide](../get-started.md#optional-extras). ## In this section diff --git a/docs/tools/mcp.md b/docs/tools/mcp.md index 3ae5758e..54b050ef 100644 --- a/docs/tools/mcp.md +++ b/docs/tools/mcp.md @@ -8,6 +8,11 @@ introspect category schemas, read entities and every page slot, create/update and delete entities, and read and write file pages as text. The transport is stdio; SSE and HTTP are not supported. +A registered server runs the `osw-mcp` console script, and there are two ways to +reach it: let `uvx` fetch it for each server, or install `osw[mcp]` once and +register the command directly. See +[Which command to register for the MCP server](#which-command-to-register-for-the-mcp-server). + **No filesystem access:** no MCP tool takes or returns a local path. File content moves inline as text (`get_file_info`, `read_file_text`, `write_file_text`), and everything path-based lives in the CLI instead @@ -42,30 +47,32 @@ Notes: for every project, or `-s project` to write a shared `.mcp.json`. - List what is registered with `claude mcp list`. -### `uvx` or the installed command +### Which command to register for the MCP server -The other examples on this page run the server with `uvx`, which needs no -install of its own. If you installed `osw[mcp]` with `uv tool install` -([Setup](index.md#setup)), register the `osw-mcp` command directly instead and -drop the `--from` argument: +- **To pin the `osw` version per server, register the `uvx` command**, as in the + example above and in every other example on this page. The package + specification is part of the entry, so one server can name a version or a + checkout that the others do not use. `uvx` needs no install of its own. The + cost is that changing the version means editing every entry that should + change. -```bash -claude mcp add osw-dev \ - -e OSW_DOMAIN=wiki-dev.open-semantic-lab.org \ - -e OSW_CRED_FILEPATH=/abs/path/to/accounts.pwd.yaml \ - -- osw-mcp -``` +- **To let all servers share one `osw` version, register the installed + `osw-mcp` command.** Install `osw[mcp]` as a uv tool ([Setup](index.md#setup)), + then register that command in place of the whole `uvx --from ...` invocation: -In JSON, that entry is `"command": "osw-mcp"` with an empty `args` array. Every -other part of an entry, `env` included, stays the same. + ```bash + claude mcp add osw-dev \ + -e OSW_DOMAIN=wiki-dev.open-semantic-lab.org \ + -e OSW_CRED_FILEPATH=/abs/path/to/accounts.pwd.yaml \ + -- osw-mcp + ``` -Which one to pick depends on how many instances you register. With `uvx`, the -package specification is part of every entry, so pinning a version or pointing -at a checkout means editing every entry in every client. With the installed -command, an entry names only `osw-mcp`, and `uv tool install` or -`uv tool upgrade osw` decides what that runs. The trade-off is that `osw-mcp` -has to be on the PATH of the client, and that all registered servers change -version together. + In JSON that entry is `"command": "osw-mcp"` with an empty `args` array. + `uv tool upgrade osw` then changes the version for every server at once. The + cost is that `osw-mcp` has to be on the PATH of the client, and that no + server can keep an older version. + +Everything else about an entry, `env` included, is the same either way. ## Registering a server @@ -190,8 +197,11 @@ Why the MCP server is shaped the way it is, and how that differs from the CLI: ## Notes for developers -To try an unreleased branch against a real client, point `uvx` at the checkout -instead of at PyPI. Everything else about the registration stays the same: +To try an unreleased branch against a real client, run it from the checkout. The +same two options apply as above. + +Point `uvx` at the checkout instead of at PyPI. Everything else about the +registration stays the same: ```bash uvx --reinstall --from "/abs/path/to/osw-python[mcp]" osw-mcp @@ -201,12 +211,30 @@ uvx --reinstall --from "/abs/path/to/osw-python[mcp]" osw-mcp it builds. In a JSON `args` array, a Windows path needs forward slashes or doubled backslashes. -The alternative is an editable tool install -([From a local checkout](index.md#from-a-local-checkout)). The server then -registers as plain `osw-mcp`, no client config contains the checkout path, and -edits take effect at the next server start without a `--reinstall`. +Or install the checkout as an editable uv tool. The server then registers as +plain `osw-mcp`, no client config contains the checkout path, and edits take +effect at the next server start without a reinstall: + +```bash +cd /path/to/osw-python +uv tool install --reinstall --editable ".[mcp]" +``` -One difference decides between the two. `create_or_update_entity` and +`osw` and `osw-mcp` then import from `src/` in that checkout. Four consequences: + +- Both commands follow the checked-out branch, so switching branches changes + what a registered server runs. +- Run the install command again after a change to `pyproject.toml`. uv + re-resolves from the checkout and installs the difference. +- Returning to a released version needs `--reinstall`. Without it uv finds the + requirement satisfied, keeps the editable environment and rewrites only the + tool receipt, so receipt and environment disagree. +- On Windows, an install that has to replace the tool environment fails with + `os error 5` while an `osw-mcp` server from it is running, because the running + process locks the tool's `Scripts` directory. Stop the MCP clients first. + +One difference decides between `uvx` and the editable install. +`create_or_update_entity` and `export_entity_jsonld` call `fetch_schema`, which regenerates `src/osw/model/entity.py` inside the installed package. `uvx` builds a non-editable wheel, so the regenerated file is written into the uv cache. Under From c492583db6a7a19647a828881b7fd45992697c96 Mon Sep 17 00:00:00 2001 From: Lukas Gold Date: Tue, 22 Sep 2026 15:15:50 +0200 Subject: [PATCH 4/4] docs(mcp): note that uvx reuses an installed osw tool - uvx runs the installed tool when it satisfies the specification - an explicit version keeps a server independent of it --- docs/tools/mcp.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/tools/mcp.md b/docs/tools/mcp.md index 54b050ef..13fc4bf1 100644 --- a/docs/tools/mcp.md +++ b/docs/tools/mcp.md @@ -54,7 +54,10 @@ Notes: specification is part of the entry, so one server can name a version or a checkout that the others do not use. `uvx` needs no install of its own. The cost is that changing the version means editing every entry that should - change. + change. Note that `uvx` reuses an installed `osw` tool whenever that + installation satisfies the specification, so an unpinned `osw[mcp]` runs the + installed version if there is one. Write an explicit version, for example + `osw[mcp]==2.6.2`, when a server must be independent of it. - **To let all servers share one `osw` version, register the installed `osw-mcp` command.** Install `osw[mcp]` as a uv tool ([Setup](index.md#setup)), @@ -207,8 +210,8 @@ registration stays the same: uvx --reinstall --from "/abs/path/to/osw-python[mcp]" osw-mcp ``` -`--reinstall` is what picks up your latest edits, since `uvx` caches the wheel -it builds. In a JSON `args` array, a Windows path needs forward slashes or +`--reinstall` is what makes `uvx` use your latest edits, since it caches the +wheel it builds. In a JSON `args` array, a Windows path needs forward slashes or doubled backslashes. Or install the checkout as an editable uv tool. The server then registers as