agent-bus-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. agent_bus_mcp-0.1.0/.github/workflows/build-wheels.yml +112 -0
  2. agent_bus_mcp-0.1.0/.github/workflows/ci.yml +84 -0
  3. agent_bus_mcp-0.1.0/.github/workflows/publish-testpypi.yml +134 -0
  4. agent_bus_mcp-0.1.0/.gitignore +29 -0
  5. agent_bus_mcp-0.1.0/AGENTS.md +50 -0
  6. agent_bus_mcp-0.1.0/CLAUDE.md +82 -0
  7. agent_bus_mcp-0.1.0/Cargo.lock +2464 -0
  8. agent_bus_mcp-0.1.0/Cargo.toml +18 -0
  9. agent_bus_mcp-0.1.0/LICENSE +21 -0
  10. agent_bus_mcp-0.1.0/PKG-INFO +337 -0
  11. agent_bus_mcp-0.1.0/README.md +308 -0
  12. agent_bus_mcp-0.1.0/agent_bus/__init__.py +3 -0
  13. agent_bus_mcp-0.1.0/agent_bus/cli.py +778 -0
  14. agent_bus_mcp-0.1.0/agent_bus/common.py +119 -0
  15. agent_bus_mcp-0.1.0/agent_bus/db.py +322 -0
  16. agent_bus_mcp-0.1.0/agent_bus/embedding_worker.py +209 -0
  17. agent_bus_mcp-0.1.0/agent_bus/entrypoint.py +40 -0
  18. agent_bus_mcp-0.1.0/agent_bus/models.py +37 -0
  19. agent_bus_mcp-0.1.0/agent_bus/peer_server.py +826 -0
  20. agent_bus_mcp-0.1.0/agent_bus/search.py +307 -0
  21. agent_bus_mcp-0.1.0/agent_bus/tool_schemas.py +192 -0
  22. agent_bus_mcp-0.1.0/agent_bus/web/__init__.py +1 -0
  23. agent_bus_mcp-0.1.0/agent_bus/web/server.py +405 -0
  24. agent_bus_mcp-0.1.0/agent_bus/web/templates/base.html +1203 -0
  25. agent_bus_mcp-0.1.0/agent_bus/web/templates/components/message.html +102 -0
  26. agent_bus_mcp-0.1.0/agent_bus/web/templates/components/messages.html +32 -0
  27. agent_bus_mcp-0.1.0/agent_bus/web/templates/components/presence.html +10 -0
  28. agent_bus_mcp-0.1.0/agent_bus/web/templates/components/search_results.html +40 -0
  29. agent_bus_mcp-0.1.0/agent_bus/web/templates/topics/detail.html +222 -0
  30. agent_bus_mcp-0.1.0/agent_bus/web/templates/topics/list.html +35 -0
  31. agent_bus_mcp-0.1.0/pyproject.toml +80 -0
  32. agent_bus_mcp-0.1.0/spec.md +263 -0
  33. agent_bus_mcp-0.1.0/src/lib.rs +2792 -0
  34. agent_bus_mcp-0.1.0/tests/test_cli.py +418 -0
  35. agent_bus_mcp-0.1.0/tests/test_cli_export.py +241 -0
  36. agent_bus_mcp-0.1.0/tests/test_cli_search.py +49 -0
  37. agent_bus_mcp-0.1.0/tests/test_cli_tail_flag.py +39 -0
  38. agent_bus_mcp-0.1.0/tests/test_db.py +722 -0
  39. agent_bus_mcp-0.1.0/tests/test_db_latest.py +39 -0
  40. agent_bus_mcp-0.1.0/tests/test_pagination.py +118 -0
  41. agent_bus_mcp-0.1.0/tests/test_search.py +54 -0
  42. agent_bus_mcp-0.1.0/tests/test_tools_smoke.py +197 -0
  43. agent_bus_mcp-0.1.0/tests/test_validation.py +45 -0
  44. agent_bus_mcp-0.1.0/uv.lock +925 -0
@@ -0,0 +1,112 @@
1
+ name: build-wheels
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ upload_artifacts:
7
+ type: boolean
8
+ default: true
9
+ workflow_dispatch:
10
+ inputs:
11
+ upload_artifacts:
12
+ type: boolean
13
+ default: true
14
+
15
+ env:
16
+ ORT_VERSION: "1.23.2"
17
+
18
+ jobs:
19
+ sdist:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Validate version sync
25
+ run: |
26
+ python - <<'PY'
27
+ import tomllib
28
+
29
+ with open("pyproject.toml", "rb") as fh:
30
+ pyproject = tomllib.load(fh)
31
+ with open("Cargo.toml", "rb") as fh:
32
+ cargo = tomllib.load(fh)
33
+
34
+ py_version = pyproject["project"]["version"]
35
+ cargo_version = cargo["package"]["version"]
36
+
37
+ if py_version != cargo_version:
38
+ raise SystemExit(
39
+ f"Version mismatch: pyproject.toml={py_version} Cargo.toml={cargo_version}"
40
+ )
41
+ print(f"Version OK: {py_version}")
42
+ PY
43
+
44
+ - name: Build sdist
45
+ uses: PyO3/maturin-action@v1
46
+ with:
47
+ command: sdist
48
+ args: --out dist
49
+
50
+ - name: Upload sdist
51
+ if: inputs.upload_artifacts
52
+ uses: actions/upload-artifact@v4
53
+ with:
54
+ name: sdist
55
+ path: dist/*.tar.gz
56
+ if-no-files-found: error
57
+
58
+ wheels:
59
+ runs-on: ${{ matrix.os }}
60
+ strategy:
61
+ fail-fast: false
62
+ matrix:
63
+ os:
64
+ - ubuntu-latest
65
+ - macos-14
66
+ - windows-latest
67
+ steps:
68
+ - uses: actions/checkout@v4
69
+
70
+ - name: Download ONNX Runtime (Windows)
71
+ if: runner.os == 'Windows'
72
+ shell: pwsh
73
+ run: |
74
+ $zip = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION.zip"
75
+ $dir = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION"
76
+ Invoke-WebRequest -Uri "https://github.com/microsoft/onnxruntime/releases/download/v$env:ORT_VERSION/onnxruntime-win-x64-$env:ORT_VERSION.zip" -OutFile $zip
77
+ Expand-Archive -Path $zip -DestinationPath $env:RUNNER_TEMP
78
+ "ORT_LIB_LOCATION=$dir\\lib" | Out-File -FilePath $env:GITHUB_ENV -Append
79
+ "ORT_PREFER_DYNAMIC_LINK=1" | Out-File -FilePath $env:GITHUB_ENV -Append
80
+ "PATH=$dir\\lib;$env:PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
81
+
82
+ - name: Build wheels (Linux, manylinux_2_28)
83
+ if: runner.os == 'Linux'
84
+ uses: PyO3/maturin-action@v1
85
+ with:
86
+ command: build
87
+ args: --release --out dist
88
+ manylinux: 2_28
89
+
90
+ - name: Build wheels (Linux, manylinux_2_28 aarch64)
91
+ if: runner.os == 'Linux'
92
+ uses: PyO3/maturin-action@v1
93
+ with:
94
+ command: build
95
+ args: --release --out dist
96
+ manylinux: 2_28
97
+ target: aarch64-unknown-linux-gnu
98
+
99
+ - name: Build wheels (macOS/Windows)
100
+ if: runner.os != 'Linux'
101
+ uses: PyO3/maturin-action@v1
102
+ with:
103
+ command: build
104
+ args: --release --out dist
105
+
106
+ - name: Upload wheels
107
+ if: inputs.upload_artifacts
108
+ uses: actions/upload-artifact@v4
109
+ with:
110
+ name: wheels-${{ runner.os }}
111
+ path: dist/*.whl
112
+ if-no-files-found: error
@@ -0,0 +1,84 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ env:
10
+ ORT_VERSION: "1.23.2"
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ${{ matrix.os }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ os:
19
+ - ubuntu-latest
20
+ - macos-14
21
+ - windows-latest
22
+ python-version:
23
+ - "3.12"
24
+ - "3.13"
25
+ - "3.14"
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - uses: dtolnay/rust-toolchain@stable
30
+ with:
31
+ components: rustfmt, clippy
32
+
33
+ - uses: actions/setup-python@v5
34
+ with:
35
+ python-version: ${{ matrix.python-version }}
36
+
37
+ - uses: astral-sh/setup-uv@v3
38
+ with:
39
+ enable-cache: true
40
+
41
+ - name: Download ONNX Runtime (Windows)
42
+ if: runner.os == 'Windows'
43
+ shell: pwsh
44
+ run: |
45
+ $zip = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION.zip"
46
+ $dir = "$env:RUNNER_TEMP/onnxruntime-win-x64-$env:ORT_VERSION"
47
+ Invoke-WebRequest -Uri "https://github.com/microsoft/onnxruntime/releases/download/v$env:ORT_VERSION/onnxruntime-win-x64-$env:ORT_VERSION.zip" -OutFile $zip
48
+ Expand-Archive -Path $zip -DestinationPath $env:RUNNER_TEMP
49
+ "ORT_LIB_LOCATION=$dir\\lib" | Out-File -FilePath $env:GITHUB_ENV -Append
50
+ "ORT_PREFER_DYNAMIC_LINK=1" | Out-File -FilePath $env:GITHUB_ENV -Append
51
+ "PATH=$dir\\lib;$env:PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
52
+
53
+ - name: Sync deps
54
+ run: uv sync --dev
55
+
56
+ - name: Build wheel
57
+ run: uv run maturin build --release -o dist
58
+
59
+ - name: Install wheel
60
+ shell: bash
61
+ run: uv pip install --force-reinstall dist/*.whl
62
+
63
+ - name: Run tests
64
+ run: uv run pytest
65
+
66
+ - name: Cargo fmt
67
+ run: cargo fmt --check
68
+
69
+ - name: Cargo clippy
70
+ run: cargo clippy --all-targets -- -D warnings
71
+
72
+ - name: Ruff format
73
+ run: uv run ruff format --check
74
+
75
+ - name: Ruff lint
76
+ run: uv run ruff check
77
+
78
+ - name: Ty type check
79
+ run: uv run ty check
80
+
81
+ wheels:
82
+ uses: ./.github/workflows/build-wheels.yml
83
+ with:
84
+ upload_artifacts: false
@@ -0,0 +1,134 @@
1
+ name: publish-testpypi
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ publish_target:
7
+ description: "Publish destination"
8
+ required: true
9
+ type: choice
10
+ default: testpypi
11
+ options:
12
+ - testpypi
13
+ - pypi
14
+
15
+ permissions:
16
+ contents: write
17
+
18
+ jobs:
19
+ build:
20
+ uses: ./.github/workflows/build-wheels.yml
21
+ with:
22
+ upload_artifacts: true
23
+
24
+ upload:
25
+ needs: build
26
+ runs-on: ubuntu-latest
27
+ outputs:
28
+ version: ${{ steps.version.outputs.version }}
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Download artifacts
33
+ uses: actions/download-artifact@v4
34
+ with:
35
+ path: dist
36
+ merge-multiple: true
37
+
38
+ - uses: astral-sh/setup-uv@v3
39
+ with:
40
+ enable-cache: false
41
+
42
+ - name: Upload to TestPyPI
43
+ shell: bash
44
+ run: |
45
+ set -euo pipefail
46
+ repo_url="https://test.pypi.org/legacy/"
47
+ token="${{ secrets.TEST_PYPI_API_TOKEN }}"
48
+ if [ "${{ inputs.publish_target }}" = "pypi" ]; then
49
+ repo_url="https://upload.pypi.org/legacy/"
50
+ token="${{ secrets.PYPI_API_TOKEN }}"
51
+ fi
52
+ MATURIN_PYPI_TOKEN="$token" MATURIN_REPOSITORY_URL="$repo_url" \
53
+ uvx --from "maturin>=1.11.5,<2.0" maturin upload --non-interactive --skip-existing dist/*
54
+
55
+ - name: Determine version
56
+ id: version
57
+ run: |
58
+ python - <<'PY'
59
+ import os
60
+ import tomllib
61
+
62
+ with open("pyproject.toml", "rb") as fh:
63
+ data = tomllib.load(fh)
64
+ version = data["project"]["version"]
65
+ with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
66
+ fh.write(f"version={version}\n")
67
+ print(f"Detected version: {version}")
68
+ PY
69
+
70
+ qa-install:
71
+ needs: upload
72
+ if: ${{ inputs.publish_target == 'testpypi' }}
73
+ runs-on: ${{ matrix.os }}
74
+ strategy:
75
+ fail-fast: false
76
+ matrix:
77
+ os:
78
+ - ubuntu-latest
79
+ - macos-14
80
+ - windows-latest
81
+ steps:
82
+ - uses: actions/setup-python@v5
83
+ with:
84
+ python-version: "3.12"
85
+
86
+ - uses: astral-sh/setup-uv@v3
87
+ with:
88
+ enable-cache: true
89
+
90
+ - name: Install from TestPyPI (no build)
91
+ shell: bash
92
+ env:
93
+ VERSION: ${{ needs.upload.outputs.version }}
94
+ run: |
95
+ set -euo pipefail
96
+ echo "Testing install for agent-bus-mcp==$VERSION on $RUNNER_OS"
97
+ for attempt in {1..10}; do
98
+ if uvx --no-build \
99
+ --default-index https://test.pypi.org/simple \
100
+ --index https://pypi.org/simple \
101
+ --from "agent-bus-mcp==${VERSION}" \
102
+ agent-bus --help; then
103
+ exit 0
104
+ fi
105
+ echo "Install failed (attempt $attempt). Waiting for TestPyPI propagation..."
106
+ sleep 20
107
+ done
108
+ echo "Install failed after retries."
109
+ exit 1
110
+
111
+ tag-release:
112
+ needs: upload
113
+ if: ${{ inputs.publish_target == 'pypi' }}
114
+ runs-on: ubuntu-latest
115
+ steps:
116
+ - uses: actions/checkout@v4
117
+ with:
118
+ fetch-depth: 0
119
+ fetch-tags: true
120
+
121
+ - name: Create annotated tag
122
+ env:
123
+ VERSION: ${{ needs.upload.outputs.version }}
124
+ run: |
125
+ set -euo pipefail
126
+ tag="v${VERSION}"
127
+ if git rev-parse "$tag" >/dev/null 2>&1; then
128
+ echo "Tag $tag already exists, skipping."
129
+ exit 0
130
+ fi
131
+ git config user.name "github-actions[bot]"
132
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
133
+ git tag -a "$tag" "$GITHUB_SHA" -m "Release $tag"
134
+ git push origin "$tag"
@@ -0,0 +1,29 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .mypy_cache/
7
+ dist/
8
+ dist-*/
9
+ build/
10
+ target/
11
+ *.egg-info/
12
+ agent_bus/_core*.so
13
+ agent_bus/_core*.pyd
14
+ agent_bus/_core*.dylib
15
+ .DS_Store
16
+ .claude
17
+ .claude/
18
+ .gemini/
19
+ .vscode/
20
+ specs*.md
21
+
22
+ # Waylog transcripts (may contain sensitive info)
23
+ .waylog/
24
+ .waylog-journal/
25
+
26
+ # Local DB artifacts (if created under repo by tests/dev)
27
+ *.sqlite
28
+ *.sqlite-wal
29
+ *.sqlite-shm
@@ -0,0 +1,50 @@
1
+ # Repository Guidelines
2
+
3
+ ## Project Structure & Module Organization
4
+
5
+ - `agent_bus/`: main Python package
6
+ - `peer_server.py`: MCP server (FastMCP) tools: `topic_*`, `cursor_reset`, `sync`
7
+ - `db.py`: SQLite (WAL) storage, schema/versioning, sync/cursor logic
8
+ - `cli.py`: admin CLI (`agent-bus cli ...`)
9
+ - `web/`: optional FastAPI web UI + Jinja templates in `agent_bus/web/templates/`
10
+ - `tests/`: pytest suite (`test_*.py`)
11
+ - `spec.md`: protocol + schema spec (treat as the source of truth when changing behavior)
12
+
13
+ ## Build, Test, and Development Commands
14
+
15
+ This repo targets Python 3.12+ and uses `uv` for local development:
16
+
17
+ ```bash
18
+ uv sync # install runtime deps
19
+ uv sync --dev # install dev deps (pytest, ruff, web extra)
20
+ uv run agent-bus # run MCP server over stdio
21
+ uv sync --extra web # install Web UI deps
22
+ uv run agent-bus serve # run Web UI (default http://127.0.0.1:8080)
23
+ uv run ruff format # format
24
+ uv run ruff check # lint
25
+ uv run pytest # tests
26
+ ```
27
+
28
+ ## Coding Style & Naming Conventions
29
+
30
+ - Format/lint with Ruff (`ruff format`, `ruff check`). Line length is 100.
31
+ - Prefer type hints and small, focused modules.
32
+ - Naming: `snake_case` (functions/vars), `PascalCase` (types), `SCREAMING_SNAKE_CASE` (constants).
33
+
34
+ ## Testing Guidelines
35
+
36
+ - Framework: pytest (some tests use `anyio` to exercise the stdio MCP server).
37
+ - Keep tests hermetic: use `tmp_path` and point `AGENT_BUS_DB` at a temp SQLite file.
38
+ - Name tests `tests/test_*.py` and prefer unit tests for `AgentBusDB` plus a small number of end-to-end smoke tests.
39
+
40
+ ## Commit & Pull Request Guidelines
41
+
42
+ Commit history uses lightweight Conventional-ish prefixes (e.g. `feat(web): ...`, `fix(web): ...`, `docs: ...`, `chore: ...`) and component prefixes like `web: ...` / `peer: ...` / `cli: ...`. Follow one of those patterns.
43
+
44
+ PRs should include: a short description, how to test, and screenshots for Web UI changes. Run `uv run ruff check` and `uv run pytest` before requesting review.
45
+
46
+ ## Security & Configuration Tips
47
+
48
+ - Web UI has no auth; keep it bound to localhost unless you add protections.
49
+ - DB schema is versioned; a mismatch requires wiping the DB (see `agent-bus cli db wipe --yes`).
50
+ - Key env vars: `AGENT_BUS_DB`, `AGENT_BUS_MAX_*`, `AGENT_BUS_POLL_*`.
@@ -0,0 +1,82 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Agent Bus is a local SQLite-backed MCP (Model Context Protocol) server for peer-to-peer agent communication. It enables multiple AI agents to communicate through a shared message bus with delta-based sync via server-side cursors.
8
+
9
+ ## Common Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ uv sync # Core dependencies only
14
+ uv sync --dev # With dev dependencies (pytest, ruff)
15
+ uv sync --extra web # With web UI dependencies
16
+
17
+ # Run the MCP server (stdio transport)
18
+ uv run agent-bus
19
+
20
+ # Run the web UI
21
+ uv run agent-bus serve
22
+
23
+ # Linting and formatting
24
+ uv run ruff format
25
+ uv run ruff check
26
+
27
+ # Run all tests
28
+ uv run pytest
29
+
30
+ # Run a single test file
31
+ uv run pytest tests/test_db.py
32
+
33
+ # Run a specific test
34
+ uv run pytest tests/test_db.py::test_topic_create_reuse_newest_open
35
+
36
+ # CLI administrative commands
37
+ uv run agent-bus cli topics list --status all
38
+ uv run agent-bus cli topics watch <topic_id> --follow
39
+ uv run agent-bus cli db wipe --yes
40
+ ```
41
+
42
+ ## Architecture
43
+
44
+ ### Core Components
45
+
46
+ - **`agent_bus/peer_server.py`**: MCP server implementation using FastMCP. Defines all MCP tools (`ping`, `topic_create`, `topic_join`, `sync`, etc.). The `sync()` tool is the primary read/write interface with delta-based polling and server-side cursors.
47
+
48
+ - **`agent_bus/db.py`**: SQLite database layer (`AgentBusDB` class). Handles all persistence: topics, messages, cursors, and sequences. Uses WAL mode for concurrent access. Key method is `sync_once()` which handles message sending and receiving in a single transaction.
49
+
50
+ - **`agent_bus/models.py`**: Frozen dataclasses for `Topic`, `Message`, and `Cursor`.
51
+
52
+ - **`agent_bus/common.py`**: Shared utilities including `tool_ok()`/`tool_error()` for MCP response formatting, error codes, and environment variable helpers.
53
+
54
+ - **`agent_bus/cli.py`**: Click-based CLI for administrative operations (list topics, watch messages, export, delete).
55
+
56
+ - **`agent_bus/entrypoint.py`**: Main entry point. Runs MCP server by default; `serve` subcommand starts web UI; `cli` subcommand runs admin commands.
57
+
58
+ - **`agent_bus/web/server.py`**: Optional FastAPI web server with HTMX-powered UI for browsing topics and messages.
59
+
60
+ ### Key Patterns
61
+
62
+ - **Server-side cursors**: Each agent has a cursor per topic tracking `last_seq`. The `sync()` tool advances this cursor, enabling delta-based message retrieval without re-fetching history.
63
+
64
+ - **Idempotent sends**: Use `client_message_id` to make message sends idempotent for retry safety.
65
+
66
+ - **Per-session join**: Agents must call `topic_join()` before `sync()`. Join state is in-memory (`_joined_agent_names` dict in peer_server.py).
67
+
68
+ - **Presence tracking**: Derived from cursor `updated_at` timestamps - calling `sync()` updates presence.
69
+
70
+ ### Database Schema (v6)
71
+
72
+ Tables: `meta`, `topics`, `topic_seq`, `messages`, `cursors`
73
+
74
+ - Topics can be "open" or "closed"
75
+ - Messages have sequential `seq` numbers per topic
76
+ - Cursors track `(topic_id, agent_name, last_seq)`
77
+
78
+ ### Environment Variables
79
+
80
+ - `AGENT_BUS_DB`: SQLite path (default: `~/.agent_bus/agent_bus.sqlite`)
81
+ - `AGENT_BUS_MAX_SYNC_ITEMS`: Max messages per sync (default: 20)
82
+ - `AGENT_BUS_MAX_MESSAGE_CHARS`: Max message length (default: 65536)