openwealth-mcp 0.3.5__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 (71) hide show
  1. openwealth_mcp-0.3.5/.gitattributes +16 -0
  2. openwealth_mcp-0.3.5/.github/CODEOWNERS +2 -0
  3. openwealth_mcp-0.3.5/.github/dependabot.yml +18 -0
  4. openwealth_mcp-0.3.5/.github/workflows/ci.yml +61 -0
  5. openwealth_mcp-0.3.5/.github/workflows/publish.yml +96 -0
  6. openwealth_mcp-0.3.5/.github/workflows/release.yml +143 -0
  7. openwealth_mcp-0.3.5/.github/workflows/tag-release.yml +76 -0
  8. openwealth_mcp-0.3.5/.gitignore +18 -0
  9. openwealth_mcp-0.3.5/.pre-commit-config.yaml +19 -0
  10. openwealth_mcp-0.3.5/CHANGELOG.md +167 -0
  11. openwealth_mcp-0.3.5/CONTRIBUTING.md +105 -0
  12. openwealth_mcp-0.3.5/LICENSE +202 -0
  13. openwealth_mcp-0.3.5/PKG-INFO +368 -0
  14. openwealth_mcp-0.3.5/README.md +327 -0
  15. openwealth_mcp-0.3.5/SECURITY.md +42 -0
  16. openwealth_mcp-0.3.5/docs/local-dev.md +33 -0
  17. openwealth_mcp-0.3.5/docs/mcp-clients.md +144 -0
  18. openwealth_mcp-0.3.5/docs/release.md +164 -0
  19. openwealth_mcp-0.3.5/pyproject.toml +115 -0
  20. openwealth_mcp-0.3.5/specs/custodyAPI.yaml +1873 -0
  21. openwealth_mcp-0.3.5/specs/customerAPI.yaml +3526 -0
  22. openwealth_mcp-0.3.5/specs/tradingAPI.yaml +2215 -0
  23. openwealth_mcp-0.3.5/src/openwealth_mcp/__init__.py +3 -0
  24. openwealth_mcp-0.3.5/src/openwealth_mcp/__main__.py +4 -0
  25. openwealth_mcp-0.3.5/src/openwealth_mcp/_server_base.py +61 -0
  26. openwealth_mcp-0.3.5/src/openwealth_mcp/app.py +8 -0
  27. openwealth_mcp-0.3.5/src/openwealth_mcp/client.py +462 -0
  28. openwealth_mcp-0.3.5/src/openwealth_mcp/config.py +128 -0
  29. openwealth_mcp-0.3.5/src/openwealth_mcp/custody/__init__.py +3 -0
  30. openwealth_mcp-0.3.5/src/openwealth_mcp/custody/app.py +28 -0
  31. openwealth_mcp-0.3.5/src/openwealth_mcp/custody/server.py +78 -0
  32. openwealth_mcp-0.3.5/src/openwealth_mcp/custody/service.py +186 -0
  33. openwealth_mcp-0.3.5/src/openwealth_mcp/customer/__init__.py +1 -0
  34. openwealth_mcp-0.3.5/src/openwealth_mcp/customer/app.py +27 -0
  35. openwealth_mcp-0.3.5/src/openwealth_mcp/customer/server.py +80 -0
  36. openwealth_mcp-0.3.5/src/openwealth_mcp/customer/service.py +310 -0
  37. openwealth_mcp-0.3.5/src/openwealth_mcp/errors.py +94 -0
  38. openwealth_mcp-0.3.5/src/openwealth_mcp/logging_config.py +112 -0
  39. openwealth_mcp-0.3.5/src/openwealth_mcp/py.typed +0 -0
  40. openwealth_mcp-0.3.5/src/openwealth_mcp/resources/__init__.py +4 -0
  41. openwealth_mcp-0.3.5/src/openwealth_mcp/resources/_spec_path.py +23 -0
  42. openwealth_mcp-0.3.5/src/openwealth_mcp/resources/custody.py +60 -0
  43. openwealth_mcp-0.3.5/src/openwealth_mcp/resources/customer.py +83 -0
  44. openwealth_mcp-0.3.5/src/openwealth_mcp/resources/trading.py +72 -0
  45. openwealth_mcp-0.3.5/src/openwealth_mcp/server.py +8 -0
  46. openwealth_mcp-0.3.5/src/openwealth_mcp/service_app.py +74 -0
  47. openwealth_mcp-0.3.5/src/openwealth_mcp/tools/__init__.py +5 -0
  48. openwealth_mcp-0.3.5/src/openwealth_mcp/tools/custody.py +305 -0
  49. openwealth_mcp-0.3.5/src/openwealth_mcp/tools/customer.py +617 -0
  50. openwealth_mcp-0.3.5/src/openwealth_mcp/tools/trading.py +536 -0
  51. openwealth_mcp-0.3.5/src/openwealth_mcp/trading/__init__.py +5 -0
  52. openwealth_mcp-0.3.5/src/openwealth_mcp/trading/app.py +28 -0
  53. openwealth_mcp-0.3.5/src/openwealth_mcp/trading/server.py +79 -0
  54. openwealth_mcp-0.3.5/src/openwealth_mcp/trading/service.py +306 -0
  55. openwealth_mcp-0.3.5/src/openwealth_mcp/validation.py +32 -0
  56. openwealth_mcp-0.3.5/tests/conftest.py +34 -0
  57. openwealth_mcp-0.3.5/tests/test_client.py +122 -0
  58. openwealth_mcp-0.3.5/tests/test_config.py +160 -0
  59. openwealth_mcp-0.3.5/tests/test_custody_service.py +161 -0
  60. openwealth_mcp-0.3.5/tests/test_customer_service.py +423 -0
  61. openwealth_mcp-0.3.5/tests/test_entrypoints.py +205 -0
  62. openwealth_mcp-0.3.5/tests/test_errors.py +63 -0
  63. openwealth_mcp-0.3.5/tests/test_logging_config.py +51 -0
  64. openwealth_mcp-0.3.5/tests/test_resources_and_tools.py +212 -0
  65. openwealth_mcp-0.3.5/tests/test_settings_docs_sync.py +62 -0
  66. openwealth_mcp-0.3.5/tests/test_tools_custody.py +90 -0
  67. openwealth_mcp-0.3.5/tests/test_tools_customer.py +210 -0
  68. openwealth_mcp-0.3.5/tests/test_tools_trading.py +315 -0
  69. openwealth_mcp-0.3.5/tests/test_trading_service.py +439 -0
  70. openwealth_mcp-0.3.5/tests/test_validation.py +33 -0
  71. openwealth_mcp-0.3.5/uv.lock +2065 -0
@@ -0,0 +1,16 @@
1
+ # Normalise all text files to LF on commit; check out as LF everywhere.
2
+ * text=auto eol=lf
3
+
4
+ # Explicitly mark binary files so git never mangles them.
5
+ *.png binary
6
+ *.jpg binary
7
+ *.gif binary
8
+ *.ico binary
9
+ *.zip binary
10
+ *.gz binary
11
+ *.whl binary
12
+ *.pyc binary
13
+
14
+ # YAML spec files — keep as LF
15
+ *.yaml text eol=lf
16
+ *.yml text eol=lf
@@ -0,0 +1,2 @@
1
+ # Default owners for all files in the repository.
2
+ * @synpulse-openwealth
@@ -0,0 +1,18 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 5
8
+ labels:
9
+ - "dependencies"
10
+
11
+ - package-ecosystem: "github-actions"
12
+ directory: "/"
13
+ schedule:
14
+ interval: "weekly"
15
+ open-pull-requests-limit: 5
16
+ labels:
17
+ - "dependencies"
18
+ - "github-actions"
@@ -0,0 +1,61 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master, main, "feature/**"]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ quality:
13
+ name: Quality (${{ matrix.python-version }})
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ python-version: ["3.11", "3.12", "3.13"]
19
+
20
+ steps:
21
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
25
+ with:
26
+ enable-cache: true
27
+
28
+ - name: Set up Python ${{ matrix.python-version }}
29
+ run: uv python install ${{ matrix.python-version }}
30
+
31
+ - name: Install dependencies
32
+ run: uv sync --frozen --extra dev
33
+
34
+ - name: Lint (ruff check)
35
+ run: uv run ruff check src tests
36
+
37
+ - name: Format check (ruff format)
38
+ run: uv run ruff format --check src tests
39
+
40
+ - name: Type check (mypy)
41
+ run: uv run mypy
42
+
43
+ - name: Tests (pytest + coverage)
44
+ run: uv run pytest -q
45
+
46
+ audit:
47
+ name: Dependency audit
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
51
+
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
54
+ with:
55
+ enable-cache: true
56
+
57
+ - name: Set up Python
58
+ run: uv python install 3.13
59
+
60
+ - name: Run pip-audit
61
+ run: uv run --with pip-audit pip-audit --requirement <(uv export --no-dev --no-hashes)
@@ -0,0 +1,96 @@
1
+ name: Publish to PyPI
2
+
3
+ # Triggered in two ways:
4
+ #
5
+ # 1. workflow_dispatch on a tag ref — called automatically by tag-release.yml
6
+ # after the release PR merges (GITHUB_TOKEN cannot trigger push events,
7
+ # but CAN trigger workflow_dispatch via the REST API).
8
+ #
9
+ # 2. push: tags v* — for manual tag pushes:
10
+ # git tag vX.Y.Z && git push origin vX.Y.Z
11
+ #
12
+ # Pipeline: build → publish-testpypi → publish-pypi
13
+ on:
14
+ workflow_dispatch:
15
+ push:
16
+ tags:
17
+ - "v*"
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ jobs:
23
+ # ── Job 1: build wheel + sdist ─────────────────────────────────────────────
24
+ build:
25
+ name: Build distribution
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
32
+ with:
33
+ enable-cache: true
34
+
35
+ - name: Set up Python
36
+ run: uv python install 3.13
37
+
38
+ - name: Verify tag matches package version
39
+ run: |
40
+ TAG="${GITHUB_REF_NAME}"
41
+ PKG_VERSION="v$(uv run python -c "import importlib.metadata; print(importlib.metadata.version('openwealth-mcp'))")"
42
+ echo "Tag: $TAG Package version: $PKG_VERSION"
43
+ if [ "$TAG" != "$PKG_VERSION" ]; then
44
+ echo "ERROR: tag $TAG does not match package version $PKG_VERSION"
45
+ exit 1
46
+ fi
47
+
48
+ - name: Build wheel and sdist
49
+ run: uv build
50
+
51
+ - name: Check distributions
52
+ run: uv run --with twine twine check dist/*
53
+
54
+ - name: Upload distributions as artifact
55
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
56
+ with:
57
+ name: dist
58
+ path: dist/
59
+
60
+ # ── Job 2: publish to TestPyPI ─────────────────────────────────────────────
61
+ publish-testpypi:
62
+ name: Publish to TestPyPI
63
+ needs: build
64
+ runs-on: ubuntu-latest
65
+ environment: testpypi
66
+ permissions:
67
+ id-token: write
68
+ steps:
69
+ - name: Download distributions
70
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
71
+ with:
72
+ name: dist
73
+ path: dist/
74
+
75
+ - name: Publish to TestPyPI
76
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
77
+ with:
78
+ repository-url: https://test.pypi.org/legacy/
79
+
80
+ # ── Job 3: publish to PyPI ──────────────────────────────────────────────────
81
+ publish-pypi:
82
+ name: Publish to PyPI
83
+ needs: publish-testpypi
84
+ runs-on: ubuntu-latest
85
+ environment: pypi
86
+ permissions:
87
+ id-token: write
88
+ steps:
89
+ - name: Download distributions
90
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
91
+ with:
92
+ name: dist
93
+ path: dist/
94
+
95
+ - name: Publish to PyPI
96
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -0,0 +1,143 @@
1
+ name: Create Release PR
2
+
3
+ # Bumps the version, updates CHANGELOG.md, and opens a PR against main.
4
+ # No tag is created here — the tag is created automatically by tag-release.yml
5
+ # once this PR is merged into main.
6
+ #
7
+ # Usage:
8
+ # GitHub UI: Actions → "Create Release PR" → Run workflow → choose bump / version
9
+ # CLI: gh workflow run release.yml --field bump=minor
10
+ # gh workflow run release.yml --field version=1.0.0
11
+ on:
12
+ workflow_dispatch:
13
+ inputs:
14
+ bump:
15
+ description: "Version bump type (ignored when 'version' is set)"
16
+ required: false
17
+ default: patch
18
+ type: choice
19
+ options: [patch, minor, major]
20
+ version:
21
+ description: "Exact version to release, e.g. 1.0.0 (overrides 'bump')"
22
+ required: false
23
+ type: string
24
+
25
+ permissions:
26
+ contents: read
27
+
28
+ jobs:
29
+ bump-pr:
30
+ name: Bump version & open PR
31
+ runs-on: ubuntu-latest
32
+ permissions:
33
+ contents: write
34
+ pull-requests: write
35
+ steps:
36
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
37
+ with:
38
+ fetch-depth: 0
39
+ token: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
43
+ with:
44
+ enable-cache: true
45
+
46
+ - name: Set up Python
47
+ run: uv python install 3.13
48
+
49
+ - name: Install package to read current version
50
+ run: uv sync --frozen
51
+
52
+ - name: Compute new version
53
+ id: bump
54
+ run: |
55
+ # Read current version and strip pre-release suffixes (e.g. "0.3.0b1" → "0.3.0")
56
+ CURRENT=$(uv run python -c "import importlib.metadata; print(importlib.metadata.version('openwealth-mcp'))")
57
+ BASE=$(echo "$CURRENT" | grep -oP '^\d+\.\d+\.\d+')
58
+ MAJOR=$(echo "$BASE" | cut -d. -f1)
59
+ MINOR=$(echo "$BASE" | cut -d. -f2)
60
+ PATCH=$(echo "$BASE" | cut -d. -f3)
61
+
62
+ EXPLICIT="${{ inputs.version }}"
63
+ BUMP_TYPE="${{ inputs.bump }}"
64
+
65
+ if [ -n "$EXPLICIT" ]; then
66
+ NEW_VER="$EXPLICIT"
67
+ elif [ "$BUMP_TYPE" = "major" ]; then
68
+ NEW_VER="$((MAJOR+1)).0.0"
69
+ elif [ "$BUMP_TYPE" = "minor" ]; then
70
+ NEW_VER="${MAJOR}.$((MINOR+1)).0"
71
+ else
72
+ NEW_VER="${MAJOR}.${MINOR}.$((PATCH+1))"
73
+ fi
74
+
75
+ echo "Bumping ${CURRENT} → ${NEW_VER}"
76
+ echo "new_version=${NEW_VER}" >> "$GITHUB_OUTPUT"
77
+
78
+ - name: Create release branch and bump files
79
+ id: branch
80
+ run: |
81
+ NEW_VER="${{ steps.bump.outputs.new_version }}"
82
+ BRANCH="release/v${NEW_VER}"
83
+ echo "name=${BRANCH}" >> "$GITHUB_OUTPUT"
84
+
85
+ git config user.name "github-actions[bot]"
86
+ git config user.email "github-actions[bot]@users.noreply.github.com"
87
+ git checkout -b "$BRANCH"
88
+
89
+ # Bump __version__ (single source of truth)
90
+ sed -i "s/__version__ = \".*\"/__version__ = \"${NEW_VER}\"/" \
91
+ src/openwealth_mcp/__init__.py
92
+
93
+ # Promote [Unreleased] → [x.y.z] in CHANGELOG
94
+ TODAY=$(date +%Y-%m-%d)
95
+ sed -i "s/## \[Unreleased\]/## [${NEW_VER}] — ${TODAY}/" CHANGELOG.md
96
+
97
+ # Insert a fresh [Unreleased] section above the new release header
98
+ LINE=$(grep -n "## \[${NEW_VER}\]" CHANGELOG.md | cut -d: -f1)
99
+ sed -i "${LINE}i ## [Unreleased]\n\n---\n" CHANGELOG.md
100
+
101
+ # Update [Unreleased] diff link at the bottom
102
+ PREV_TAG=$(git describe --tags --abbrev=0 HEAD 2>/dev/null || echo "")
103
+ REPO_URL=$(git remote get-url origin | sed 's/\.git$//')
104
+ if [ -n "$PREV_TAG" ] && grep -q "^\[Unreleased\]:" CHANGELOG.md; then
105
+ sed -i "s|^\[Unreleased\]:.*|\[Unreleased\]: ${REPO_URL}/compare/v${NEW_VER}...HEAD|" CHANGELOG.md
106
+ sed -i "/^\[Unreleased\]:/a [${NEW_VER}]: ${REPO_URL}/compare/${PREV_TAG}...v${NEW_VER}" CHANGELOG.md
107
+ fi
108
+
109
+ git add src/openwealth_mcp/__init__.py CHANGELOG.md
110
+ git commit -m "chore: release v${NEW_VER}"
111
+
112
+ git push origin "$BRANCH"
113
+
114
+ - name: Open PR against main
115
+ env:
116
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
117
+ run: |
118
+ NEW_VER="${{ steps.bump.outputs.new_version }}"
119
+ BRANCH="${{ steps.branch.outputs.name }}"
120
+
121
+ PR_URL=$(gh pr create \
122
+ --title "chore: release v${NEW_VER}" \
123
+ --body "## Release v${NEW_VER}
124
+
125
+ Automated version bump — review the diff, then **merge to trigger the publish pipeline**.
126
+
127
+ ### What happens after merge
128
+ 1. \`tag-release.yml\` detects the \`chore: release v${NEW_VER}\` commit on \`main\`
129
+ 2. Creates and pushes tag \`v${NEW_VER}\` pointing to the merge commit
130
+ 3. \`publish.yml\` fires on the tag → builds wheel/sdist → publishes to TestPyPI then PyPI
131
+
132
+ ### Changes
133
+ - \`src/openwealth_mcp/__init__.py\` — version bumped to \`${NEW_VER}\`
134
+ - \`CHANGELOG.md\` — \`[Unreleased]\` promoted to \`[${NEW_VER}]\`" \
135
+ --base main \
136
+ --head "$BRANCH")
137
+
138
+ echo "PR opened: $PR_URL"
139
+
140
+ # Enable auto-merge so the PR merges automatically once required checks pass.
141
+ # If branch protection requires human review, the PR stays open for manual merge.
142
+ gh pr merge "$PR_URL" --squash --auto || \
143
+ echo "::notice::Auto-merge not available (branch protection requires review). Merge the PR manually."
@@ -0,0 +1,76 @@
1
+ name: Tag Release
2
+
3
+ # Fires on every push to main. When the HEAD commit message starts with
4
+ # "chore: release v", extracts the version and creates the matching tag.
5
+ #
6
+ # This is the bridge between the release PR merge and the publish pipeline:
7
+ #
8
+ # release.yml → PR "chore: release vX.Y.Z" → merge to main
9
+ # │
10
+ # [this workflow]
11
+ # creates tag vX.Y.Z
12
+ # │
13
+ # publish.yml fires
14
+ on:
15
+ push:
16
+ branches: [main]
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ tag:
23
+ name: Create release tag
24
+ # Only run when the commit is a release bump (chore: release vX.Y.Z)
25
+ if: "startsWith(github.event.head_commit.message, 'chore: release v')"
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ contents: write # push tag
29
+ actions: write # gh workflow run (dispatch publish.yml via REST API)
30
+ steps:
31
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
32
+ with:
33
+ token: ${{ secrets.GITHUB_TOKEN }}
34
+
35
+ - name: Extract version from commit message
36
+ id: version
37
+ run: |
38
+ MSG="${{ github.event.head_commit.message }}"
39
+ # Extract "vX.Y.Z" from "chore: release vX.Y.Z" (ignores PR number suffix)
40
+ TAG=$(echo "$MSG" | grep -oP 'v\d+\.\d+\.\d+' | head -1)
41
+ if [ -z "$TAG" ]; then
42
+ echo "ERROR: could not parse version from commit message: $MSG"
43
+ exit 1
44
+ fi
45
+ echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
46
+ echo "Detected release tag: ${TAG}"
47
+
48
+ - name: Check tag does not already exist
49
+ run: |
50
+ TAG="${{ steps.version.outputs.tag }}"
51
+ if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then
52
+ echo "::warning::Tag ${TAG} already exists — skipping."
53
+ exit 0
54
+ fi
55
+
56
+ - name: Create and push tag
57
+ env:
58
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59
+ run: |
60
+ TAG="${{ steps.version.outputs.tag }}"
61
+ git config user.name "github-actions[bot]"
62
+ git config user.email "github-actions[bot]@users.noreply.github.com"
63
+ git tag "$TAG"
64
+ git push origin "$TAG"
65
+ echo "::notice::Tag ${TAG} pushed."
66
+
67
+ - name: Trigger publish workflow
68
+ # GITHUB_TOKEN cannot trigger push-based workflow runs (security restriction).
69
+ # Using `gh workflow run` (REST API call) bypasses this: API-triggered
70
+ # workflow_dispatch events always fire regardless of who created them.
71
+ env:
72
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73
+ run: |
74
+ TAG="${{ steps.version.outputs.tag }}"
75
+ gh workflow run publish.yml --ref "$TAG"
76
+ echo "::notice::publish.yml triggered for ${TAG}."
@@ -0,0 +1,18 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .coverage
9
+ htmlcov/
10
+ dist/
11
+ build/
12
+ .env
13
+ logs/
14
+ .cursor/mcp.json
15
+ .mcp.json
16
+ .tmp_*.py
17
+ _customers_dump.json
18
+
@@ -0,0 +1,19 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.9.10
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v1.15.0
11
+ hooks:
12
+ - id: mypy
13
+ additional_dependencies:
14
+ - pydantic>=2
15
+ - pydantic-settings>=2
16
+ - httpx>=0.27
17
+ - types-PyYAML>=6
18
+ args: [--config-file=pyproject.toml]
19
+ pass_filenames: false
@@ -0,0 +1,167 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ ---
13
+
14
+ ## [0.3.5] — 2026-09-04
15
+
16
+ ---
17
+
18
+ ## [0.3.4] — 2026-09-04
19
+
20
+ ---
21
+
22
+ ## [0.3.3] — 2026-09-03
23
+
24
+ ---
25
+
26
+ ## [0.3.2] — 2026-09-03
27
+
28
+ ---
29
+
30
+ ## [0.3.1] — 2026-09-03
31
+
32
+ ### Added
33
+
34
+ - **`openwealth-customer-mcp`** — new MCP server for the OpenWealth Customer
35
+ Management API v2.0.6 with **26 tools** covering the full customer onboarding
36
+ and lifecycle: customers, persons, contacts, addresses, documents, KYC, and
37
+ prospect pre-checks (GET + POST + PUT + DELETE).
38
+ - **`OPENWEALTH_CUSTOMER_MANAGEMENT_BASE_URL`** — new env variable for the
39
+ Customer Management server base URL.
40
+ - **`specs/customerAPI.yaml`** — vendored OpenAPI YAML for Customer Management
41
+ v2.0.6, served as `openwealth://specs/customer` and
42
+ `openwealth://specs/customer.yaml` MCP resources.
43
+
44
+ ---
45
+
46
+ ## [0.3.0] — 2026-09-02
47
+
48
+ ### Added
49
+
50
+ - **`OPENWEALTH_CUSTODY_BASE_URL`** and **`OPENWEALTH_TRADING_BASE_URL`** — each
51
+ MCP server now has its own base URL variable. A single `.env` file can hold
52
+ both. The URL for each server is resolved at startup via
53
+ `Settings.base_url_for(service)`, printing a clear error and exiting with
54
+ code 1 if the required variable is unset.
55
+
56
+ ### Changed
57
+
58
+ - **BREAKING: `OPENWEALTH_BASE_URL` removed.** Replace it with
59
+ `OPENWEALTH_CUSTODY_BASE_URL` (for the Custody server) and/or
60
+ `OPENWEALTH_TRADING_BASE_URL` (for the Trading server) in your `.env` file
61
+ and MCP client configuration (`claude_desktop_config.json`, `.cursor/mcp.json`).
62
+ - `OpenWealthHttpClient` now requires an explicit `base_url` keyword argument
63
+ (previously read from `settings.base_url`).
64
+
65
+ ### Removed
66
+
67
+ - **LLM wiki layer** (`wiki/`, `raw/`, `AGENTS.md`, `.cursor/rules/llm-wiki.mdc`)
68
+ replaced by three plain Markdown pages under `docs/` (`mcp-clients.md`,
69
+ `local-dev.md`, `release.md`). The wiki was an agent-maintained knowledge base
70
+ that added 30 files to the repo with no value for package consumers.
71
+ - **Stale Docker runbook** (`wiki/runbooks/docker-cursor-mcp.md`) which documented
72
+ a `Dockerfile` removed in v0.2.0 and the old package name `openwealth_ai_mcp`.
73
+
74
+ ---
75
+
76
+ ## [0.2.0] — 2026-09-02
77
+
78
+ ### Added
79
+
80
+ - **Trading MCP server** (`openwealth-trading-mcp`) with 18 tools covering the
81
+ full Order Placement API v3.0.1 lifecycle: customers, accounts, orders,
82
+ executions, states, quotes, and event subscriptions.
83
+ - **`--check` flag** on both server entry points: validates settings and prints
84
+ a one-line status without starting the stdio loop. Useful for deployment
85
+ smoke tests.
86
+ - **`Retry-After` header support** in the HTTP client with ±20% jitter, so
87
+ retries respect server-side rate-limit signals instead of always using
88
+ exponential backoff.
89
+ - **Symmetric input validation** for Trading tools: `validate_id` on list-orders
90
+ filter params, `validate_date` on `settlement_date` in `create_order`, and
91
+ presence checks on every `allocations` entry.
92
+ - **`py.typed` marker** — the package now ships inline type information for
93
+ downstream `mypy --strict` users.
94
+ - **`test_settings_docs_sync`** — asserts that the README config table and
95
+ `Settings` field list are identical, so documentation can no longer silently
96
+ diverge from code.
97
+ - **`test_spec_contract`** — parametrised contract test that verifies every
98
+ `operationId` and path used by `CustodyService` and `TradingService` against
99
+ the vendored OpenAPI specs.
100
+ - **`test_entrypoints`** — smoke tests for `main()` and `--check` on both
101
+ servers, with `server.run` monkeypatched.
102
+ - **CI matrix** across Python 3.11, 3.12, and 3.13 (previously 3.13 only).
103
+ - **`pip-audit` job** in CI for supply-chain scanning.
104
+ - **Dependabot** configuration for pip and GitHub Actions weekly updates.
105
+ - **GitHub Actions pinned by commit SHA** to harden the supply chain.
106
+ - `CONTRIBUTING.md` and `CODE_OF_CONDUCT.md` links.
107
+
108
+ ### Changed
109
+
110
+ - **Package renamed** from `openwealth-ai-mcp` / `openwealth_ai_mcp` to
111
+ `openwealth-mcp` / `openwealth_mcp`. This is a **breaking change** for any
112
+ existing import. Console scripts (`openwealth-custody-mcp`,
113
+ `openwealth-trading-mcp`) are unchanged.
114
+ - **Single version source**: `__version__` in `src/openwealth_mcp/__init__.py`
115
+ is the only declaration; `pyproject.toml` reads it dynamically via Hatch.
116
+ Bumping one file bumps both.
117
+ - **License metadata** updated to PEP 639 form (`license = "Apache-2.0"`).
118
+ - **Package metadata** enriched with `authors`, `keywords`, `classifiers`
119
+ (Python 3.11/3.12/3.13, Development Status :: 4 - Beta, Typing :: Typed),
120
+ and `[project.urls]` (Homepage, Repository, Issues, Changelog).
121
+ - **`publish.yml`** tag trigger re-enabled (`push: tags: v*`); version check
122
+ made conditional on tag context so manual dispatch no longer fails.
123
+ - **Coverage gate** raised from 80% to 84% to match the achieved baseline.
124
+ - **`OPENWEALTH_LOG_FILE` description** in README no longer says "Recommended
125
+ with Docker" (Docker support removed).
126
+
127
+ ### Removed
128
+
129
+ - **Docker support** (`Dockerfile`, `docker-compose.yml`, `.dockerignore`).
130
+ The servers are distributed as a pip-installable library; Docker was an
131
+ optional deployment target that added maintenance cost without proportional
132
+ value for the current user base.
133
+ - **`openwealth-mcp` console script alias** (was a duplicate of
134
+ `openwealth-custody-mcp` and ambiguous with two servers present).
135
+ - **`IMPROVEMENT-PLAN.md`** from the repository root (absorbed into
136
+ `CHANGELOG.md` and GitHub issues).
137
+ - **Junk files** (`.coverage`, `_customers_dump.json`, `.tmp_*.py`, `logs/`)
138
+ from the working tree; `.gitattributes` added to enforce LF line endings.
139
+
140
+ ### Fixed
141
+
142
+ - **`mypy` strict failures** in `tools/trading.py`: `invoke_tool` now takes
143
+ `Awaitable[str]` instead of `Any`, matching the custody implementation.
144
+ - **README config table** was documenting eight env vars that no longer exist
145
+ in `Settings` (`OPENWEALTH_ENV`, `OPENWEALTH_TRANSPORT`, etc.) and had the
146
+ wrong default for `OPENWEALTH_TIMEOUT_SECONDS` (30 vs 120 in code).
147
+ - **Unused dead code** removed: `TypeVar("_T")` in `tools/custody.py`,
148
+ `peek_client()` in both `app.py` files.
149
+
150
+ ---
151
+
152
+ ## [0.1.0] — 2026-08-10
153
+
154
+ Initial release of the Custody MCP server.
155
+
156
+ - 10 read-only GET tools covering Custody Services API v3.2.0.
157
+ - FastMCP over stdio with clean `tools → service → HTTP client` layering.
158
+ - Pydantic-validated settings; structured JSON error envelopes.
159
+ - Vendored OpenAPI spec served as MCP resource.
160
+
161
+ [Unreleased]: https://github.com/OpenWealth/OpenWealth-MCP/compare/v0.3.5...HEAD
162
+ [0.3.5]: https://github.com/OpenWealth/OpenWealth-MCP/compare/v0.3.3...v0.3.5
163
+ [0.3.4]: https://github.com/OpenWealth/OpenWealth-MCP/compare/v0.3.3...v0.3.4
164
+ [0.3.3]: https://github.com/OpenWealth/OpenWealth-MCP/compare/v0.3.2...v0.3.3
165
+ [0.3.0]: https://github.com/synpulse-openwealth/openwealth-mcp/compare/v0.2.0...v0.3.0
166
+ [0.2.0]: https://github.com/synpulse-openwealth/openwealth-mcp/compare/v0.1.0...v0.2.0
167
+ [0.1.0]: https://github.com/synpulse-openwealth/openwealth-mcp/releases/tag/v0.1.0