Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to Web Algebra are recorded here. The format follows
[Semantic Versioning](https://semver.org/). The normative definition of every
operation is [formal-semantics.md](formal-semantics.md).

## [2.0.1] - 2026-10-21

### Added

- **`web-algebra mcp`** runs the MCP server on stdio, as `web-algebra-mcp`
does. The MCP Registry entry (`server.json`) runs it: a registry client
starts a PyPI package as `uvx web-algebra`, which on its own starts the
planner.

## [2.0.0] - 2026-10-21

Web Algebra now has a formal semantics, and the Python implementation conforms
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ or with Claude Code:
claude mcp add web-algebra -e CERT_PEM_PATH=/path/to/LinkedDataHub/ssl/owner/cert.pem -e CERT_PASSWORD=******** -- uvx --from web-algebra web-algebra-mcp
```

`uvx web-algebra mcp` runs the same server.

Environment variables:

| Name | Required | Description |
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "web-algebra"
version = "2.0.0"
version = "2.0.1"
description = "Composable RDF operations in JSON"
readme = "README.md"
license = "Apache-2.0"
Expand Down
10 changes: 8 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
"url": "https://github.com/AtomGraph/Web-Algebra",
"source": "github"
},
"version": "2.0.0",
"version": "2.0.1",
"packages": [
{
"registryType": "pypi",
"identifier": "web-algebra",
"version": "2.0.0",
"version": "2.0.1",
"runtimeHint": "uvx",
"packageArguments": [
{
"type": "positional",
"value": "mcp"
}
],
"transport": {
"type": "stdio"
},
Expand Down
12 changes: 12 additions & 0 deletions src/web_algebra/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ def main(settings: BaseSettings, json_data: Optional[str]):

def cli() -> None:
parser = argparse.ArgumentParser(description="Run the AI-powered DSL interpreter.")
parser.add_argument(
"command",
nargs="?",
choices=["mcp"],
help="mcp: run the MCP server on stdio, as web-algebra-mcp does",
)
parser.add_argument(
"--from-json",
type=str,
Expand All @@ -152,6 +158,12 @@ def cli() -> None:
)
args = parser.parse_args()

if args.command == "mcp":
from web_algebra.__main__ import main as serve

serve()
return

# the flags override CERT_PEM_PATH / CERT_PASSWORD, which the settings
# read from the environment, as the MCP server and the tests do
overrides = {
Expand Down
14 changes: 12 additions & 2 deletions tests/test_mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ def mcp_tools():


class Stdio:
def __init__(self):
def __init__(self, command=("-m", "web_algebra")):
self.proc = subprocess.Popen(
[sys.executable, "-m", "web_algebra"],
[sys.executable, *command],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
Expand Down Expand Up @@ -106,6 +106,16 @@ def test_initialize_names_the_server_and_its_version(stdio):
assert info["version"] == version("web-algebra")


def test_the_cli_mcp_command_is_the_stdio_server():
# `web-algebra mcp` is what an MCP Registry client runs (server.json)
server = Stdio(("-m", "web_algebra.main", "mcp"))
try:
answer = server.request("initialize", INITIALIZE, timeout=60)
finally:
server.close()
assert answer["result"]["serverInfo"]["name"] == "web-algebra"


def test_initialize_offers_tools(stdio):
assert "tools" in stdio.initialized["result"]["capabilities"]

Expand Down
5 changes: 5 additions & 0 deletions tests/test_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ def test_server_json_names_the_pypi_package():
assert [p["identifier"] for p in SERVER["packages"] if p["registryType"] == "pypi"] == ["web-algebra"]


def test_server_json_runs_the_mcp_command():
# `uvx web-algebra` alone would start the planner, not the server
assert [p.get("packageArguments") for p in SERVER["packages"]] == [[{"type": "positional", "value": "mcp"}]]


def test_readme_carries_the_server_name():
assert f"mcp-name: {SERVER['name']} " in (ROOT / "README.md").read_text().replace("-->", " -->")

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading