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.
Files changed (68) hide show
  1. mcp_server_appwrite-0.7.0/.dockerignore +12 -0
  2. mcp_server_appwrite-0.7.0/.env.example +27 -0
  3. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.github/workflows/ci.yml +32 -11
  4. mcp_server_appwrite-0.7.0/.github/workflows/production.yml +88 -0
  5. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.github/workflows/publish.yml +3 -3
  6. mcp_server_appwrite-0.7.0/.github/workflows/staging.yml +89 -0
  7. mcp_server_appwrite-0.7.0/AGENTS.md +140 -0
  8. mcp_server_appwrite-0.7.0/CLAUDE.md +1 -0
  9. mcp_server_appwrite-0.7.0/Dockerfile +23 -0
  10. mcp_server_appwrite-0.7.0/PKG-INFO +179 -0
  11. mcp_server_appwrite-0.7.0/README.md +156 -0
  12. mcp_server_appwrite-0.7.0/compose.yaml +29 -0
  13. mcp_server_appwrite-0.7.0/docs/authentication.md +39 -0
  14. mcp_server_appwrite-0.7.0/docs/development.md +74 -0
  15. mcp_server_appwrite-0.7.0/docs/documentation-search.md +36 -0
  16. mcp_server_appwrite-0.7.0/docs/self-hosted.md +176 -0
  17. mcp_server_appwrite-0.7.0/docs/tool-surface.md +49 -0
  18. mcp_server_appwrite-0.7.0/pyproject.toml +58 -0
  19. mcp_server_appwrite-0.7.0/scripts/build_docs_index.py +219 -0
  20. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/server.json +10 -4
  21. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/__init__.py +8 -0
  22. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/auth.py +284 -0
  23. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/context.py +339 -0
  24. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/data/docs_index.npz +0 -0
  25. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/data/docs_index_meta.json +1 -0
  26. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/docs_search.py +210 -0
  27. mcp_server_appwrite-0.7.0/src/mcp_server_appwrite/http_app.py +194 -0
  28. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/operator.py +96 -6
  29. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/server.py +339 -54
  30. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/service.py +7 -3
  31. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/tool_manager.py +3 -1
  32. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/support.py +30 -4
  33. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_functions.py +0 -1
  34. mcp_server_appwrite-0.7.0/tests/integration/test_oauth_discovery.py +65 -0
  35. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_operator.py +1 -1
  36. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_sites.py +0 -1
  37. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_storage.py +0 -1
  38. mcp_server_appwrite-0.7.0/tests/unit/test_auth.py +220 -0
  39. mcp_server_appwrite-0.7.0/tests/unit/test_context.py +191 -0
  40. mcp_server_appwrite-0.7.0/tests/unit/test_docs_search.py +126 -0
  41. mcp_server_appwrite-0.7.0/tests/unit/test_http_app.py +41 -0
  42. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_operator.py +106 -7
  43. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_server.py +118 -12
  44. mcp_server_appwrite-0.7.0/uv.lock +1569 -0
  45. mcp_server_appwrite-0.4/.env.example +0 -3
  46. mcp_server_appwrite-0.4/PKG-INFO +0 -296
  47. mcp_server_appwrite-0.4/README.md +0 -279
  48. mcp_server_appwrite-0.4/images/appwrite-logo-darkbg.png +0 -0
  49. mcp_server_appwrite-0.4/images/appwrite-logo-lightbg.png +0 -0
  50. mcp_server_appwrite-0.4/images/claude-desktop-integration.png +0 -0
  51. mcp_server_appwrite-0.4/images/cursor-integration.png +0 -0
  52. mcp_server_appwrite-0.4/images/vs-code-integration.png +0 -0
  53. mcp_server_appwrite-0.4/images/windsurf-integration.png +0 -0
  54. mcp_server_appwrite-0.4/pyproject.toml +0 -35
  55. mcp_server_appwrite-0.4/src/mcp_server_appwrite/__init__.py +0 -16
  56. mcp_server_appwrite-0.4/uv.lock +0 -769
  57. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.gitignore +0 -0
  58. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/.python-version +0 -0
  59. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/LICENSE +0 -0
  60. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/src/mcp_server_appwrite/__main__.py +0 -0
  61. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_avatars.py +0 -0
  62. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_locale.py +0 -0
  63. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_messaging.py +0 -0
  64. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_tables_db.py +0 -0
  65. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_teams.py +0 -0
  66. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/integration/test_users.py +0 -0
  67. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/test_all.py +1 -1
  68. {mcp_server_appwrite-0.4 → mcp_server_appwrite-0.7.0}/tests/unit/test_service.py +0 -0
@@ -0,0 +1,12 @@
1
+ .git
2
+ .github
3
+ .ruff_cache
4
+ .venv
5
+ __pycache__
6
+ *.pyc
7
+ .env
8
+ .env.*
9
+ !.env.example
10
+ deploy
11
+ images
12
+ tests
@@ -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
- format:
9
- name: Format
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.