mcp-server-appwrite 0.4__tar.gz → 0.7.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.
- mcp_server_appwrite-0.7.0/.dockerignore +12 -0
- mcp_server_appwrite-0.7.0/.env.example +27 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.github/workflows/ci.yml +32 -11
- mcp_server_appwrite-0.7.0/.github/workflows/production.yml +88 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.github/workflows/publish.yml +3 -3
- mcp_server_appwrite-0.7.0/.github/workflows/staging.yml +89 -0
- mcp_server_appwrite-0.7.0/AGENTS.md +140 -0
- mcp_server_appwrite-0.7.0/CLAUDE.md +1 -0
- mcp_server_appwrite-0.7.0/Dockerfile +23 -0
- mcp_server_appwrite-0.7.0/PKG-INFO +179 -0
- mcp_server_appwrite-0.7.0/README.md +156 -0
- mcp_server_appwrite-0.7.0/compose.yaml +29 -0
- mcp_server_appwrite-0.7.0/docs/authentication.md +39 -0
- mcp_server_appwrite-0.7.0/docs/development.md +74 -0
- mcp_server_appwrite-0.7.0/docs/documentation-search.md +36 -0
- mcp_server_appwrite-0.7.0/docs/self-hosted.md +176 -0
- mcp_server_appwrite-0.7.0/docs/tool-surface.md +49 -0
- mcp_server_appwrite-0.7.0/pyproject.toml +58 -0
- mcp_server_appwrite-0.7.0/scripts/build_docs_index.py +219 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/server.json +10 -4
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/__init__.py +8 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/auth.py +284 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/context.py +339 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/data/docs_index.npz +0 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/data/docs_index_meta.json +1 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/docs_search.py +210 -0
- mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/http_app.py +194 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/operator.py +96 -6
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/server.py +339 -54
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/service.py +7 -3
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/tool_manager.py +3 -1
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/support.py +30 -4
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_functions.py +0 -1
- mcp_server_appwrite-0.7.0/tests/integration/test_oauth_discovery.py +65 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_operator.py +1 -1
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_sites.py +0 -1
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_storage.py +0 -1
- mcp_server_appwrite-0.7.0/tests/unit/test_auth.py +220 -0
- mcp_server_appwrite-0.7.0/tests/unit/test_context.py +191 -0
- mcp_server_appwrite-0.7.0/tests/unit/test_docs_search.py +126 -0
- mcp_server_appwrite-0.7.0/tests/unit/test_http_app.py +41 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_operator.py +106 -7
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_server.py +118 -12
- mcp_server_appwrite-0.7.0/uv.lock +1569 -0
- mcp_server_appwrite-0.4/.env.example +0 -3
- mcp_server_appwrite-0.4/PKG-INFO +0 -296
- mcp_server_appwrite-0.4/README.md +0 -279
- mcp_server_appwrite-0.4/images/appwrite-logo-darkbg.png +0 -0
- mcp_server_appwrite-0.4/images/appwrite-logo-lightbg.png +0 -0
- mcp_server_appwrite-0.4/images/claude-desktop-integration.png +0 -0
- mcp_server_appwrite-0.4/images/cursor-integration.png +0 -0
- mcp_server_appwrite-0.4/images/vs-code-integration.png +0 -0
- mcp_server_appwrite-0.4/images/windsurf-integration.png +0 -0
- mcp_server_appwrite-0.4/pyproject.toml +0 -35
- mcp_server_appwrite-0.4/src/mcp_server_appwrite/__init__.py +0 -16
- mcp_server_appwrite-0.4/uv.lock +0 -769
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.gitignore +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.python-version +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/LICENSE +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/__main__.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_avatars.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_locale.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_messaging.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_tables_db.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_teams.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_users.py +0 -0
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/test_all.py +1 -1
- {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_service.py +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Appwrite Cloud base endpoint. The served project's OAuth authorization server
|
|
2
|
+
# lives under it at <APPWRITE_ENDPOINT>/oauth2/<APPWRITE_PROJECT_ID>.
|
|
3
|
+
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
|
|
4
|
+
|
|
5
|
+
# External URL clients use to reach THIS MCP server. Used to build the canonical
|
|
6
|
+
# resource URI (<MCP_PUBLIC_URL>/mcp) and RFC 9728 metadata. For hosted
|
|
7
|
+
# deployment, set this to your public HTTPS origin, for example
|
|
8
|
+
# https://mcp.appwrite.io.
|
|
9
|
+
MCP_PUBLIC_URL=http://localhost:8000
|
|
10
|
+
|
|
11
|
+
# The single Appwrite project this MCP serves. Defaults to the Cloud console
|
|
12
|
+
# project; override only for non-console deployments. Tokens issued by any other
|
|
13
|
+
# project's OAuth server are rejected.
|
|
14
|
+
# APPWRITE_PROJECT_ID=console
|
|
15
|
+
|
|
16
|
+
# HTTP bind address.
|
|
17
|
+
HOST=0.0.0.0
|
|
18
|
+
PORT=8000
|
|
19
|
+
|
|
20
|
+
# Optional. Enables appwrite_search_docs by embedding incoming docs queries.
|
|
21
|
+
# OPENAI_API_KEY=sk-...
|
|
22
|
+
|
|
23
|
+
# ── Integration tests only (not used by the running server) ─────────────────
|
|
24
|
+
# The live integration suite authenticates to the Appwrite API with an API key
|
|
25
|
+
# and runs against APPWRITE_PROJECT_ID (above).
|
|
26
|
+
# APPWRITE_PROJECT_ID=your-project-id
|
|
27
|
+
# APPWRITE_API_KEY=your-api-key
|
|
@@ -3,26 +3,33 @@ name: CI
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
5
5
|
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
6
8
|
|
|
7
9
|
jobs:
|
|
8
|
-
|
|
9
|
-
name:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint & format
|
|
10
12
|
runs-on: ubuntu-latest
|
|
11
13
|
steps:
|
|
12
14
|
- name: Check out code
|
|
13
|
-
uses: actions/checkout@v4
|
|
15
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
14
16
|
|
|
15
17
|
- name: Set up Python
|
|
16
|
-
uses: actions/setup-python@v5
|
|
18
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
17
19
|
with:
|
|
18
20
|
python-version: "3.12"
|
|
19
21
|
|
|
20
22
|
- name: Set up uv
|
|
21
|
-
uses: astral-sh/setup-uv@v7
|
|
23
|
+
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
24
|
+
with:
|
|
25
|
+
version: "0.11.22"
|
|
22
26
|
|
|
23
27
|
- name: Install dev dependencies
|
|
24
28
|
run: uv sync --group dev
|
|
25
29
|
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: uv run --group dev ruff check src tests
|
|
32
|
+
|
|
26
33
|
- name: Check formatting
|
|
27
34
|
run: uv run --group dev black --check src tests
|
|
28
35
|
|
|
@@ -31,15 +38,17 @@ jobs:
|
|
|
31
38
|
runs-on: ubuntu-latest
|
|
32
39
|
steps:
|
|
33
40
|
- name: Check out code
|
|
34
|
-
uses: actions/checkout@v4
|
|
41
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
35
42
|
|
|
36
43
|
- name: Set up Python
|
|
37
|
-
uses: actions/setup-python@v5
|
|
44
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
38
45
|
with:
|
|
39
46
|
python-version: "3.12"
|
|
40
47
|
|
|
41
48
|
- name: Set up uv
|
|
42
|
-
uses: astral-sh/setup-uv@v7
|
|
49
|
+
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
50
|
+
with:
|
|
51
|
+
version: "0.11.22"
|
|
43
52
|
|
|
44
53
|
- name: Install dependencies
|
|
45
54
|
run: uv sync
|
|
@@ -47,6 +56,16 @@ jobs:
|
|
|
47
56
|
- name: Run unit tests
|
|
48
57
|
run: uv run python -m unittest discover -s tests/unit -v
|
|
49
58
|
|
|
59
|
+
docker:
|
|
60
|
+
name: Docker build
|
|
61
|
+
runs-on: ubuntu-latest
|
|
62
|
+
steps:
|
|
63
|
+
- name: Check out code
|
|
64
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
65
|
+
|
|
66
|
+
- name: Build hosted HTTP image
|
|
67
|
+
run: docker build -t appwrite-mcp:ci .
|
|
68
|
+
|
|
50
69
|
integration:
|
|
51
70
|
name: Integration
|
|
52
71
|
runs-on: ubuntu-latest
|
|
@@ -57,15 +76,17 @@ jobs:
|
|
|
57
76
|
APPWRITE_ENDPOINT: ${{ secrets.APPWRITE_ENDPOINT }}
|
|
58
77
|
steps:
|
|
59
78
|
- name: Check out code
|
|
60
|
-
uses: actions/checkout@v4
|
|
79
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
61
80
|
|
|
62
81
|
- name: Set up Python
|
|
63
|
-
uses: actions/setup-python@v5
|
|
82
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
64
83
|
with:
|
|
65
84
|
python-version: "3.12"
|
|
66
85
|
|
|
67
86
|
- name: Set up uv
|
|
68
|
-
uses: astral-sh/setup-uv@v7
|
|
87
|
+
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
|
88
|
+
with:
|
|
89
|
+
version: "0.11.22"
|
|
69
90
|
|
|
70
91
|
- name: Install dependencies
|
|
71
92
|
run: uv sync --extra integration
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: Production deployment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}
|
|
10
|
+
cancel-in-progress: false
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
packages: write
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
ENVIRONMENT: production
|
|
18
|
+
PROJECT: mcp
|
|
19
|
+
DECLARATIVE_OWNER: appwrite-labs
|
|
20
|
+
DECLARATIVE_REPOSITORY: assets-applications
|
|
21
|
+
REGISTRY_GITHUB: ghcr.io
|
|
22
|
+
REGISTRY_DOCKERHUB: docker.io
|
|
23
|
+
IMAGE_NAME: appwrite/mcp
|
|
24
|
+
TAG: ${{ github.event.release.tag_name || github.sha }}
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout the repo
|
|
31
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
32
|
+
|
|
33
|
+
- name: Login to GitHub Container Registry
|
|
34
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
|
35
|
+
with:
|
|
36
|
+
registry: ${{ env.REGISTRY_GITHUB }}
|
|
37
|
+
username: ${{ github.actor }}
|
|
38
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
|
|
40
|
+
- name: Login to Docker Hub
|
|
41
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
|
42
|
+
with:
|
|
43
|
+
registry: ${{ env.REGISTRY_DOCKERHUB }}
|
|
44
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
45
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
46
|
+
|
|
47
|
+
- name: Build and push
|
|
48
|
+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
|
49
|
+
with:
|
|
50
|
+
context: .
|
|
51
|
+
push: true
|
|
52
|
+
tags: |
|
|
53
|
+
${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}
|
|
54
|
+
${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}
|
|
55
|
+
|
|
56
|
+
deploy:
|
|
57
|
+
needs: build
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
steps:
|
|
60
|
+
- name: Get token for ${{ env.DECLARATIVE_REPOSITORY }}
|
|
61
|
+
id: app-token
|
|
62
|
+
uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2
|
|
63
|
+
with:
|
|
64
|
+
app-id: ${{ vars.DECLARATIVE_DEPLOYMENT_GITHUB_APP_ID }}
|
|
65
|
+
private-key: ${{ secrets.DECLARATIVE_DEPLOYMENT_GITHUB_APP_PRIVATE_KEY }}
|
|
66
|
+
owner: ${{ env.DECLARATIVE_OWNER }}
|
|
67
|
+
repositories: ${{ env.DECLARATIVE_REPOSITORY }}
|
|
68
|
+
|
|
69
|
+
- name: Checkout ${{ env.DECLARATIVE_REPOSITORY }}
|
|
70
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
71
|
+
with:
|
|
72
|
+
repository: ${{ env.DECLARATIVE_OWNER }}/${{ env.DECLARATIVE_REPOSITORY }}
|
|
73
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
74
|
+
|
|
75
|
+
- name: Update image tag
|
|
76
|
+
run: yq -i '.["mcp"].image.tag = strenv(TAG)' ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/fra1.yaml
|
|
77
|
+
|
|
78
|
+
- name: Commit and push
|
|
79
|
+
run: |
|
|
80
|
+
git config user.name "github-actions[bot]"
|
|
81
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
82
|
+
git add ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/fra1.yaml
|
|
83
|
+
if git diff --cached --quiet; then
|
|
84
|
+
echo "No changes to commit"
|
|
85
|
+
else
|
|
86
|
+
git commit -m "chore(${{ env.ENVIRONMENT }}): ${{ env.PROJECT }} image tag to ${{ env.TAG }}"
|
|
87
|
+
git push
|
|
88
|
+
fi
|
|
@@ -10,17 +10,17 @@ jobs:
|
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
12
|
- name: Check out code
|
|
13
|
-
uses: actions/checkout@v4
|
|
13
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
14
14
|
|
|
15
15
|
- name: Set up Python
|
|
16
|
-
uses: actions/setup-python@v5
|
|
16
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
17
17
|
with:
|
|
18
18
|
python-version: "3.12"
|
|
19
19
|
|
|
20
20
|
- name: Install build dependencies
|
|
21
21
|
run: |
|
|
22
22
|
python -m pip install --upgrade pip
|
|
23
|
-
pip install build twine
|
|
23
|
+
pip install build==1.5.0 twine==6.2.0
|
|
24
24
|
|
|
25
25
|
- name: Build package
|
|
26
26
|
run: python -m build
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
name: Staging deployment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
packages: write
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
ENVIRONMENT: staging
|
|
19
|
+
PROJECT: mcp
|
|
20
|
+
DECLARATIVE_OWNER: appwrite-labs
|
|
21
|
+
DECLARATIVE_REPOSITORY: assets-applications
|
|
22
|
+
REGISTRY_GITHUB: ghcr.io
|
|
23
|
+
REGISTRY_DOCKERHUB: docker.io
|
|
24
|
+
IMAGE_NAME: appwrite/mcp
|
|
25
|
+
TAG: ${{ github.sha }}
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
build:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout the repo
|
|
32
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
33
|
+
|
|
34
|
+
- name: Login to GitHub Container Registry
|
|
35
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
|
36
|
+
with:
|
|
37
|
+
registry: ${{ env.REGISTRY_GITHUB }}
|
|
38
|
+
username: ${{ github.actor }}
|
|
39
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
+
|
|
41
|
+
- name: Login to Docker Hub
|
|
42
|
+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
|
43
|
+
with:
|
|
44
|
+
registry: ${{ env.REGISTRY_DOCKERHUB }}
|
|
45
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
46
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
47
|
+
|
|
48
|
+
- name: Build and push
|
|
49
|
+
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
|
50
|
+
with:
|
|
51
|
+
context: .
|
|
52
|
+
push: true
|
|
53
|
+
tags: |
|
|
54
|
+
${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}
|
|
55
|
+
${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}
|
|
56
|
+
|
|
57
|
+
deploy:
|
|
58
|
+
needs: build
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- name: Get token for ${{ env.DECLARATIVE_REPOSITORY }}
|
|
62
|
+
id: app-token
|
|
63
|
+
uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2
|
|
64
|
+
with:
|
|
65
|
+
app-id: ${{ vars.DECLARATIVE_DEPLOYMENT_GITHUB_APP_ID }}
|
|
66
|
+
private-key: ${{ secrets.DECLARATIVE_DEPLOYMENT_GITHUB_APP_PRIVATE_KEY }}
|
|
67
|
+
owner: ${{ env.DECLARATIVE_OWNER }}
|
|
68
|
+
repositories: ${{ env.DECLARATIVE_REPOSITORY }}
|
|
69
|
+
|
|
70
|
+
- name: Checkout ${{ env.DECLARATIVE_REPOSITORY }}
|
|
71
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
|
72
|
+
with:
|
|
73
|
+
repository: ${{ env.DECLARATIVE_OWNER }}/${{ env.DECLARATIVE_REPOSITORY }}
|
|
74
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
75
|
+
|
|
76
|
+
- name: Update image tag
|
|
77
|
+
run: yq -i '.["mcp"].image.tag = strenv(TAG)' ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/fra1.yaml
|
|
78
|
+
|
|
79
|
+
- name: Commit and push
|
|
80
|
+
run: |
|
|
81
|
+
git config user.name "github-actions[bot]"
|
|
82
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
83
|
+
git add ${{ env.ENVIRONMENT }}/${{ env.PROJECT }}/fra1.yaml
|
|
84
|
+
if git diff --cached --quiet; then
|
|
85
|
+
echo "No changes to commit"
|
|
86
|
+
else
|
|
87
|
+
git commit -m "chore(${{ env.ENVIRONMENT }}): ${{ env.PROJECT }} image tag to ${{ env.TAG }}"
|
|
88
|
+
git push
|
|
89
|
+
fi
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for AI agents and human contributors working in this repository.
|
|
4
|
+
|
|
5
|
+
## What this repo is
|
|
6
|
+
|
|
7
|
+
`mcp-server-appwrite` is a [Model Context Protocol](https://modelcontextprotocol.io)
|
|
8
|
+
server for Appwrite. It exposes Appwrite's API to MCP clients as a small set of
|
|
9
|
+
operator-style tools, supporting two deployments from one codebase:
|
|
10
|
+
|
|
11
|
+
- **Cloud (hosted HTTP):** a Starlette ASGI app that acts as an OAuth 2.1
|
|
12
|
+
Resource Server. It validates the client's bearer token and forwards it to the
|
|
13
|
+
Appwrite REST API. Served at `mcp.appwrite.io/mcp`.
|
|
14
|
+
- **Self-hosted (`stdio`):** runs locally and authenticates with a project API
|
|
15
|
+
key (`APPWRITE_PROJECT_ID`, `APPWRITE_API_KEY`, `APPWRITE_ENDPOINT`).
|
|
16
|
+
|
|
17
|
+
Python ≥ 3.12, packaged with `hatchling`, managed with `uv`.
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
Source lives in `src/mcp_server_appwrite/`:
|
|
22
|
+
|
|
23
|
+
| File | Responsibility |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
| `__main__.py` / `server.py` | Entry point, CLI args, transport selection (`--transport stdio\|http`), service registration, low-level MCP server. |
|
|
26
|
+
| `http_app.py` | Hosted Streamable-HTTP transport: `/mcp`, RFC 9728 protected-resource metadata, `/healthz`. |
|
|
27
|
+
| `auth.py` | OAuth 2.1 resource-server layer — bearer-token validation against the project's Appwrite authorization server. |
|
|
28
|
+
| `service.py` | `Service` base class: introspects an Appwrite SDK service and turns its methods into MCP tool definitions. |
|
|
29
|
+
| `tool_manager.py` | Registry of all services and their generated tools. |
|
|
30
|
+
| `operator.py` | The compact "operator" surface — `appwrite_search_tools`, `appwrite_call_tool`, result/resource storage, write confirmation. |
|
|
31
|
+
| `context.py` | `appwrite_get_context` — workspace summary (project, services, account/org for OAuth). |
|
|
32
|
+
| `docs_search.py` | In-process semantic docs search (`appwrite_search_docs`) over a prebuilt index. |
|
|
33
|
+
| `data/` | Committed docs index artifact (`docs_index.npz`, `docs_index_meta.json`), shipped in the wheel/image. |
|
|
34
|
+
|
|
35
|
+
`scripts/build_docs_index.py` rebuilds the docs index (requires `OPENAI_API_KEY`).
|
|
36
|
+
|
|
37
|
+
### Tool surface (key design point)
|
|
38
|
+
|
|
39
|
+
The server boots in a compact workflow: the client sees up to 4 tools
|
|
40
|
+
(`appwrite_get_context`, `appwrite_search_tools`, `appwrite_call_tool`, and
|
|
41
|
+
optionally `appwrite_search_docs`), while the full Appwrite catalog (25 services)
|
|
42
|
+
stays internal and is searched at runtime. Mutating hidden tools require
|
|
43
|
+
`confirm_write=true`. Large outputs are stored as MCP resources and returned as a
|
|
44
|
+
preview + resource URI.
|
|
45
|
+
|
|
46
|
+
## Local development
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Install uv, then sync deps
|
|
50
|
+
uv sync # runtime deps
|
|
51
|
+
uv sync --group dev # + black, ruff (lint/format)
|
|
52
|
+
uv sync --extra integration # + integration-test deps
|
|
53
|
+
|
|
54
|
+
# Run hosted HTTP transport
|
|
55
|
+
MCP_PUBLIC_URL=http://localhost:8000 APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1 \
|
|
56
|
+
uv run mcp-server-appwrite --transport http
|
|
57
|
+
|
|
58
|
+
# Run self-hosted stdio transport
|
|
59
|
+
APPWRITE_ENDPOINT=http://localhost:9501/v1 \
|
|
60
|
+
APPWRITE_PROJECT_ID=<id> APPWRITE_API_KEY=<key> \
|
|
61
|
+
uv run mcp-server-appwrite
|
|
62
|
+
|
|
63
|
+
# Or via Docker (hosted HTTP/OAuth)
|
|
64
|
+
docker compose up --build # compose.yaml; endpoint at http://localhost:8000/mcp
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Pre-PR checklist
|
|
68
|
+
|
|
69
|
+
Run these locally before opening a PR. They mirror the `CI` workflow
|
|
70
|
+
(`.github/workflows/ci.yml`), which runs on every pull request and on pushes to
|
|
71
|
+
`main`. **All four jobs must pass.**
|
|
72
|
+
|
|
73
|
+
1. **Lint** (`lint` job)
|
|
74
|
+
```bash
|
|
75
|
+
uv sync --group dev
|
|
76
|
+
uv run --group dev ruff check src tests
|
|
77
|
+
```
|
|
78
|
+
Ruff config: `target-version = py312`, rules `E`, `F`, `W`, `I` (import
|
|
79
|
+
sorting), with `E501` (line length) delegated to black.
|
|
80
|
+
|
|
81
|
+
2. **Format** (`lint` job)
|
|
82
|
+
```bash
|
|
83
|
+
uv run --group dev black --check src tests
|
|
84
|
+
```
|
|
85
|
+
Run `uv run --group dev black src tests` (without `--check`) to auto-fix.
|
|
86
|
+
|
|
87
|
+
3. **Unit tests** (`unit` job)
|
|
88
|
+
```bash
|
|
89
|
+
uv sync
|
|
90
|
+
uv run python -m unittest discover -s tests/unit -v
|
|
91
|
+
```
|
|
92
|
+
Fast, no external services or credentials required.
|
|
93
|
+
|
|
94
|
+
4. **Docker build** (`docker` job)
|
|
95
|
+
```bash
|
|
96
|
+
docker build -t appwrite-mcp:ci .
|
|
97
|
+
```
|
|
98
|
+
The hosted HTTP image must build cleanly.
|
|
99
|
+
|
|
100
|
+
5. **Integration tests** (`integration` job) — *CI runs these only for pushes and
|
|
101
|
+
for PRs from branches on the same repo (not forks).* They create and delete
|
|
102
|
+
**real** Appwrite resources, so they need live credentials and are skipped
|
|
103
|
+
when absent:
|
|
104
|
+
```bash
|
|
105
|
+
uv sync --extra integration
|
|
106
|
+
APPWRITE_PROJECT_ID=<id> APPWRITE_API_KEY=<key> APPWRITE_ENDPOINT=<url> \
|
|
107
|
+
uv run --extra integration python -m unittest discover -s tests/integration -v
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### CI environment versions
|
|
111
|
+
|
|
112
|
+
CI pins Python `3.12` and `uv` `0.11.22`. Match these locally if you hit
|
|
113
|
+
version-specific differences.
|
|
114
|
+
|
|
115
|
+
### If you change the docs index
|
|
116
|
+
|
|
117
|
+
Rebuilding `src/mcp_server_appwrite/data/` requires `OPENAI_API_KEY`. Re-run the
|
|
118
|
+
build script and commit the refreshed artifact:
|
|
119
|
+
```bash
|
|
120
|
+
OPENAI_API_KEY=sk-... uv run python scripts/build_docs_index.py
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Other workflows
|
|
124
|
+
|
|
125
|
+
- `publish.yml` — package publishing.
|
|
126
|
+
- `staging.yml` / `production.yml` — deployment (publishes images to Docker Hub).
|
|
127
|
+
|
|
128
|
+
These are not gated on PRs the way `ci.yml` is, but be mindful when touching the
|
|
129
|
+
`Dockerfile`, `pyproject.toml` version, or deployment config.
|
|
130
|
+
|
|
131
|
+
## Conventions
|
|
132
|
+
|
|
133
|
+
- Keep the exposed tool surface small — new Appwrite capabilities should flow
|
|
134
|
+
through the operator/catalog mechanism, not become top-level tools.
|
|
135
|
+
- New SDK services are registered automatically; you generally don't hand-write
|
|
136
|
+
tool definitions.
|
|
137
|
+
- Match existing style: black formatting, ruff-clean imports, type hints, module
|
|
138
|
+
docstrings explaining intent (see `auth.py`, `http_app.py`, `docs_search.py`).
|
|
139
|
+
- Add unit tests under `tests/unit/` for any non-trivial logic; add integration
|
|
140
|
+
coverage under `tests/integration/` when touching real API behavior.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
FROM python:3.12-slim AS base
|
|
2
|
+
|
|
3
|
+
ENV PYTHONUNBUFFERED=1 \
|
|
4
|
+
UV_COMPILE_BYTECODE=1 \
|
|
5
|
+
UV_LINK_MODE=copy
|
|
6
|
+
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
COPY --from=ghcr.io/astral-sh/uv:0.11.22 /uv /usr/local/bin/uv
|
|
10
|
+
|
|
11
|
+
COPY pyproject.toml uv.lock README.md ./
|
|
12
|
+
COPY src ./src
|
|
13
|
+
|
|
14
|
+
RUN uv sync --frozen --no-dev
|
|
15
|
+
|
|
16
|
+
ENV HOST=0.0.0.0 \
|
|
17
|
+
PORT=8000 \
|
|
18
|
+
MCP_TRANSPORT=http \
|
|
19
|
+
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
|
|
20
|
+
|
|
21
|
+
EXPOSE 8000
|
|
22
|
+
|
|
23
|
+
CMD ["uv", "run", "mcp-server-appwrite", "--transport", "http"]
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-server-appwrite
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: MCP (Model Context Protocol) server for Appwrite
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: appwrite<22,>=21.0.0
|
|
8
|
+
Requires-Dist: docstring-parser>=0.16
|
|
9
|
+
Requires-Dist: httpx>=0.27.0
|
|
10
|
+
Requires-Dist: mcp[cli]>=1.12.0
|
|
11
|
+
Requires-Dist: numpy>=2.0
|
|
12
|
+
Requires-Dist: openai>=1.40
|
|
13
|
+
Requires-Dist: pyjwt[crypto]>=2.9.0
|
|
14
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
15
|
+
Requires-Dist: starlette>=0.40.0
|
|
16
|
+
Requires-Dist: uvicorn[standard]>=0.30.0
|
|
17
|
+
Provides-Extra: integration
|
|
18
|
+
Requires-Dist: argon2-cffi>=23.1.0; extra == 'integration'
|
|
19
|
+
Requires-Dist: bcrypt>=4.1.2; extra == 'integration'
|
|
20
|
+
Requires-Dist: passlib>=1.7.4; extra == 'integration'
|
|
21
|
+
Requires-Dist: pycryptodome>=3.20.0; extra == 'integration'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Appwrite MCP server
|
|
25
|
+
|
|
26
|
+
mcp-name: io.github.appwrite/mcp
|
|
27
|
+
|
|
28
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) server for Appwrite.
|
|
29
|
+
It exposes Appwrite's API — databases, users, functions, teams, storage, and more
|
|
30
|
+
— as tools your MCP client can call.
|
|
31
|
+
|
|
32
|
+
Connect to the hosted server at **`https://mcp.appwrite.io/mcp`** and authenticate
|
|
33
|
+
through your browser. The first time you connect, your client opens an Appwrite
|
|
34
|
+
consent screen; approve the scopes and you're connected. There are no keys to
|
|
35
|
+
copy.
|
|
36
|
+
|
|
37
|
+
## Connect your client
|
|
38
|
+
|
|
39
|
+
Pick your client below. Each adds the hosted Appwrite Cloud server.
|
|
40
|
+
|
|
41
|
+
<details open>
|
|
42
|
+
<summary><b>Claude Code</b></summary>
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
claude mcp add --transport http appwrite https://mcp.appwrite.io/mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
<details>
|
|
51
|
+
<summary><b>Claude Desktop</b></summary>
|
|
52
|
+
|
|
53
|
+
Go to **Settings → Connectors → Add custom connector** and paste
|
|
54
|
+
`https://mcp.appwrite.io/mcp`.
|
|
55
|
+
|
|
56
|
+
On the free plan, bridge the remote server through stdio instead (requires
|
|
57
|
+
Node.js) by editing your config via **Settings → Developer → Edit Config**:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"appwrite": {
|
|
63
|
+
"command": "npx",
|
|
64
|
+
"args": ["mcp-remote", "https://mcp.appwrite.io/mcp"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary><b>Cursor</b></summary>
|
|
74
|
+
|
|
75
|
+
Edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project).
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"mcpServers": {
|
|
80
|
+
"appwrite": {
|
|
81
|
+
"url": "https://mcp.appwrite.io/mcp"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
</details>
|
|
88
|
+
|
|
89
|
+
<details>
|
|
90
|
+
<summary><b>VS Code</b> (GitHub Copilot)</summary>
|
|
91
|
+
|
|
92
|
+
Edit `.vscode/mcp.json` (workspace) or your user configuration via the Command
|
|
93
|
+
Palette → **MCP: Open User Configuration**.
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"servers": {
|
|
98
|
+
"appwrite": {
|
|
99
|
+
"type": "http",
|
|
100
|
+
"url": "https://mcp.appwrite.io/mcp"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
<details>
|
|
109
|
+
<summary><b>Codex</b></summary>
|
|
110
|
+
|
|
111
|
+
Edit `~/.codex/config.toml`.
|
|
112
|
+
|
|
113
|
+
```toml
|
|
114
|
+
[mcp_servers.appwrite]
|
|
115
|
+
url = "https://mcp.appwrite.io/mcp"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
</details>
|
|
119
|
+
|
|
120
|
+
<details>
|
|
121
|
+
<summary><b>OpenCode</b></summary>
|
|
122
|
+
|
|
123
|
+
Edit `opencode.json` (project) or `~/.config/opencode/opencode.json` (global).
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"$schema": "https://opencode.ai/config.json",
|
|
128
|
+
"mcp": {
|
|
129
|
+
"appwrite": {
|
|
130
|
+
"type": "remote",
|
|
131
|
+
"url": "https://mcp.appwrite.io/mcp",
|
|
132
|
+
"enabled": true
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
<details>
|
|
141
|
+
<summary><b>Windsurf</b></summary>
|
|
142
|
+
|
|
143
|
+
Edit `~/.codeium/windsurf/mcp_config.json`.
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"mcpServers": {
|
|
148
|
+
"appwrite": {
|
|
149
|
+
"serverUrl": "https://mcp.appwrite.io/mcp"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
</details>
|
|
156
|
+
|
|
157
|
+
## Self-hosted Appwrite
|
|
158
|
+
|
|
159
|
+
Running your own Appwrite instance? Run the MCP server locally over `stdio` and
|
|
160
|
+
authenticate with a project API key. See [docs/self-hosted.md](docs/self-hosted.md)
|
|
161
|
+
for per-client setup.
|
|
162
|
+
|
|
163
|
+
## Documentation
|
|
164
|
+
|
|
165
|
+
- [Tool surface](docs/tool-surface.md) — the tools exposed to the model and the
|
|
166
|
+
internal Appwrite catalog.
|
|
167
|
+
- [How Cloud authentication works](docs/authentication.md) — the OAuth 2.1 flow.
|
|
168
|
+
- [Documentation search](docs/documentation-search.md) — the in-process
|
|
169
|
+
`appwrite_search_docs` tool and how to rebuild its index.
|
|
170
|
+
- [Self-hosted Appwrite](docs/self-hosted.md) — run the server locally with a
|
|
171
|
+
project API key.
|
|
172
|
+
- [Local development](docs/development.md) — running, testing, and debugging the
|
|
173
|
+
server locally.
|
|
174
|
+
- [AGENTS.md](AGENTS.md) — full contributor guide and pre-PR checklist.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
This MCP server is licensed under the MIT License. See the [LICENSE](LICENSE) file
|
|
179
|
+
for details.
|