From 66577c958adc496b3c2ea7d1a4f3dccdebfd1716 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 5 Aug 2026 01:06:47 +0530 Subject: [PATCH 01/13] Add MCP server function template blog --- .optimize-cache.json | 2 + .../+page.markdoc | 152 ++++++++++++++++++ .../changelog/(entries)/2026-08-05.markdoc | 22 +++ .../functions/templates/+page.markdoc | 4 + .../announcing-mcp-server-template/cover.avif | Bin 0 -> 24618 bytes .../template.avif | Bin 0 -> 43919 bytes 6 files changed, 180 insertions(+) create mode 100644 src/routes/blog/post/announcing-mcp-server-template/+page.markdoc create mode 100644 src/routes/changelog/(entries)/2026-08-05.markdoc create mode 100644 static/images/blog/announcing-mcp-server-template/cover.avif create mode 100644 static/images/blog/announcing-mcp-server-template/template.avif diff --git a/.optimize-cache.json b/.optimize-cache.json index 91ce8a0ea92..716c6ef645a 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -233,6 +233,8 @@ "static/images/blog/announcing-init-faster-smoother-better/init-ticket.png": "fe4e16ef27d3fcba378c52882ce3458aab3f1de84cb183d39db577e5264ef905", "static/images/blog/announcing-inversion-queries/cover.png": "232f806b8b655f469cb5398ba3abce2074e959d2fb49b9782b1889b22f1ee16e", "static/images/blog/announcing-list-cache-ttl/cover.png": "ca1554dc34d1222b86ccc295252af8e07b2f635b9b10e1227a21fff81138e409", + "static/images/blog/announcing-mcp-server-template/cover.png": "6d56132149089769607e9533405f33a7001edf09896487f20667bf4515588661", + "static/images/blog/announcing-mcp-server-template/template.png": "b1646eb4855b86243e941b1c4041127ad7d231f8b7b3ca3255127b8cd163aeca", "static/images/blog/announcing-message-based-realtime-sdk/cover.jpg": "00559db66e7c1333bc9b9acc0784fd4d6fb2fc7c4e1964e3cbb93e49640323a4", "static/images/blog/announcing-new-push-notifications-features/cover.png": "a0c758cf6c8a95e09a0d2ca562b0775a50d34a4d691d675cda70e44ad21805ac", "static/images/blog/announcing-opt-in-relationship-loading/cover.png": "e16cc16ea6d968b29af19bcd6274741141584a7efe5e1bb18be19b77c3a380c8", diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc new file mode 100644 index 00000000000..406e494abe3 --- /dev/null +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -0,0 +1,152 @@ +--- +layout: post +title: "Build and deploy an MCP server with Appwrite Functions" +description: Deploy your own MCP server on Appwrite Functions with the new Python template. Expose custom tools to Claude Code, Cursor, and other AI clients over HTTPS. +date: 2026-08-05 +cover: /images/blog/announcing-mcp-server-template/cover.avif +timeToRead: 6 +author: aditya-oberai +category: announcement, ai +featured: false +faqs: + - question: "What is the MCP server template for Appwrite Functions?" + answer: "It is a function template that deploys a stateless Model Context Protocol server over HTTPS, built with the official MCP Python SDK. It ships with two demo tools (`echo` and `add`), optional bearer authentication, and a package structure ready for your own tools. You can create it from the Appwrite Console under **Functions** > **Templates**." + - question: "How do I connect Claude Code or Cursor to an MCP server hosted on Appwrite?" + answer: "Deploy the template and copy your function's domain. In Claude Code, run `claude mcp add --transport http my-mcp https://.appwrite.run`. In Cursor or Claude Desktop, add the URL to the `mcpServers` section of your MCP configuration. The server speaks Streamable HTTP, so there is no local process to run." + - question: "How do I add my own tools to the MCP server template?" + answer: "Register tools in `src/app.py` with the `@server.tool` decorator. Python type hints on the function's parameters become the tool's `inputSchema` automatically. Push the change to your connected repository, and once the new deployment is live, clients pick up the updated tool list." + - question: "How do I secure an MCP server running on Appwrite Functions?" + answer: "Set the `MCP_AUTH_MODE` environment variable to `bearer` and `MCP_AUTH_TOKEN` to a long random secret. The server then rejects any request without a matching `Authorization: Bearer` header, using constant-time comparison. Clients pass the token through the `headers` field of their MCP configuration." + - question: "Does the template support the stateless MCP 2026-07-28 specification?" + answer: "Yes. The template handles both the legacy handshake used by clients on protocol version `2025-06-18` and the modern stateless protocol introduced in the [MCP 2026-07-28 specification](/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification). Appwrite Functions are stateless request/response workers, which matches the direction the protocol has taken." + - question: "What are the limitations of the MCP server template?" + answer: "Two main ones. The server is stateless JSON over HTTPS, so there is no SSE streaming, no progress updates during tool calls, and no server-initiated messages like sampling. And tool calls run as [synchronous executions](/docs/products/functions/execute#synchronous-executions), which Appwrite caps at 30 seconds. Keep `MCP_TOOL_TIMEOUT` at its default of 25 seconds so a slow tool returns a clean JSON-RPC error before the cap. Long-running work should start a job and return a handle that another tool can poll." + - question: "Is this the same as the Appwrite MCP server?" + answer: "No. The [Appwrite MCP server](/docs/tooling/ai/mcp-servers) gives AI tools access to Appwrite's own APIs, like creating users or managing databases, through `https://mcp.appwrite.io/`. The MCP server template is for building and hosting your own MCP server with your own custom tools on Appwrite Functions." +--- + +The Model Context Protocol has become the standard way to give AI tools new capabilities. Claude Code, Cursor, Claude Desktop, and most other AI clients speak it, and when an agent needs a skill it does not have, the answer is an MCP server. Writing one is the easy part: with the official SDKs, a tool is a decorated function. Hosting one is where the friction starts. You need an HTTPS endpoint, authentication, deployments, and infrastructure that scales, all for what is often fifty lines of code. + +Today, we are announcing the **MCP server template** for Appwrite Functions. It deploys a working, stateless MCP server over HTTPS, built with the official MCP Python SDK, that you can connect to Claude Code, Cursor, and any other MCP client in minutes. You will find it in the Appwrite Console under **Functions** > **Templates**. + +# What you get out of the box + +- **A working MCP server**: the template ships with two demo tools, `echo` and `add`, so you can verify the full loop from AI client to hosted server before writing any code. +- **The official Python SDK**: tools are plain Python functions registered with a decorator. Type hints become each tool's `inputSchema` automatically. +- **Streamable HTTP transport**: stateless JSON-RPC over your function's domain, supporting both the legacy MCP handshake and the stateless protocol from the [MCP 2026-07-28 specification](/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification). +- **Optional bearer authentication**: one environment variable gates the endpoint behind an `Authorization` header. +- **Nothing to operate**: your function's domain is the server URL. TLS, deployments, scaling, and logs all come from [Appwrite Functions](/docs/products/functions). + +# Deploy an MCP server from the Console + +1. In the [Appwrite Console](https://cloud.appwrite.io), open your project and head to **Functions** > **Templates**. + +2. Search for **MCP server** and click **Create**. + +![Appwrite MCP server template](/images/blog/announcing-mcp-server-template/template.avif) + +3. Optionally set environment variables: `MCP_SERVER_NAME` for the display name clients see, `MCP_AUTH_MODE` and `MCP_AUTH_TOKEN` for bearer authentication, and `MCP_TOOL_TIMEOUT` for a soft deadline on tool calls (best kept at the 25-second default). All of them have sensible defaults. + +4. Optionally, connect a GitHub repository. You can connect one later through the function's settings page too. + +5. Deploy the function. + +Once the deployment is live, your function's domain is your MCP server URL: + +``` +https://.appwrite.run +``` + +There is no separate hosting step and no reverse proxy to configure. The domain serves MCP directly. + +# Connect it to your AI tools + +In Claude Code, adding the server is one command: + +```bash +claude mcp add --transport http my-mcp https://.appwrite.run +``` + +In Cursor or Claude Desktop, add the URL to your MCP configuration: + +```json +{ + "mcpServers": { + "my-mcp": { + "url": "https://.appwrite.run" + } + } +} +``` + +That is the whole setup. Ask your agent to call the `echo` tool, and you will see the request travel from your editor to a serverless function and back. + +# Write your own tools + +The demo tools exist to be replaced. Tools live in `src/app.py`, and each one is a Python function registered with a decorator: + +```python +# src/app.py +from mcp.server.mcpserver import MCPServer + +server = MCPServer(name="my-mcp", version="0.1.0") + +@server.tool(description="Do something useful.") +def my_tool(query: str) -> str: + return f"got: {query}" +``` + +Type hints become the tool's `inputSchema`, so clients know exactly what arguments to send. Push the change to your connected repository, and Appwrite builds and activates the new deployment automatically. + +Because the server runs inside your Appwrite project, every request carries a [dynamic API key](/docs/products/functions/develop#dynamic-api-key) in its headers. A tool that needs your data can initialize the Appwrite SDK with that key and query your databases, storage, or users, without you creating, scoping, or rotating any credentials. + +# Secure the endpoint + +By default, the endpoint is open, which is convenient while you experiment. Before you expose anything internal, set two environment variables on the function: `MCP_AUTH_MODE=bearer` and `MCP_AUTH_TOKEN` set to a long random secret. The server then rejects every request that does not carry the matching header, comparing tokens in constant time. + +On the client side, pass the token in your MCP configuration: + +```json +{ + "mcpServers": { + "my-mcp": { + "url": "https://.appwrite.run", + "headers": { + "Authorization": "Bearer your-long-random-secret" + } + } + } +} +``` + +# Built for the stateless MCP era + +For most of its life, MCP was a stateful protocol, and it fought serverless hosting. Sessions had to land on the same instance, and the transport leaned on long-lived SSE streams. The [MCP 2026-07-28 specification](/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification) changed that by making the protocol core stateless: every request is self-describing, and any request can be handled by any instance. + +That shift makes request/response platforms like Appwrite Functions a natural home for MCP servers, and the template meets the protocol on both sides of the transition. It answers the legacy `initialize` handshake for clients still on protocol version `2025-06-18`, and it handles the modern stateless path for clients that have moved to `2026-07-28`. + +# When to reach for this template + +The template is the right starting point when you want AI agents to call tools that are yours: + +- **Internal team tools**: look up orders, query a product database, check the status of a job, or trigger a workflow, all from a chat in your editor. +- **A controlled wrapper around an existing API**: instead of handing an agent raw API credentials, expose three or four specific operations with your validation in the middle. +- **Tools over your Appwrite data**: with the dynamic API key, tools can read and write your project's databases and storage without extra configuration. + +## What it does not do + +The template makes two deliberate trade-offs, and they are worth knowing before you build on it: + +- **No streaming.** The server is stateless JSON over HTTPS. There is no SSE support, so tools cannot stream progress while they run, and the server cannot send server-initiated messages like sampling requests back to the client. A tool call returns once, with its final result. +- **No long-running tool calls.** Requests to a function's domain are [synchronous executions](/docs/products/functions/execute#synchronous-executions), which Appwrite caps at 30 seconds. We recommend keeping `MCP_TOOL_TIMEOUT` at its default of 25 seconds, so a slow tool returns a clean JSON-RPC error before the platform cuts the connection at 30. For work that needs minutes, have one tool start the job and return a handle that a second tool can poll. + +If streaming or long-running synchronous calls are hard requirements, a container-based host is the better fit for that server today. And if what you want is for AI tools to manage Appwrite itself, creating users, provisioning databases, or deploying functions, you do not need to build anything: the hosted [Appwrite MCP server](/docs/tooling/ai/mcp-servers) already does that with one URL. + +# Start building your MCP server + +The MCP server template is available now on [Appwrite Cloud](https://cloud.appwrite.io) and for self-hosted instances. Open your project, head to **Functions** > **Templates**, search for **MCP server**, and you will have a live endpoint your AI tools can call in a few minutes. If you are new to the Model Context Protocol, our [complete guide to MCP](/blog/post/what-is-mcp-a-complete-guide-for-developers) covers how the protocol works before you start building on it. + +- [Function templates documentation](/docs/products/functions/templates) +- [Appwrite Functions development guide](/docs/products/functions/develop) +- [MCP server template source on GitHub](https://github.com/appwrite/templates/tree/main/python/mcp-server) +- [What's new in the MCP 2026-07-28 specification](/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification) diff --git a/src/routes/changelog/(entries)/2026-08-05.markdoc b/src/routes/changelog/(entries)/2026-08-05.markdoc new file mode 100644 index 00000000000..b69ccbdea3e --- /dev/null +++ b/src/routes/changelog/(entries)/2026-08-05.markdoc @@ -0,0 +1,22 @@ +--- +layout: changelog +title: "Deploy your own MCP server with the new Functions template" +date: 2026-08-05 +cover: /images/blog/announcing-mcp-server-template/cover.avif +--- + +The new **MCP server** [function template](/docs/products/functions/templates) deploys a stateless [Model Context Protocol](https://modelcontextprotocol.io/) server over HTTPS, built with the official MCP Python SDK. It ships with two demo tools, optional **bearer authentication**, and support for both the legacy MCP handshake and the stateless `2026-07-28` protocol. + +Create it from the Console under **Functions** > **Templates**, and your function's domain becomes an MCP endpoint you can connect to Claude Code, Cursor, and other AI clients: + +```bash +claude mcp add --transport http my-mcp https://.appwrite.run +``` + +Register your own tools in `src/app.py` with the `@server.tool` decorator, and use the [dynamic API key](/docs/products/functions/develop#dynamic-api-key) to build tools that read and write your Appwrite project's data. + +Two trade-offs to know: the server is stateless JSON only, so there is no SSE streaming or server-initiated messages, and tool calls are synchronous with a **30-second execution cap** (25-second soft deadline by default). The announcement covers both in more detail. + +{% arrow_link href="/blog/post/announcing-mcp-server-template" %} +Read the announcement +{% /arrow_link %} diff --git a/src/routes/docs/products/functions/templates/+page.markdoc b/src/routes/docs/products/functions/templates/+page.markdoc index 69ff3d97dda..0b3d3e52f74 100644 --- a/src/routes/docs/products/functions/templates/+page.markdoc +++ b/src/routes/docs/products/functions/templates/+page.markdoc @@ -102,6 +102,10 @@ A comment is made to your PR about the build, unless you enable **Silent mode**. * Generate PDFs programmatically with Appwrite Functions. * Node.js --- +* MCP server +* Expose custom tools to AI clients over HTTPS using the Model Context Protocol. +* Python +--- * Payments with Stripe * Receive card payments and store paid orders. * Node.js diff --git a/static/images/blog/announcing-mcp-server-template/cover.avif b/static/images/blog/announcing-mcp-server-template/cover.avif new file mode 100644 index 0000000000000000000000000000000000000000..bf6b3927764e8fc39721c4b71421376b70d5435e GIT binary patch literal 24618 zcmYIvV~{A(uI|{jZQHhO+qP}nGka{?-ecRgZM=QXsar2q9ehcuJL^YxvT8K|0054e zi>HI3o241RKeDwnWBiY9Yian;26V7Bbus)8{*MSPOl+L~rvd;tSQ@+hpZL4YA3ApVK}#e?Gf2l`jV|9pV|@o*TrdIVG&{FZEybz=1%(06-uiK%im& z04z%<)BlzE?{@!^ZT`DJ|BBShvo$evK>~n+;3_t z4o1)ebA~tsB+-b$&gBhlP-S5z2Sv;pfkD<$F!K(rMp=5lXYHx7rv6RjEW^j%O@Lu0 z4>{HP{kCt!w@6n$e-;b0QVmy7XqOE}jy7=%aWUi=Tcuo~?x~d>!-nY06OGS+S{i;? zEwHF*H?H~hoiIwIf1gS-N#yJL<3A{n@YT8?u zP5ZN+6N^Z|*`-pkD@@Gw6#cT}9V zRT9Ek?>OlbF$Mry<)@+eVP~Cm)VK2{3h@&&K&UHO77bGLGQ*`tHHw&c2*Y%zf)&+> z4B+G#4v+EtEtw5Hoga@u&dU(56CyPq!64jm$>5{#BUHMr&7}G}z(fMv$$VUg zJeekWUJY?r4Zz<%3$+yEj*Qki_4;?_(`z7`Af*PIh8pS5-uKJRA34WMRyCnr(0l|` zDrE$`(4U|7yL%QkGjho5Tk_HB&FG%_^g{OZsVTOS1n*i@WU{o&Aa;hgzM&Yq(by2r zA2(Dt}2zHh_vFrQ&sF6hI}Loj6YcZ-7s zNur?3p`|3NaacxgS~t^@QqRs6cb1bxqBc2y=>E#ppMsZg6wK z=JfiaRQ>}no0&FOTeuA)2aw#l5F5AiqH(J#lHGHx$ zfS47^G@>X!D%7EoZ2_QXr8-GmHALC*ZG+hrJg{&gAqdPNkVw6Xv=D0expnn+i!-ot zhxV!CaqcN1fi39vgv+LM0l&1X@nioi)G+)_&YzGq{#l_3>eR)4&u zUs?y*k~$?yM}v$z+9((cV!8X~G;i0M69xh~teNQ7aG3~5rskc&T$bY4Q)9}I`mTz| zQ8?#L<3?J~h4iLado@DVX6*I*8j@3%;|#s&$D?vrGT!EGskP&JL2qtpCbdb%ilRf` zqEpn;!`GpCgfmJ%*?~zOJ;n~dfX*WXl+51i$$?gT6zjrpNRuY8JsSF)GePX(JwKgl zL%#;|e`$V@9VgXu%bRAKmLTRYzDc?#99jdn#C9=79L$MO_(AIj?pYKi?+EKH1t*%G zShVAhrn!O*X-+sOboXV0lew&&aw*}O3%0ANnc15#2bi@ZNk}8cdZt$c) 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 JU-3Uz{2#dLtMdQ= literal 0 HcmV?d00001 From 003d735856dfd02ead40c1cceb543aec050fdff1 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 5 Aug 2026 22:16:18 +0530 Subject: [PATCH 02/13] fixes from chirag's feedback --- .../blog/post/announcing-mcp-server-template/+page.markdoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc index 406e494abe3..f8372931833 100644 --- a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -5,7 +5,7 @@ description: Deploy your own MCP server on Appwrite Functions with the new Pytho date: 2026-08-05 cover: /images/blog/announcing-mcp-server-template/cover.avif timeToRead: 6 -author: aditya-oberai +author: chirag-aggarwal category: announcement, ai featured: false faqs: @@ -37,6 +37,8 @@ Today, we are announcing the **MCP server template** for Appwrite Functions. It - **Optional bearer authentication**: one environment variable gates the endpoint behind an `Authorization` header. - **Nothing to operate**: your function's domain is the server URL. TLS, deployments, scaling, and logs all come from [Appwrite Functions](/docs/products/functions). +The template pins the MCP Python SDK to `mcp==2.0.0`. Version 2.0.0 [became stable on July 28, 2026](https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0), so it is still a new major release. The exact pin is deliberate because the template's serverless adapter uses lower-level SDK entry points that can change between releases. Review compatibility before upgrading it. + # Deploy an MCP server from the Console 1. In the [Appwrite Console](https://cloud.appwrite.io), open your project and head to **Functions** > **Templates**. @@ -79,7 +81,7 @@ In Cursor or Claude Desktop, add the URL to your MCP configuration: } ``` -That is the whole setup. Ask your agent to call the `echo` tool, and you will see the request travel from your editor to a serverless function and back. +That is the whole setup. Ask your agent to list the server's available tools, then call one to see the request travel from your editor to a serverless function and back. # Write your own tools From 8002c354ae33712c4568f4db6dab6de3e7f96ba0 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 5 Aug 2026 22:18:27 +0530 Subject: [PATCH 03/13] update cover image --- .optimize-cache.json | 2 +- .../announcing-mcp-server-template/cover.avif | Bin 24618 -> 9346 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.optimize-cache.json b/.optimize-cache.json index 716c6ef645a..9c8d807ffbf 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -233,7 +233,7 @@ "static/images/blog/announcing-init-faster-smoother-better/init-ticket.png": "fe4e16ef27d3fcba378c52882ce3458aab3f1de84cb183d39db577e5264ef905", "static/images/blog/announcing-inversion-queries/cover.png": "232f806b8b655f469cb5398ba3abce2074e959d2fb49b9782b1889b22f1ee16e", "static/images/blog/announcing-list-cache-ttl/cover.png": "ca1554dc34d1222b86ccc295252af8e07b2f635b9b10e1227a21fff81138e409", - "static/images/blog/announcing-mcp-server-template/cover.png": "6d56132149089769607e9533405f33a7001edf09896487f20667bf4515588661", + "static/images/blog/announcing-mcp-server-template/cover.png": "dde7e9ccefa808a87be43ebc6f80a9b676414eebcaf0293b700bce8e55071de5", "static/images/blog/announcing-mcp-server-template/template.png": "b1646eb4855b86243e941b1c4041127ad7d231f8b7b3ca3255127b8cd163aeca", "static/images/blog/announcing-message-based-realtime-sdk/cover.jpg": "00559db66e7c1333bc9b9acc0784fd4d6fb2fc7c4e1964e3cbb93e49640323a4", "static/images/blog/announcing-new-push-notifications-features/cover.png": "a0c758cf6c8a95e09a0d2ca562b0775a50d34a4d691d675cda70e44ad21805ac", diff --git a/static/images/blog/announcing-mcp-server-template/cover.avif b/static/images/blog/announcing-mcp-server-template/cover.avif index bf6b3927764e8fc39721c4b71421376b70d5435e..f0a70b944d59637da15cff59161be3302ef59063 100644 GIT binary patch delta 9051 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 Bk52#q delta 24443 zcmV(;K-<59NvgmBkarYb9RLCV0001Au>b)800000004Qhivt0FUY>1aVRRAz3JN)D zXZ@YR0vZhpy5MF=c1G`o(6|duA{D5a?d}ZsiWrme^k< zeZ*)W6HIr`X{LY_rV&n2Qz=lB5{p_PXc~&y(jmG71ge*`aA=O%M&M}?vy`uHt;z}| z(*m=4W=Z1f9lOqdCnubBA#N5tHhqT%AiWIe5yJvVvKTiydkbKzXl70dBQ=N^Cb^-` z`3qJlrt#owc~sa}{UUQrJ~zA|7-mli%(ngb;bK11E~wGyjRMxJ4xyrMn+7Kq%I^s3 z!*PwPQ>j;ZTAPeE5pz6?A21cBhwH3B(^+oGS^WKw$0A>U@s%vgB7JrKf6PgED8B6> zZ5H?Gp4MVv6}o{w6nWb_ItTCfWxlVQE&kb@jS(O@yHu&)Loc}Cjv;@jP3mjG9Sm8p z9awqqg+AfE9DJcrX$k}uqmbcxO=dj?Pe|5r

afuqgK|l8&F{*PqZNAqkZOn}_la zjbE>TQ_qNh9Bf+^#H3HnCH?IZ{fdrTYLXD>zR4x@BNzY{s{3I_gHgD7m^ z2)ZZLaqBf!Lf-|T5EUv@5FUm8{hzt`!p|mg|ByF!;a2jBdw`gn9mdb`^FL{ip+w>EV#~I?mwhm8`bpXQ z>M!+%xQDP6ehP0_llw3>4gz)8Rn)nyYPJ?(xc(kjXrVt&Me9!^d7rWoY=YWe6Ruhe z?@|r6MAwlnqW7vzP>*fE&|WJwjd|)honLC_h+owYO6=LDOV7vO4*k7^Dq`aKWrnAJ zzZv;6(7ryEefY$W4Eu&!bQi?5!we=b@YBMfl0^m8g{CCejv8Y4C)hQy3Juo;o?yVF zW=iX4upw6l6#~#Dud}qO5YSP(q!;d{b`H>kXD?qxDu2NY+nH?a+#RvT;t4xl2-@$_ zMUK~0DOaw9ZTr4Kly>e&i4qMr(3}E)P7Z;S!br6kUL2LQIpm7~p^9r~Pr?-MAxZfS zOwGl6dNkr3d?LX_?PnlswF@t89F7F1n^=6C7y>g;r&x+9`l(k76Kwzs&q}%^by!6= zA8ms-P~i3lKP2ofcFqgoKHKRaDs-=vrtox|ZPj~wwRi34aZ;6ta(T><=mTdW_A zpVF-`#gm}QO=JGnEP}n<;4P0F;RlOWqvcog?=RHZ1l&sJB9|5kj^x^*$bvNR{W)j2 zTF^rR1mmsBz*uz3fRigd&KcE8IN(+?m`eSth@4RAJC-{V*_{b{DA@O66I(I9e*D8u zQ%*UB?!X=@cT!{BJ+-cGI`$WTw6(M)Y?B&_E*IP`QCeOfTrBerVwdLL43o#@8;9x( zo*@BAo8Y~i3s&<+yBKhmOCW9J!~4)=5xqU>=ghYk?FN7LwDL{KC0=%(%{I+QBR{0> zlJOzK*avAFbY&63oQP2V7Qh3&(?ut_hQ6i;BF)P?YXBdePHX5Y{YKM&ubhclgY?%8 zp{y?T)d7oxY+WHJ$fC-wkX)u)wsRmwP*;(Wa4|CQOAoP=tr{9);@%Tur!Wj&O3?B{ zRVqVu92bbQmCL(9DG+inUy330;Y5vVWR-@&5E7B}&8osibO}efMEUj-QQdrtEd&!& zf|*DT((4*Eau$gN>@$^rEF4k51|iyA9}O@;L$?{la)m$b`1RS`$vcRP_pUCM?c^v1 z9HL>w8-R`swVA`!MRsWicc~{$5p28D+)e@aGHL$_l&-)0C8ta~pS_~YYd63Wz;Dr` z2P$bbkKHRP9km5<%x{T*@77tkg~ogai7J*Uj>6`lUa;^m+^jBtk^+|O00-A}wsi}Z z8w$@i?Mq);9-=ar2i}&I1Coc3eAr)k|L;q}Ldum!9cHVIN0^7?HpD8Nzex6%Z^l19ik( z#LD{6IOnG}3GFqQnK0po>&h>Nj%WL;=?X(6}oXOV6@M3A}+-UcaC)ma7{1k-`oSwAxpX zvvej;2QwvN5%E?MlzZIwk9|5tiFpBBT>D0KZ5y5Q=6O3yXbxkn3_JBqp$?m`dR zQOz$1s4tC1Fbfiyb0MfHZhN@vrl87sK^1u$e+-hcH!%~i(<^P|!@dH_aM10KZ_V94 z^!fU)c$txwdl?d0Z1UlIl=^ZRdaq4fuwi@9JPOa^$)c@WHR35}i6?({FH@ExJYEZu z=BIwI;W3(jMfuINDpk@VwfV?J6J{sRiJ(*Xc2w~bw&Sy&O4xHs)$F1Zuu8Np#et&v z>8=bZhcn&5IC!C*53nbOAf0u8!p;WnGZKIg9>COR@2q74dt`#{FWJpv5)hEZ}gA$eE6RM_r8-K&7>4n>QM&saV_h`d!kN zZ4O^6zIH-Z7TWX@+ZxxjaA_o}s+Ita6`7IGFdb&~^gU$JShGP&aMCFYt_ih_Fv;rh zwbp4DD(5Ta3K2O4==Y>{v~GxO%3rH?XwxgCjb40{@%bQ4@m4kB{S4fFed;8uL6-c* z)ejYaSR*m9dzQ@FyL_^jRrZ73)c6%1c`GnJjynmKWIsbDBgIW~on(?aiZJS5{C7;Q zT;7hBOw)R{ITsFL^OJ0Mdy1xi9+}T?yF`?KL7$y8DJ3pp)t_NrlP)LPL&IdB_nrUF z8?B7kRYZ{4wcC?SHd-*!^92T~8$m5xu?RGOPO{=z^Gs0aX%?-P0=Bb4EDnpOF{k47 zOHuG29ze7B%u8wq?kkZ;e-nl2bh-X!NwA30-P~lI(WmV%p_8$+()+o))(W+gU-ux! zmGDe5Lnk)5Yhr3bw;SfnSM89|;A=-)RhS{Cab^#Ab-)ksdYdziGNnf9AI59$%?VV0 z{I=>~?-_&A-uq$x3htwQvoDu_$UN598AOguZerj0FgsQp`qAgOkq!x908SZ*NE-=v z-*QQTa)blN4v~&E_=a!SXul8lPon5z15ktN9w`0Av6)_kY8Qb>Qj+Cl4ipLN8Dxso z_^;6@+6L!Ouk;N`JvdPhTn%RP?+?{~bt@QB8<}llrpQ#FzX9IkcT_d8(J7|YR4EO_ z=2IO$C^gv)OSEDemCqw>*?SM|<1#o^U5X|Nz%9_U0Fy!@eey;`kE!7VlpiuLBxDZX zwhD;|m{~^M*%mT($;%ZS@}T)ESzZ8J)YUf-TucObKiEQ(7j;n)2cDy4toU|+f4(R1 zbE8yuyA%4)D(vGU!$c7civmW|b0hg!Fyk+$ym{@^W)fh?`6V;S>KLK1%?Yn@8+85! zDmq9Qk+~mIY-fSgy~S0<4VPr>oy7mdrQnOM96ck*+$?_hn z11CRTCq3biu70hB0p2e>uGgA>TsU}7`cp9%0J? zYk{>DxL$B91IHMz;;JX@L9L{+m(9;yr82N=Z>@B~8U{$QXmNF8(Pv5=!~@}l&aCLI z+lHIiUn&)4M)nKXM=8TYU7)Tv>T+=(c;~7EAdM8ahXEHETgIb1s3xF)AEeE_16oqw zPV?pVcM;2{k;g)fj=}JoCZaU%=FMQzwB^U(Fk~J_lp|_k#8?%hlw+J-ajhkoB(x#K z9I8tF9KS`}>5YVBKgu!l)LvgKfJp-1At)8o5g;!LJa9D?1p)uW0R>TlF4wg(&+9d` z3lI={Wmq5PJ%Cjklx8=7;I5gTf{or0m39Z9bupAG{X5ihZXXwaU_obJ1ntBk=&2jWPOBS*vc&xV^Vo_Qmr|QY6B+cjnzVky1?Hxpi(a!D{ zXJKZ&yGlR!&ro>V(nP9ua1$ffLjG-@jy`KsR%;jYK`@}OU5^5ZEZ+S)%=I*$B861g ze!7AqKZY}^?-9m-Nzyw<*lK`7BEa#3L9|ih!&K)``%<~vldD?DS9IYbNJeW%-~IG& z_J~X%?2du`It|j}!D@+)ZJg+c8to}p8o2F-3#VHKn3ToQl7AhxR6VG~cuM;fatqn9 zkn$n#pH0~nRv&dpJRt&mrF_ceH+3)rGo?oM5aDpJ7#z@lPTTV*CZrGZ$5%%FH@GMw zBruSCp3*Qkq2ptBJA!KxCl2Z|hzxQk+BQ1f%rr3{OmNZW@|I|a`Xc$q0)}5x35OMt zGwmzoX&gYGMyA|(nhs4GEvYn4LHs+;CfDbf`|DF2?c;AN>g@e(SCrAv(>?~HTKQTi z@EdwZ83x&ZH9%-LEYO-r?C!e1inkgJOx$SPx95H7R);-bgOpvTDWD4h01A3X|EHN+ zMH#P*>AQ(SK?9UNtfGq`&AWyId>t3WDxUcLKb$n%n6aJ%aF8hFcPgD>I(0pO9Tgo9 zO(np7`3z|=L6h+ zAc(gC-1536h=+|xJ152YuCMg8ZiAviO~e3yf?@TFnrkw{tIpZlOrajQ^s+}dN`&*I zUT=`G1k@)7zti=YCY7yR{pf8fw|b-00Zs&HQkv4e_%u@F*hw;O&4fHDBaRCeV)^&m zX2sP>%x!oJOgjxanMGbgsgDX2C{!HLn#X7ciB?uA5rYLFsvVocP*_?OJ+Lmn(C@o{ zV@nX^pE)CfMt%JXO5M0x&;n4De~=y{yZX~Da|~>5J=ffnyetJmCx4}Toi}d;2PZ9_ zq}=ZXi}gB0(z_S|!O^`_QINho;Kbm@)=tB5(6N@QiA;8eQ~HCp*}Fza&9|af0W$j-#P{! zxrBh&n*a^u{unf$y^ep5oCxjtS3M^T_X+7kCOSh!qMaOzqzub#*w9+%wVScbsWbemoqOYBv4PiGl&Dp(+jg7%P;pm#+PQ@GEKgCCX{u!Ui z2*(4l7^@tL$gRp38+|fixiPI!5Ct;RUiG%hCI8MrbQZV$Y~~3?$*c^N9Vj`P=&BGs zKuu?D(!g|S^t)q2-B>l z?+JnQ2XZUP@?&6y{DVx1?E81OZCGL44wB8Jq3KC%uC&n#mG2-oRutlh4)xBc)Vh2f6#SSg*hw!w+gB3y& zpLcNwY5JX=HH8`c)VXSZC)1(eNqL=LSI*oaAuKitvv)RR+=pm1;C(+V7613#Mu?8a zH8JtVvey{x8ib!Bye(q7(kJV@hH1D!U^dS1p1~lV45HJ((@5b}>e!al$R@i0O@4f) zIz}I7E!?3X@+G6v)mmNjhm_F zPyk9AfeZxi=%ITgR_SaB=0r95J15wtVRWe!#WLT-Ze3kz)-2`F%aaMkIe_!$#Y*i< zY<}l#7@Py5v+7WwKF33a<#fF*-fbPVu9P|>=TwjXMY+JX9Qb($RZCLz|9#Wfd!rhu zqz;ne2#I7VHE_TH}*wIW!R1>1kl6wze ziTMaA>xSI1P~Sm*9kkC|$?ym~1jo(2yv^O4Rxz2p5E=*QH)BI9F-wzF}# zW7q_aGicm@b=81#93t^p>Q725EY|1w&9us3y?kfn{PPy4^^O?f|H1qTm)`~TU9E+kC8@S&4Jb8Q z^{jVY2jSA*y@eGhyJ1CoJCg0Pay5`MD}gk@5*yQhnX=p@vI5PdZU5-6XF4;v&(l@{ z4qYc!W4~k(&gPG`oT=xG;}#Q0wDw|`5sd(=Xs;APd~$3fQ@Gh*9YQQiK4{JtrD3)I zlrOeE;f~Kx1KpC6c~Zx2=)u%;KVBSLhv=xs!4h{Rz*xYnyb*@R1|2?>uNZ6m`JlQ zv=zS-9#PEtwQVOfQRHN0dr6|nkxMHiT9Bq%wQqAROm4jeS+*@|nlO=>EN31B)z7|i z;*w_;XKN_N!cA4}dkt%l7I3Fo9&ka5Wr`<9qYZ@ILiS=oW3&e#kf3bRmLP_IhxRl` zY0YD)Nez!Ynsu@K(`bCphu>A(szcCOXjmrLkHfpiz$>x`oN#`#cj8>evja=xJr_&8_BG;A>u^ji1% z$KA6i?K~{f4w$~dU>q_!b_f}NfPW^1Zo`<^tz>1U3iQ%xPKfoMj2zMpg&vuTbcNGv z@29(q;1a`;62PQc-fC>J++21u-S*hn!PMbs_7CYBoT!|PGA90c3o=Zh2M5%KYe~cT zquM|k80>_>H<9hK`n+dLo;!dB>n9BPXo1L&4uUb{5~p6|y5o_RaY}bi2q7CzQu0Hxt>4<<)zL8(G zoaif*8$Lc|)Vhe>U&+W8 zu~=J*Miz!1O7mh`iFn7VZP~%vuXP#%^`oTeOwwVib62-wo<+R_AnrRv%#u%Dk^|ib zoyG_drKx-V;W-US_iL9}OS8wbv-4X#T(c~|KJu_MagBL!28ym9Bs=>Lo91cUW<>s& zBCWq|BoPVHq$5&)FT1a1=!02)aMFxCa>Ub|I>QhqtV#NS47NXkFa#ptU8qzi>+)OK zj$93p>jGBjme>G}!QK|q5NJ_tLZ zI!r?ObJ)|4Q408P>oj2+`*Xmy93A)S6sY6<&q|;;#)q_I%LiEES?}8_frR7$d#iFx za@e;(VjhowYTsX76WZ#xPJ8IPBz(GqlRap$*@%ffDh7<|`Z1xmiO@v&VC;(Y^xmk> zwcG_l))?u0`y1$6bml`;a|0C?@Lp@ETuIz&w**DTx2|tPUK!S}f`tV%ah8EgXxdJV z)63mt7~3AA8}a;O$4%HCmPg1N1a)QuPN$HPun!i0nM#<5eP^N|!Y5`yW<=lBJ7$F? zKeAR2iyo}V-)pRdGRwI|=Ty_L@siTBH-g4hlUrQbl`M z`J)SnWmt^gDQpV8FLqk1wHcs5juZ?VS>GDnYs(VMVWm0Z9U>~I zKFSt6IsSPwpgx><6E5YTyC>6J(pdoo(!8mlKy6xQ0j&zXmKpz}UYKiuW;Gg+rKSrR zQ+1$VaM*VU>#@pYnqb+9Rx6=3v#S#*#&yo?4o2ZQGkt9h#6dkl7E$q&aV zd7yA&DM)19M{gi^o4?%#6|rOcBT!*>xF%{Prx>O=qo(GZ00^b+VhMv=_j#tmb*A(Z zLm53_hs)jc^1#_|Ubo+aGf8pYn(ok%?ZdB^QKfZlnrXhqTZsf;D-5zF>W|X^_FZ;= ziyUe0t%LvL=JlZB2oU0|G{o22itFN0yMAAhWFX#{+kW@N`jVsCrz*3Gc%{n>0CF|H ztBCYN5v{AjK|VQw(AS9vOZG*Q3zM!sV+F!H(^DIddRgFR`(K&@o$f7@@VebfH$lLs z$6M-hq9P>fI5|e>XZw6xEF$*h6kJPx3$?688A}MTw9c0nvUZ4Q2|Gu(pvGQD>Jm%b zq7AXW{bfXfxoUhEd=mK#X_!inw0;`wsVskiCaLnWW$)1J-+;W-xX4tc9hCK}u`hjQ z2Vo825b)41d6XFN$!w?jBDt>7Vvm0w9x=nF&F~$pP^ur1n6v5#Sw~znt4Y9r+SFto zpPjj71UN$psIwZSMA=^ai&!qnu#SJsO1P(14BGXegJ0b9e-$;+$Qa7TsXz;$oZ8cY zHq3}DJSNsfgoguo*U@4SdDV#Fk4{Ts_M%I32hNm@8H&PTDWlX^J}*4?vQv)o4FRf7 zx!P&HhS@?mf)uoqa#S;@q6!0lng*OIQLn+3UxVznqt!{gm}iid_0d68A#h8tqn737XuM$wtjf|LUs^w5KPjcKYqP$8<= zq@yWi43ak&?4O&)|2kBEx;lJXx;khxdIO(7FN_NXoB}a%dU93X9$y;dIc&s&b>D+2 zN>0qzQLxId2_7~?pj(&2tzsivd4LGh1EP+gyD z6ahA`vzBL1nAMlk9uIH|&ZhD1xiB0b9p~CCRO8C!qR&US(QX%igT)&8LQHJ4VaNP? z61GC^y|y;PzaUz#sBV6V2x(cYCGk_}2BHgo;5R9hq(-E$b)Dg_d~=M$&5J#QcCCKs z=M)DPG?8(!X6EeJZ(C25miR#!gJE}2*`e+)!(($%2@#u<{6I9D6!hAdG$1jsZP+(4 z@DEHaHD$ZtJ)H)Bdt*O2EPF|4C=F=hP9#CACP~t8w;#qV)M)#rs%u8nIO^^B=ix-6 zMjlp|u$MmR+(VDooRfV@5>M*No=6cLWLhA={7~|HI8;g_0tnu6NAvRFis z3-C5a9eD<`4#t6Lgb{(=ZC>y>&IGhSey&#co8sx4{Oucmj8xQfD|LZ<9Mdt|O?9)8 z)kYPF*Rv+dKeH6|tI{q(NIXHf>b!X@OPO5c7WdV-K7K0DYOE&y_yn&huLV=o$j|!k zAp~_`h>)nx3=ZLV0jH35Z@Cdwgp8*f_-AMi5vTNK zclKr(vj#7^{@#H3c!lCnuYhQ3M!yfW{fH}1mGQ^2)|I}B@Iz5A8e_HTyl5Bs=@eQ% zZgc_r&IAPIibq)|*W0efHvKKZZApTCq*HSqBxqI&^HHg^p5#0 z&89Yk-eQZ~WIZ1Eukv3GPQXPC!rY-jN<}ozFue0h+N48la2raDlUiFUMUPKjOf+Ms z?ln$sg#^Rq#HbwbS`R^V0;MIs!_2@`UaFY;p`g+B^ZzfX)O&bK#mhl}=&JfLGb1DN zGpj;>)xi_I#54PfBgVVeDeFN!NG$YDYJ%Px+#X&lWZ~DH$u%N{U9=m;O$du z&)c)#1)cY8*TJ7W63uk$1Uh7>XMXcYqaVPu4Lhq~EBd}T%-fYb3RPJ>ncJxnMO}#m zX5#QuaRrthF2ZDY%z@$iwU3^s6t{)#skv!?QljKK<>&@gG-0s5Pl~P06?&9Ze(g_q zW2Tz@#P>?9^rY{-wm^L2x2j`Y9O#~@i{W=&?9s|7)mc|g!VIiY8*UL(kql(as;3!K z@iwLIV@B}ccFCB)!K`7Xp|Utag!~t#S0-@^Bzq>LwE$SV)JFNGh8LzjNonG~zh+*4 zeTx6}2T+_O91KDf2)?>MKmZ;Z*Acgf%aK2^7nTpB#(ca`pAI9l0zJsIo@!yfOM?H0 zxE(XoKXtGZDMZ`tdN8iG8o@D-;x%DOT?6Sy0Wv~W$-bFkYmuEOyqt-QN>-cDUx@DP ziB=1~!R}JLn43gdY*V#KfNPN0-wh^zxYo89Ixpyis%h^+6Jfi46p1GjTqPj-xF8Gy z)nGA9fN4p0L~xEC+@~C&4`Nj>=E-oc14HeTRdD4|%Xx@X0zv2FF(eBJ9W2UVt6MKY zD(~QzsF7S(O>v;tDZkVDc3feeVC2&kKS!g$Lr|(H8#ifiug4abH;Tn3pNA=bSG9kD zd!&40*AG7drR#&-_jf+Zd!hK5Spi-O1Cb(Pu-XJ>9^*=H@Ejuwu1J7pZu1c6 zJ5TB$&+5}2AE4YrhjP3{>I3@5Diejo);i%dFNFv+(1RCU zCsqCCoBz-mhWJX^5bp8&*`3j}psr5wTPlan{Le6LDno%I$id?qmSL2(Bh~cE`*w zZ`#+=7Cx>ZCnvf_jyd+e+o0s9gGS@~3%c8cr0-3~W=T|Nxd93FU3)}@p3gaqvW%?+ z!E<8G^;BR758jk{Xy=nX#-V1UE#UboXQ+qn4zu>kigRCTAgp44Sw$|~zk%Df`0e^f zOipW_0??fHePuH;q=FeTeoe(!`Q-1egA*>SSdu~T(!^RHcGQ?ryV~Ouj0NX>5en|= zKRhn@jyY$oubzy=~GX$=K zmBskfRsZ7fZu^RV!!=&SzZWLgV$4TYQ_Fe(%#iWPVQLVCgw*#T_bC5jX=nu$j0b8u zTsR>FY-gy`M^xK*gM0(l|2#01quKgHGEsvyzK-zu3WFG|!gq7+?t0@hdp)B_9DLVkvwv&`5mR#Rp^&o7K5dWA)|{!o_AHIOMG zfz*#)ffxj+*+0c5uGv=JPQ!IDu_aC$Aje=TELEe{VpuTLAmZJmOgDV_Uz^1Lok2;v zY3-V=%%g9A#IccdU{ZtisC@R^kz3%8zeh-BH|bM}QJtqOb6hqEGySYIW7WU3R4Saq zndBhWz;%t@CkigL)If|4fhy~_{gYw5>{adRXCsn_Ovevwls^m@^L7UR+C3PNP1nBNKhB!gGT>-S<3*lca*!$w4Z_E_Jr4ozr zF=<+#$V(tH=-iAh=Kpjh6HONdr z*P*`!#FjRauZ@Uzxjn+J^)i8NBcR$i@aENWYBzz32rd*Try?{w1WhM8ZCdNAXYYH+ zGT8Y^V~*QZW?n*HK<$MR(4l0vmLB_EXI=q^3{B1zNj}UjuhIl%jQN(^sN<@JO!+H+ zPXEwd;-S*{osZKhszAw|C{5&Txk4aE5CZ>1=EX_u6GIM>6#NEu(sM{4l~rbS%enB1t|`h{Em8-~iGMQWc? z0Zze!ta(RA3DN*&-zQICu)x1}sRYn}4dRL~PF!|>B{E-_NI9s;^8ki>v-6|~>#7#4 zSQ)UYf?_ls!#ylt4sC|RJE|!GgfSkG&F5E@4vg0^Bf#}eEyWnts@dQZ_ir~NBf+t5 zP_aP#c>J4ew>{%7nnb#2F%lKP3Vj$+t;biJNk(2M;>b{A%|O%O4vYobYPBVQE1hN7 zbwAmmVX`7ev(Vs0_M_SCtjO<0lP)B|6|v1HjZPDl%R*Wfb_6Ar`W>_wd+}SdceqVT z-*U@$4oX*WVTe?8P#M+c=8oEW%EnO1-pb{q?lRCqu}Q$Tr!r&S9~*3 zIc`;7-YOtzgb0?vD_&T1Pe(1(*t{>Xk#xn z{AdYZg|8=O3_8Tkt)lfJ zHh7Ol@Ak!AA>dllNv$_aVGm5R6qQrG7+>y5Wb~^rx!u!D%bs!mbm#HTYODO1UT{5WTd#u+ ziVgp&DTnmy|v#9sox!jaJJ`){goK-a2%_?NxS z5{L-I-o7n2VS&KV-kraPK922X!B2H!VXdd)Sg?NvL{56QJ0!}j8W13)+R`OVN>L9# zJwJ8T-*#0-m2UIbotrbR1@oWV>MYJG$_@0j#zpgghgLyA?Q=8m?CB&-GLiEtS^iRR z|A3%VeUx>h_vB)($VwiGeq{mp6R2`n93VT2#3*(cG*v&2Bbd&*k3CwFq-22Gph(r2d7hg1ms-e|aBF%Wb} zF}QGKcO|cT4BBkx_kIe_)Z0ktZi;N|_({|oH#-h>(ey6SG&@@? zV-Bu#$5>`+QXe;BU_{U*VOXH1RXE(Gxw~(MK$X&=MxuENDM}1GJ*) zECJ(?7eHjsCn!FHKt2lypvF9v;=I#+lR5tRd@nxTBeu@)IM$3tEyE_Y8{YNw!3JGD zBxdTw4!8-Drx;>2HzV#kcqHy3-4h6eVC6!`szE@)T-WxqP+px#lC#{Qw9)m%%M%Pk z;A~Opozgk|9X zoPTT=9H1|xVA6_AS|!a{v_S7OTjk4rv7?TebL5|*$T%OriRB{1=>6H$z1B=9jYENG zaOOnxvl#Z_<}L-3{sRxI?J2I|whmM*TZX>lKFD0B~#6kf3=f4=NT3#v#PkZv1y|Ub5N`Hz_KA^eCLRzDgBBSQDo; zU+UTG4nSB*{HI}5GB@ULjB_7EEBxpMF_wrRG1X(Z<0yr4XxDKtxt7t8<)@9{hJgqs zVtqhwy(EA&2F9VC9J^9yUp}|Z-}`I4u~B8wGeZ$o_8Wcyf+x^7NRZ&9dH_6nq237a zo@<=zeRI6!X@oL=_9g?bWE4z~6<{wV=S@M)CxJ`06SfyVl`%~Ewi_}e9+T*yrb-NWHUGLRJ2RJU z4xY3jBL#ZGp@D}i?FvS3+7>V$M^;l1u`KS*-f_QG8^Z&vCKrj=^-$^EM3y%OfBen7 zR_aUQ0f&Ix|CGV%F#8YbF+JyU)H{FTtJ{;j^|xfTJFLUH6UM_hyV9fYN;oDm>Xmk65V1Iw!VJ2cfQXIl?&v-T zDjF&L`=^y-uJ^c9v?#or>33VXTH1qCk-p&sf#qO-P^XpSj4fTi0KH08mlyh=vRG^J z0yb3n0GdrhgwnBDHSPI@ZUPC~_(7@OB@mQc*zNnPI>2n-q}gf}xO~a9(kgIGK*$N{ zdS&IZqS-N^a5vP91|v~n9y>{}e>A1N`p2gv?a>Uo5!FG@dZF1N8NBL=kId!EL~)hn ziHBc*mc%>IEdSW5G(voHu@;bJ0s7ns$Z=-%Wmjeee6LJi$*5VcZ+c!*EoEn}xcV5e z&8J)*<1s~4oO?66i-fX+Q1!|mEdiD5t45l+B(8k_n3hCZBScXvEEMF5qq{3o zhyk)X_Y5N$p&?6;QBH9Wczq9Lm2jtDJq3g`B~ESV=dOFNHO zyuNP$p_4b$nOXjQ1EV^lIa)!!%mj@nX2Z@cZB8jI@%Tg3(D=(%%gh@&qvb|=8LnY} z9jBZ@(VWvZ#~PIx$0(;1yiU(9iB%^Ddg+S=j^D8F!3dtJCML*FBK_mDqo8(-G=VEp7)$SR zDSspbw+Z0F-s@&b`5~?nccFP-gzt3~7t|pQfM!4sh4vf!=zPFh2UQ`i8@fn;e^H5U zLXK*LthWJ1U5s>7ix35N*hwULd1u=&?M8oTb~#t^cS+^{3Pl zG(N@!)Ka{B{0^>C<(wKe4U`&t4wc=l;HCrN73#~b)FM{U|8R^|Uyab&0j(gNTI77o z|B&^juOdL7w{cBw8EV~sB%TTc9IC`UB$ixsfNKMQpOy4NZr)Kof|^Ll`D0d=;$_OO zqC{&WB5*|9IxX&E$pW0_Fmt`^ZQ>gB>ZIti3y&n%oY~J>9l0lsQ6ltI(fnn{Fm{PP zPUqwk14ysaXoooVFGM35G;N4oeoWwrhm(IvRMKUJ0s~RIhSI8kYitAroWX-~?(oSQ z7c=LAMCiGj6h2ae3)k1viCl8N3_XB!=AQnecfpVpb}y%4l3c?v)rC;~4hc>fEQ-H+ zI9A>I#R=e*9#6x1?7Xi=SOR-sLh*yTeQ12<Y;rVT&XhMR*w{{vJ}5e zZ$h0}V*@|UM8Ga%dBgz3rj(=_OW;uUwTajSCPN5+{~vILq^ZV5{ac}uCQk3RhlyrC z?3$E4di*zF%VSP&X7RYH^)mt~=p{d67C1bA3v{=FFS7yb5JP_5*o!E8 z@ayxiT%Z8oHo~uR$`uS~5+LmH;+4K>f*Pg|3@pNLiw`p&5b#dS*$OmqSOrGnVn42Q zWtQ3k)M;IFjplAA0addN(wzV1ykw|Sdy)hmuStoPW=zjg4Ou!?2h+)FhWqtxlyr5R zu*-NN{JuMXq$9~VNWMyrD5NUq!=x~+QvC7ECdkV-r#TRA^gsIH#zg!&CdKY6zKU>K_`wk>F3x5`c+q(S1{}8 zY6KbjC;`cfPGrpasVcUdFM4#%M~jobGQKUS{#5pV!HNqkwr?wFkd)qzE;RhN!6d7^ zc}4yK2#YIQeFowr?WESel!ha;B@%~qVY*J`{FU5=5UrY492^Uma9rL-0UgMRz*+K7 zGy;{y_fVG=AngQ+AO&f}UOV4^=V#DMvy|z0-n!dW2*)Sz$f!`x+&%>k-AGPKZpEE>~=P zu$w43r-??+E)$;c!-XhbOu^+uBrXW;8;^#%fXOD$^b7P$)&w~vG0kPbvZF%DtJOqo z%uSW+=>8^ve`?9io^`*sdilpMbeN4p=ez$m1CosajNR+2Qr|UoF`1YRA70E)=kJ<- zy|B1Cw>v(^I=VK?bTNd?om#G?zN}0&zF6?oST6_{gp3E}g>~(uX7jYQ26oxeoOJ-$ z2a|6)d)6ovAg@ynCnl8mfb@kijrVl38CpBxOASn-AqqV%ZMsV^upGs|-WzAF43O== zhDHG^LLfG&yw|wQN|`$fE^|GY7E-Q%n+pu~`54#sAZiN*TDjEn%{U&N(MVL6FK1d29dg`!pN^0b3IC%%7^cCW4Q@YzVN^f(Os6C=MB^(S+B7v~< zqW$CA`8HWdoPk(U)fE|))k{6M=-tx)qs@8dg6mIM9O5i$Tr#7RI4_hQfX4gu6tE=d z$=}f*&6(CY*f5E@0t0tjshg=2rS#+2AG4OWD12$_Mtqqh&6Od;TPMV69tml|Xl#nX z4cf^SW%fZ(rjx3Tf#dH%YOtAq(9qKba|(d$@m=R}mT4Ut;(B?R{(LP80Ort%w#2gO zKwS9$zTOan=P#k=`YOf?m7o0+%VK0BWWyw94$Oc-&?X)X+?S!kZSATvbe+ z0h2`v7m7o1FVc$@cP-B4;_hz6T`urZ+=~= zVKS4MbB>oZT!NO)ce!CR)f@w#(o5(tLcY_*Fx@4YV?RZ@Hj75_r6t~WwM><&F{+}e zu60Gv!M;I>QDlV`L2Su;E7NDV6FWH+@Ym?<@*{o`vWD;Yn_|Efp-Z*CZ|;G*4x{q$ z(K_ub0cXP}0R{i@qXEW=xFeq15|DdnDGH!$5w{$?W7_I{k>tf(u|KkQK-(f90%s@+ zG3}WNlYBPrv7kg-P-*Z|i<)T4^!;q)nwKrk@XDnHAwtg6JwB$#5S%B6qXaDH z0aQ_mLGCeGSDV&{XNIq`Zv0$CEz(bPAK&Dyz7`a#)q$#F!F-8wmv`kgz8h-tpToV4 z8k|2N8owQM=_^DgFQB}m=#5N&(eyVE(h=%GUu#@3{Ah~VtUz!aef++dF#h>!qXhp2 zvVBR%8H&6XAH&OWvBr=R!rb%YSr{lm#>CV3S-A4?Pdc1;^+vt=Qr*W_PkH-#{s8(_ zus!wEl*;O}N$A~0;>6BdA+34k-^b~1y49OfZPrYYs$Mmsn6j0$?%KjMPZ9F60+W(k zymV=?^cQa4+ExrBZ!NY$8a1(qHQcMsHT!?{UQ3(oiyga1TZ>hZc6cBum>kMe7u zg%7|S)hYG6wz(Z=dtRDEHPe5!heLCV6~Qv$flvo3*cGGH-I|Tw|Lc4F)>Gd z=qN18u7vM@C}dged5=1t;sG56mB=%{_D{T=qdsLgG&${G^13wF_J|LPM)?JTUCnd{ zC(9(iVt1{brSnd)%Q||E7BC>X0S*@xU&{j^+5Z%?Y^QG$JvfQpH== zQ;YEAkWR_LQz@Ji5LPyR_*{sI;zN;4)z(x})4~64dE85bJ7p-&(OIzPk<#GzOdaQ& zqF2$VjY20BR^cAuYXaL-mR{R0gv@=r1D|l ziR4*IyCV44L7<*EISY=!d6Ht(6FU4%Ib!M3mf{o*oWC$IF9X=%sUMidH!0v2j}>T2F(7{Wo|5A zr&|8`+fHxgxmw5@qUHGHYNM!A0Pe;vJIXac-=ogw%0mT1inU4S zxK(z!NL<0-5(9|u9Fx#-YxOqM8$lknuFt*fuj!Ka`QeeKA1IM!wC>2eCAj2}NTR&z z_1A-VMic($1HtIhp!~402$_;RIqUcSsy0s4T`#Y>c8c8XP0&~Q7o}qwj}QPu&Y9UkzLTPa0h+vMt~dV* z&G6fCGBF-^p}b_OSXYcAF`$=u2-E9jO8Qk<-e>DF3w=w@Nx-}XC;&p?UC-?EWGbNJ z?B=8}O`s&%!&U-s>~x>t9?dG}Zgx86K(v5k=I7-U7}u5^K1T&#IU4Q;MSK5*j?=NC z;LCO^9e_^KEW95V)%Ka&vgd5nt5=q<%-%zHKpdZ@N*}G38lI1R=||A?$M0$O)Sug# ztxigIF`pQ_@jB3_Yj(r;bzwMRM{jrsX|s={zYX_sY*wU_j zpEj>EAQve!@An`#_Gt}e=_H13olE|?v={0w)Qrp02c1>Q7-}cB7_gy&b!dmxM>xz} z#t6tWjNEfG1)r@Xk9Bcc$4^gmcOuu7!CBF*AW&`|T2P=;7n6EaZa5%@T=0ox#_lPLgVgIml^geRDfg-eK>wb86 zWMwu_L0;rM=~D{V5!W`CBEP}$V{xP;YYFg;MfDnyEFIS&PRZRh2~+?XQAW9=`fHYA zGD$+FmWWnr$=L7YD6$VpC7+6@?u zQez43s*;%^H+V9G34GGIzMQr=kRrKYkBb=jFFN;W(OgR(!>km&Z`Q6i?Q7jkPXdGnaL%wcgo5;3?a0S>3KX){HJFXS@Vj7nYWPa6ML>m@oScPo&t$t9wZsn1+ ze||vZQD*0Bh)p&c%ie5p^c!2`l=DX1&uL9QTgs6s^}acFSD>r1u|dfB1*ozqVmAa& zW4x~TvuSh*>i!OYx~#|ujf=C%aBDaFAoI5~X~fduEBE}5v7n`swI1sdC6Q7@n{U`} zuF~vX4cqH%+wt#tlD6hJyK^dgbKhZv;GYMMmu+7E@MfPN(0M^%pUem|NDa&qY2+SC zTVD;J*dx2WX!g-@b7HQ`q6GMu)uoWVTAE*+;*v#8bJ3FU(zEhuHgLR7y(f)=*bGI} z;3e!F3&uAwE6i{rOMYWe4Rnm}N?x1Omag(1sW z@2}`HqrD(Kd|Cw@e;0VqpJ&ef7|3em)Co1~S*6ycwzbl`!6ph)uLFp!DW+a+xi|V< z-$$=saJLbw^9^4>=eX~Y|z)xs_hX;}Z)9Ei8MoT#7**1|aaHtZ~nqfF+2F7cO78c8-AtroaMU5C`ur z#;8@r*#e0ip5!GKP*uRM{=3QC0~VRUek`L1DrNQp+jgO10HMe$&ta955LAA|;ibXt z_>lGImeZbFHOziIF`{f=$hTYA?n}_<(drxKYtri^D~n}h zX{YeR_tCAA_l!oJyk<3Y!Sd>30|IJCn<)w|af*hH56pC?cOuQZO7;+~a}X0_&3GWU zxj{$BXw@3lxvDDC#dq6Zsd>w(@frid1|P3xA*<1AzL{5T{J?zu5eZq`pFJ`2 zk6dMk;t#w!AUY^>Lb0oe`r^gP$kQY_#bjK;x0Yw%g5l4R?51M6roXeogCPPA2{E{b zCR=PN+&!g9rWeQYC=}gP1@D+}H|T8nh80nQtkDbq@K`iMIt`PXQMTHg!HVw$Rzpre zhw$&cj^ph|EhGVT1B+c1jZ+cc)(Gms zkYWG|p;>5Pc+s?2bdfh$&nR*3^upoWk1^xZ`XmEYp$~a9J>-m^b#YF+0JVg2zq zgU>9uuOh_ilq}5=fy!`+i;b>q9nP&NZMuZIgZ zm1?t2VXd{*>1@~Sd?*pI_yXnQs@G{~^TLby&w*78lKegj+EwB%OacQj3zC4V`A~Xz zlJn`^Yoa1M3u>eMR28Ud_TW7R{sT$I7Zw*1eWXqdLHLNsTHSY+d0m$*j8j7?T9iNs z#k#QBP9IX8uSsqKx;96b-;$|<=YYtMj`xRz0SWEerUcFbPRS)qi`*uWKPis3qP=F} zhuAwqow=INO%bYkp6R*|4VmXG2JVb7HNI^?N14s;MieNj;oo5Dd5*BgxoU#=K=mJo z&-VP48i@`6eq^Bf8pO<9Y?&r9Ws?ESI?7o*d;|+d*SH4FF%J zH96;}WwiK2G$f8t^|1Jxz4sQz2_yEy#bloz-qHU;l@}DIUblJr5F7(G>;;Pf9~|e) zL+Nq+qf|KSSpJ5!3Y0u7jO7r>THG_IlJ(+d>A-UFSPZq~@0{aJq04y`0Tzj}FT>DG zyA3(9vgY?yFzlCVL>@XE?xhJ5sDmHH@*TV7AP)-Yjzp>a%vK25D+O z>F08n#J?Nwa9lU;j%4gv!7} zYP$c)598knPwkP)6WKX(kilwMr|A;WXUb*Rx0%p4m}zIRs>`Q6LDs~*YY4Pl&(yc& zhG)26-Dj7lTG%aIo`i!4R0?WrL>h&7yL+yj?hj$eoyC5?Ur4>#EZ_eAi;%dCji;7F zsL>zlP!lkwjDR-osHg9(A0U(N+6QDET$9dz4U^q$=gzWiN~~(5THlt78&0CsAE^4Z z^{vclkfMKtZC!%=^R7{tSi9gY91agAG_O6i`U;C*q>0ka?iDE&2>3DGN$<~+g#008 z2p1C`t(*10(#EW}u$>P0BG5~It}JWOOu?6rN+C$FFM{@D=}0oc z^MOBR^R0Bzl+YW1>B43nr#E zW^xjJc7#82tIM2PQtuurjEXFj`KY0Ol@ytnUQI6Ra9I5XBW9F%$S&?eP456-nDAgL zv?@@n#y@Gqj{d_;V;SEH>+s+A-Ll4s8a4e{nWU^ygrnIIVAf)z9(pa(`|DwM$v@0a z*h?f4`wMW!rG+agz7sWaow^c0F(Hh%A{c-Y0bYA&B7QupKjXfyRSHTdSQ^%oC@^t8 zl-8H#Uee2nP)t#YdsjrkUO8tjUO)mn-ZGs|eelHBeBruLKADvcyk(8Q*pH3X#p}$D z+uRXW`}H^m&|BJQ{4q*`bhjrETBe8F+#)-eV(8qt<7dRo|IU)tZLwuDbF(?S%~R+toB z(_d3#Xc7HMr@2xj=_HPVY9p7sxP7oe4o&5{Xjdo$7EZrhg3~WOPU0Pz@RENKW$46d zJ(yR-SmTAa=|rN}>-~HI60s2XN}n8Nu78>^c+>pxQ{R`-oVAO*!Mb^w^8GiwBZ&FE z$DW5ot($`J5XS4;_+^($ZmH|ttp8PVIpZ-wdYKT$);{Cc_S-~7@y0zzinJ}T2L5XI z9VHUbH#lp9=W7q6S;d~i*_O%trREj({27y4REQTw;27~h^@iTniPvYm9>msDPmGv7 z;nXngy?_<^Tbs@V1JrZHa*#Q5@xq!hqvf_7*2GP+TJ$Q&I(QTtiD>)nleCvrn0FFzl^f(%K|31 zJ^E(n?XVigJ&X9!uhPvuQMhw8+DKrW?4N=IaaWh3?6>#|n$tT>HiaJEmTYdLhpBUb zKX+mO+gmF58@Li$Y2T*(*DHupX#^VRhio4hb{}fTeA%!xkQjjvcT52%P0v2 z_C8X=hdfv^+?S>nBAr@NsU1A4-;9Wb@#+~(iQ3cKF{AG10JfJ z{oRWL8=3+k(`bf18wtq1tAxPHQZL;W7?HHgP|hQNpcrya4PY<_34w zYf{^5KYhnndH2F5j`D8Rihh@wEGB$+y6L<}v9dqo-AK9v{174v44WOzT&*Xy9vZ8? zl_8iajZ#w7GtY4JR6f{)+Cp*QkGd+ePh$@{ zB`8br_BAykZ;LY_!HiBN^beAKGr!;q_c-4dr*c~fCa)|F3@y@U+)^_KGa{w66G~UY z;L+gmFY&J`-piFA+kZ#dFxJmTLt&1i=DiDX2RV9tbU?oW6CT!|kUXGReXX=?99BdD z>ChyLa~j4wP0w`A2`QBoErf{dyK6F|I4BTYZ@;xRXm%W{qGiV`Pz~zDD~7^-$&tfU zEiCwYtz=AoE?kCq#rF?==Zce+@R2~H0iI6JI~k^+%$_Lm!M-~`krsqR)<*Ves43eS zf#L05YX^}cxZCS*L=~Xdpagw6NK02x^Kuo_Dq><=Z}M9u?(+2K=c-MEKqudfvAkuY z$H5A)Bq89{wYAuZ7vYGZf!{;Xv~69Ki7Wnj%-L6WAPwa2Tfxuo50CdJZt{Os4WnH zcc40^kyyhc#`e@(C7jnTxTb1w9Uo6qS+4yqs29$d^a+O!aWJsE_CB4cwlvRH=Sp1; z$|W9~PnIB9Islx0+Eeb4-$Y(o^r_&N(tpbGWi9(md6x0SmQaWSx^A(^^F6IAWD-L^%7QJMX#}y+B-FQIP4->KKAFyE_IwUF>BtwU(x|K`3L2Qq@81hzXxmws(3lD z<&!sgF>RfLOu_puPj)+ETj=we7DWW_H6V78Rr2Q))Tp6D5`tWp2B+)b5*Fx#1$A|M zn^$*av^;AVCbnccm5PzEMrgXd(OoyQ(dmJT%@#o;f`3~o27UmPdlA%}sCR(t zyDn`LZzIGeGmGo|65_oQlceJfVQ^TP~oDO&*+(YtG?h>Z` z+!x1KD#P7wkByC9LGM;a$jSl}nwe+jGIue65aQdO=9^wfzdb;5khd8sn?)T|<)RXa zpAOFCc}voA9y?XH_N(Lpnk~82)HD=#7ez{5HqficY(gKv@&=t0j0j^y##sHs5v0`9 z37isjrR+JAJcBG7&(?$p5S+`GWs%KtE^WKS=pWuZ&lJry1A+~ z) zm{}escLcvNsX~b-zx@~WjMo?4xeikQt=5Ib%$?(%^UvFF<}j%Pj$ASFIL{RQ-p!x%3!9aDq0$9d z>dZcA$;o94Q^${Z1MxyLrUssjr!{R+;=oU$P<%}cg_$Bjz9Q;Qnmgq@Un~BOR-#gY zZi!d5>_fhkX$Ngn$r5GaD%}rBr@*YUR%EYo?wS_pWi@-3@Pu=P$=b)MZdZk>=~|gu zn((EI5zpZ<%tt#h!pcBa$`%Ch*_bD8`$+5=ZhHE22tZl=>i18MU(^ol)eXS9bHk0J zq#qX=Q`DoU%|HvP5L_bXXERmsKeA4^VH%Dzv7D(h@u^NP*jxK`QNUdih}h++OKLNj ze&wbdEsLsM(jFD5S-$O&okqjM6fr? z1z)zqpj`W9+nNknAqLdLyQI1yU_YY*?O0xqg_NYkyieKWj}kx8f5_XpaVxwa4S6oh zid06O&w{R9>V3BD;oByACU!(@0*` zk1UtuTe6Q?>l5x=pds81!_w-u-Z)K|UY7t9LPP@-rO|?vJB_J1I(FeLf-IPf*=-Kb z^0z;|C$B!_$yy!Zfu%7dUo^DE&wcw;I-^<7Kr51%k|E@*LO?@n)fpt*hh!NoKeHu1 z1pC>E^u{!EhWY{M6n(v7*oKi{Fgz4{dr2qIzT((52O&9WZl54I!w-OGx?bYX>Ssx} zwBGXwW>yWnK~>se(mCvG+j`peHt;vY`lU&iBCyh|>5d<^?Dw8Bma*}b3XZKkw6c9r zufJ_@*U4J9jYYSrVu{!u9@2pKzE?eKWNZNeh2Kazg{cl0NHdB2T%b+Mt|{jd0!EQQ zb||zm=JSs7HzvdJvlL%=}=aym!KuI$x^W-_z;3e_YsUV9UZ3{htb3W=0|}2yOkl+tCTCL3Pf zwa@pDUR46i_`N;GHfaJiZ_nEkmRA9`OQJ2Sj5)Y#n<(ZSNe7s_#5UFr_jHX;YP*D3 zn6h0HcP2;?9|q~TugFCLf*Xk+bw)rar1o6c0zG4(fx!oxjkJOV8sS2Jk%HcT%Jv}Q v|0vt%a@dgvFvG#Ug9G96KFt3U^8b(c?-c(919?1E From 9f147b0aae9ec7fc9a86c60d5f130887991c80c9 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Wed, 5 Aug 2026 23:32:39 +0530 Subject: [PATCH 04/13] Add financial reporting MCP server tutorial --- .optimize-cache.json | 1 + .../+page.markdoc | 293 ++++++++++++++++++ .../financial-reporting-mcp-server/cover.avif | Bin 0 -> 23669 bytes 3 files changed, 294 insertions(+) create mode 100644 src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc create mode 100644 static/images/blog/financial-reporting-mcp-server/cover.avif diff --git a/.optimize-cache.json b/.optimize-cache.json index 9c8d807ffbf..0bca72d4577 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -643,6 +643,7 @@ "static/images/blog/february-and-march-product-update-realtime-queries-appwrite-skills-and-new-database-features/Introducing_Realtime_queries.png": "0b632e9ceac3a763f5ba2ed50ab54fffe389fde34fcdfb7ad99599ec7ae83b9e", "static/images/blog/february-and-march-product-update-realtime-queries-appwrite-skills-and-new-database-features/Relationship_queries.png": "2d9772691f05b1be3ec6cb954d77babc10d5666c9994fe3975d2a078facc87b8", "static/images/blog/file-tokens.png": "23d2fa4a88db2d9548f43f95df15b5ca60d512481570ed2d1b3d66ce1b1f504f", + "static/images/blog/financial-reporting-mcp-server/cover.png": "d5e7d26b27799982db7106eb3209207f29ef78004907b2cb65f9d96fd61bd901", "static/images/blog/firebase-vs-open-source-tradeoffs/cover.png": "1be4185b4fa90c5f37e96003a74b8b55c31956d0258c70000fdec0990f2496eb", "static/images/blog/first-pr.png": "f369419a756ccb2c784dac916d79a1cc33317fa4c43f37c7f41ae62bf0a603dd", "static/images/blog/first-pr1.png": "256144fd88d0564c239cb73c16882113e4fe2cb23156fcbc4f15f6f70437faaf", diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc new file mode 100644 index 00000000000..79efad9aa03 --- /dev/null +++ b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc @@ -0,0 +1,293 @@ +--- +layout: post +title: "Build your own AI financial analyst with Appwrite MCP" +description: Learn how to build a financial reporting MCP server with Appwrite Functions, TablesDB, and custom tools for statements, cash flow, and portfolio insights. +date: 2026-08-05 +cover: /images/blog/financial-reporting-mcp-server/cover.avif +timeToRead: 8 +author: aditya-oberai +category: tutorial, ai +featured: false +unlisted: true +faqs: + - question: "What is a financial reporting MCP server?" + answer: "A financial reporting MCP server exposes controlled reporting operations as tools that an AI client can call. Instead of giving the model unrestricted database access, you can define tools for tasks such as portfolio summaries, account statements, transaction searches, and monthly cash-flow reports." + - question: "What does the Appwrite MCP server template include?" + answer: "The template includes a Python MCP server, stateless Streamable HTTP transport, example `echo` and `add` tools, optional bearer authentication, configurable tool timeouts, and the adapter needed to run the server as an Appwrite Function. Replace the example tools with your own domain-specific operations." + - question: "How does the Appwrite MCP server differ from the MCP server template?" + answer: "The [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) lets an AI agent manage Appwrite resources, so you can use it to create the database schema and seed demo data. The MCP server template lets you build and host your own domain-specific server, such as the financial reporting server in this tutorial." + - question: "Which AI clients can connect to an MCP server hosted on Appwrite?" + answer: "Any MCP client that supports remote servers over Streamable HTTP can connect to the Function's generated domain. This includes clients such as Claude Code, Cursor, and Claude Desktop. If bearer authentication is enabled, configure the client to send the token in its `Authorization` header." + - question: "How does the financial reporting function access Appwrite TablesDB?" + answer: "Appwrite passes a dynamic API key to each Function execution in the `x-appwrite-key` request header. The server uses that key with the supplied project endpoint and project ID. The demo limits the key to `databases.read`, `tables.read`, and `rows.read`, which allows reporting without granting write access." + - question: "How should a financial MCP server handle multiple currencies?" + answer: "Keep totals grouped by currency unless you have an explicit exchange-rate source and conversion policy. The demo reports USD, EUR, and GBP separately so it never adds unlike monetary values or implies a conversion rate that was not supplied." + - question: "Can I use this MCP server with real financial data?" + answer: "The architecture can be adapted for real data, but the demo is not a production banking system. Before using sensitive data, add user-specific authorization, audit logging, data minimization, stricter secret management, and compliance controls appropriate to your jurisdiction and use case." +--- + +MCP is moving AI beyond isolated chat experiences. It gives models a standard, controlled way to work with the systems that run real products, from support platforms and internal operations to commerce and financial reporting. Instead of pasting data into a prompt, developers can expose focused tools that retrieve live information, enforce business rules, and return structured results. + +We wanted to test that impact with a scenario where accuracy and controlled access matter. Using our new [MCP server Function template](/blog/post/announcing-mcp-server-template), we developed a **financial analysis MCP server** that can summarize a portfolio, generate account statements, analyze spending, calculate monthly cash flow, and search transactions from an AI client. + +We built the entire scenario on Appwrite. First, we used the [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) to create a connected financial data model and populate it with realistic dummy data. Then we deployed the MCP server template as an Appwrite Function and extended its example tools into a read-only reporting layer over that data. + +# How we built the financial analysis MCP server + +The project uses two MCP servers with different responsibilities: + +- **Appwrite MCP server:** Connects your AI coding agent to Appwrite so it can create the TablesDB schema and seed test data. +- **Your financial reporting MCP server:** Runs as an Appwrite Function and exposes only the reporting tools you define. + +The second server never needs a long-lived Appwrite API key. Appwrite Functions receive a dynamic API key for each execution, and its permissions are limited by the Function scopes you select. This lets the AI client request useful reports without receiving unrestricted database access. + +You will need an [Appwrite Cloud account](https://cloud.appwrite.io), an Appwrite project, a GitHub account, and an MCP-compatible client such as Claude Code, Cursor, or OpenAI Codex. + +# Test our financial analysis MCP server + +You can try the completed server before building your own. Add this configuration to an MCP client that supports Streamable HTTP, such as Cursor or Claude Desktop: + +```json +{ + "mcpServers": { + "finance-mcp": { + "url": "https://6a73369c003d9823a215.fra.appwrite.run/", + "headers": { + "Authorization": "Bearer test-string-123" + } + } + } +} +``` + +The bearer token is intentionally public because this server contains only fictional demo data. Do not reuse the token for another deployment. Once connected, ask for a portfolio summary, generate a 30-day statement for `acc-001`, or compare spending and monthly cash flow for `cust-001`. + +The complete implementation, Appwrite configuration, tool definitions, and additional test prompts are available in the [GitHub repository](https://github.com/appwrite-community/finance-mcp-demo). + +# Model a real financial scenario with the Appwrite MCP server + +Before developing the reporting tools, we needed an Appwrite project that reflected the structure and edge cases of a real financial system. We connected the hosted Appwrite MCP server to our AI client so it could create and populate that backend through natural-language instructions. + +Add the hosted Appwrite MCP server to your AI client: + +```json +{ + "mcpServers": { + "appwrite": { + "type": "http", + "url": "https://mcp.appwrite.io/" + } + } +} +``` + +When you connect for the first time, sign in with your Appwrite account and authorize the project you want to use. The hosted server uses OAuth, so you do not need to create an API key for this step. + +We created a TablesDB database named `FinDB` with the ID `findb`. Its five tables model the reporting relationships we needed: + +| Table | Important columns | Relationship | +| --- | --- | --- | +| `customers` | `fullName`, `email`, `phone`, `dateOfBirth`, `kycStatus`, `country` | One customer has many accounts | +| `accounts` | `accountNumber`, `accountType`, `balance`, `currency`, `accountStatus`, `openedDate` | Belongs to a customer | +| `cards` | `cardNumberMasked`, `cardType`, `cardNetwork`, `expiryDate`, `cardStatus` | Belongs to an account | +| `categories` | `name`, `categoryType`, `description` | Groups transactions | +| `transactions` | `transactionType`, `amount`, `transactionDate`, `transactionStatus` | Belongs to an account and category | + +Ask your agent to create the schema with a prompt like this: + +```text +In my Appwrite project , create a TablesDB database named FinDB +with the ID findb and these tables: + +- customers: fullName, email, phone, dateOfBirth, kycStatus, and country +- accounts: accountNumber, accountType, balance, currency, accountStatus, + and openedDate +- cards: cardNumberMasked, cardType, cardNetwork, expiryDate, and cardStatus +- categories: name, categoryType, and description +- transactions: transactionType, amount, transactionDate, and transactionStatus + +Use the enum values verified|pending|rejected for KYC; checking|savings|credit +for account type; active|frozen|closed for account status; debit|credit for card +and transaction type; visa|mastercard|amex for card network; +active|blocked|expired for card status; income|expense for category type; +completed|pending|failed for transaction status; and USD|EUR|GBP for currency. + +Add two-way one-to-many relationships from customers to accounts, accounts to +cards, accounts to transactions, and categories to transactions. Add unique +indexes for customer email, account number, and category name. + +Before changing the project, show me the proposed schema. After I approve it, +create the tables and verify that every relationship and index is available. +``` + +This lets the agent translate the model into API calls while giving you a review point before it changes the project. + +## Replicate a real situation with fictional data + +We developed this fictional database specifically for the tutorial because a public demo should never expose real customer or transaction data. The scenario itself is not a toy model. Its customers, accounts, cards, categories, relationships, account states, transaction states, currencies, and reporting requirements replicate what a possible real-world financial application could contain. + +We then asked the agent to populate the tables with synthetic but internally consistent records: + +```text +Seed FinDB with fictional financial data for reporting tests. Create customers +across several countries, one or two accounts per customer, a mix of checking, +savings, and credit accounts, masked card numbers, income and expense +categories, and twelve months of transactions. + +Keep every relationship valid. Include active, frozen, and closed accounts, +and completed, pending, and failed transactions. Distribute account currencies +across USD, EUR, and GBP. Never create real personal or payment-card data. +Create and verify the data in manageable batches. +``` + +The resulting demo contains 30 customers, 47 accounts, 32 cards, 19 categories, and more than 5,000 transactions. You can start smaller. What matters is enough variation to test filters, date ranges, relationships, and aggregations in a realistic reporting workflow. + +# Set up the MCP server Function template + +In the Appwrite Console, open **Functions** > **Templates**, search for **MCP server**, and create the Python Function. Connect it to a new GitHub repository so each push produces a deployment. The [Function templates documentation](/docs/products/functions/templates) explains the repository and production-branch options in the creation wizard. + +![Appwrite MCP server Function template](/images/blog/announcing-mcp-server-template/template.avif) + +Configure the Function with these settings: + +| Setting | Value | +| --- | --- | +| Runtime | Python 3.14 | +| Entrypoint | `src/main.py` | +| Build command | `pip install -r requirements.txt` | +| Timeout | 30 seconds | +| Execute permission | Any | +| Scopes | `databases.read`, `tables.read`, `rows.read` | + +Set `MCP_AUTH_MODE` to `bearer`, add a long random value as `MCP_AUTH_TOKEN`, and set `MCP_SERVER_NAME` to `finance-mcp`. The HTTP endpoint is public at the Function layer because MCP clients call its domain directly, while the bearer token protects the MCP request itself. + +Also set `FINDB_DATABASE_ID=findb` if you changed the default in the code. Keep `MCP_TOOL_TIMEOUT` at 25 seconds so a slow tool can return a clean error before the Function reaches its 30-second execution limit. + +# Extend the template with financial reporting tools + +The template includes `echo` and `add` tools to prove the transport works. Replace them in `src/app.py` with a server configured for financial reporting: + +```python +import os +from mcp.server.mcpserver import Context, MCPServer + +DATABASE_ID = os.environ.get("FINDB_DATABASE_ID") or "findb" + +server = MCPServer( + name=os.environ.get("MCP_SERVER_NAME") or "findb-reporting", + version="1.0.0", + instructions=( + "Read-only financial reporting over customers, accounts, cards, " + "categories, and transactions. Group totals by currency and never " + "convert currencies." + ), +) +``` + +These instructions help the model choose and combine tools correctly, but each tool must still validate its own inputs. + +## Query TablesDB with the dynamic API key + +Every tool needs a small request layer for the TablesDB REST API. Read the dynamic key from the MCP context and combine it with the endpoint and project ID supplied to the Function: + +```python +def appwrite_headers(ctx: Context) -> dict[str, str]: + api_key = (ctx.headers or {}).get("x-appwrite-key") + if not api_key: + raise ValueError("No dynamic Appwrite API key was provided") + + return { + "X-Appwrite-Project": os.environ["APPWRITE_FUNCTION_PROJECT_ID"], + "X-Appwrite-Key": api_key, + "Content-Type": "application/json", + } +``` + +The key can only use the read scopes configured on the Function. Even if a prompt asks a reporting tool to change a balance, Appwrite rejects the write because the Function has no row-write scope. See the [Functions development guide](/docs/products/functions/develop#dynamic-api-key) for details on dynamic keys. + +## Define narrow tools with useful descriptions + +MCP turns Python type hints into an input schema. A tool should describe the report it returns, its filters, accepted values, and important defaults: + +```python +@server.tool( + description=( + "List customers with basic profile fields. Filter by KYC status " + "or country. Returns at most 100 entries." + ) +) +def list_customers( + ctx: Context, + kyc_status: str | None = None, + country: str | None = None, + limit: int = 25, + offset: int = 0, +) -> dict: + limit = max(1, min(limit, 100)) + # Build Appwrite queries, call TablesDB, and return selected fields. +``` + +The [finance MCP demo](https://github.com/appwrite-community/finance-mcp-demo) implements eight read-only tools: + +| Tool | Report | +| --- | --- | +| `portfolio_summary` | Counts, balances by currency and account type, transaction status, and date coverage | +| `list_customers` | Customer profiles filtered by KYC status or country | +| `customer_overview` | One customer's accounts, cards, balances, and recent activity | +| `account_statement` | Transactions and totals for an account and date range | +| `spending_by_category` | Completed debit spending or credit income grouped by category | +| `monthly_cash_flow` | Monthly inflow, outflow, and net cash flow | +| `search_transactions` | Transactions filtered by account, category, status, type, amount, or date | +| `list_accounts` | Accounts filtered by customer, type, or status | + +Use [Appwrite queries](/docs/products/databases/queries) to filter and select only the columns each report needs. For aggregations, page through matching rows and calculate totals inside the Function. Cap list results, validate date strings, and require either an account ID or customer ID when a report accepts both scopes. + +Most importantly, do not add USD, EUR, and GBP into one number. The demo groups every balance and cash-flow total by currency. Without an exchange-rate source and a stated conversion time, a combined total would be misleading. + +# Deploy and connect the financial MCP server + +Commit your changes and push them to the production branch. Appwrite builds and deploys the Function automatically. When the deployment is active, copy its generated domain and add it to your MCP client: + +```json +{ + "mcpServers": { + "finance-mcp": { + "type": "http", + "url": "https://..appwrite.run/", + "headers": { + "Authorization": "Bearer " + } + } + } +} +``` + +Restart or reconnect the client, then ask it to list the available tools. Test simple reports before trying a request that requires several tools: + +```text +Give me a portfolio summary with balances separated by currency. + +Generate a 30-day statement for account acc-001. + +Compare customer cust-001's balances, spending by category, and monthly cash +flow. Keep currencies separate and state which tools you used. +``` + +The final prompt lets the client combine deterministic reports into a readable answer without receiving unrestricted access to TablesDB. + +# Harden financial reporting before using real data + +This project uses fictional data, shared bearer authentication, and whole-dataset reporting. Treat it as a technical pattern, not a production banking system. + +For real financial data, add identity-aware authorization so each caller can access only permitted customers and accounts. Minimize personally identifiable information in tool responses, keep audit logs, rotate secrets, and review the regulatory requirements for your application. You should also move large analytical workloads to a dedicated reporting pipeline instead of scanning thousands of operational rows during a synchronous Function request. + +The design principle still holds: expose the smallest reporting capability an agent needs, enforce access in code and Appwrite scopes, and return structured evidence the client can explain. + +# Build your agentic apps with Appwrite + +Build agentic apps on [Appwrite Cloud](https://cloud.appwrite.io) with data, permissions, and Functions. Explore the [Appwrite AI docs](/docs/tooling/ai) for implementation guides. Configure the backend with the Appwrite MCP server, then deploy the template with your agent's actions. Adapt the pattern to support, commerce, operations, and other workflows. + +- [Appwrite MCP server documentation](/docs/tooling/ai/mcp-servers/api) +- [Appwrite Function templates](/docs/products/functions/templates) +- [Appwrite database queries](/docs/products/databases/queries) +- [Financial reporting MCP demo](https://github.com/appwrite-community/finance-mcp-demo) diff --git a/static/images/blog/financial-reporting-mcp-server/cover.avif b/static/images/blog/financial-reporting-mcp-server/cover.avif new file mode 100644 index 0000000000000000000000000000000000000000..64e21d8f7365b4fee55ab5caeca4d99cd3166b01 GIT binary patch literal 23669 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 Date: Wed, 5 Aug 2026 23:37:15 +0530 Subject: [PATCH 05/13] Cross-link MCP template announcement and tutorial --- .../blog/post/announcing-mcp-server-template/+page.markdoc | 2 ++ .../blog/post/financial-reporting-mcp-server/+page.markdoc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc index f8372931833..9455df771f1 100644 --- a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -148,6 +148,8 @@ If streaming or long-running synchronous calls are hard requirements, a containe The MCP server template is available now on [Appwrite Cloud](https://cloud.appwrite.io) and for self-hosted instances. Open your project, head to **Functions** > **Templates**, search for **MCP server**, and you will have a live endpoint your AI tools can call in a few minutes. If you are new to the Model Context Protocol, our [complete guide to MCP](/blog/post/what-is-mcp-a-complete-guide-for-developers) covers how the protocol works before you start building on it. +To see the template applied to a realistic use case, follow our [financial analysis MCP server tutorial](/blog/post/financial-reporting-mcp-server). It shows how to turn account and transaction data into controlled tools for portfolio summaries, statements, spending analysis, and cash-flow reports. + - [Function templates documentation](/docs/products/functions/templates) - [Appwrite Functions development guide](/docs/products/functions/develop) - [MCP server template source on GitHub](https://github.com/appwrite/templates/tree/main/python/mcp-server) diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc index 79efad9aa03..221c891d325 100644 --- a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc +++ b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc @@ -288,6 +288,6 @@ The design principle still holds: expose the smallest reporting capability an ag Build agentic apps on [Appwrite Cloud](https://cloud.appwrite.io) with data, permissions, and Functions. Explore the [Appwrite AI docs](/docs/tooling/ai) for implementation guides. Configure the backend with the Appwrite MCP server, then deploy the template with your agent's actions. Adapt the pattern to support, commerce, operations, and other workflows. - [Appwrite MCP server documentation](/docs/tooling/ai/mcp-servers/api) -- [Appwrite Function templates](/docs/products/functions/templates) +- [MCP server template announcement](/blog/post/announcing-mcp-server-template) - [Appwrite database queries](/docs/products/databases/queries) - [Financial reporting MCP demo](https://github.com/appwrite-community/finance-mcp-demo) From 1c890ce13b30a7ee5e98c905cc3532fbec922080 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 00:21:11 +0530 Subject: [PATCH 06/13] Add guide for building MCP servers --- .../+page.markdoc | 2 +- src/routes/docs/tooling/ai/+layout.svelte | 4 + src/routes/docs/tooling/ai/+page.markdoc | 3 + .../tooling/ai/build-mcp-server/+page.markdoc | 215 ++++++++++++++++++ .../docs/tooling/ai/mcp-servers/+page.markdoc | 14 +- 5 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc index 9455df771f1..f27702dc81e 100644 --- a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -150,7 +150,7 @@ The MCP server template is available now on [Appwrite Cloud](https://cloud.appwr To see the template applied to a realistic use case, follow our [financial analysis MCP server tutorial](/blog/post/financial-reporting-mcp-server). It shows how to turn account and transaction data into controlled tools for portfolio summaries, statements, spending analysis, and cash-flow reports. -- [Function templates documentation](/docs/products/functions/templates) +- [Build an MCP server guide](/docs/tooling/ai/build-mcp-server) - [Appwrite Functions development guide](/docs/products/functions/develop) - [MCP server template source on GitHub](https://github.com/appwrite/templates/tree/main/python/mcp-server) - [What's new in the MCP 2026-07-28 specification](/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification) diff --git a/src/routes/docs/tooling/ai/+layout.svelte b/src/routes/docs/tooling/ai/+layout.svelte index 0ce74952a64..e54ab1d0573 100644 --- a/src/routes/docs/tooling/ai/+layout.svelte +++ b/src/routes/docs/tooling/ai/+layout.svelte @@ -111,6 +111,10 @@ { label: 'Guides', items: [ + { + label: 'Build an MCP server', + href: '/docs/tooling/ai/build-mcp-server' + }, { label: 'AI in Functions', href: '/docs/tooling/ai/ai-in-functions' diff --git a/src/routes/docs/tooling/ai/+page.markdoc b/src/routes/docs/tooling/ai/+page.markdoc index f3c8c8d78ec..6d0444e177f 100644 --- a/src/routes/docs/tooling/ai/+page.markdoc +++ b/src/routes/docs/tooling/ai/+page.markdoc @@ -146,6 +146,9 @@ Open-source benchmark evaluating how well AI models understand Appwrite's APIs a Guides for building AI-powered features on top of Appwrite, from running models in Functions to building full agent pipelines. {% cards %} +{% cards_item href="/docs/tooling/ai/build-mcp-server" title="Build an MCP server" %} +Expose custom tools to AI clients over HTTPS with the MCP server Function template. +{% /cards_item %} {% cards_item href="/docs/tooling/ai/ai-in-functions" title="AI in Functions" %} Run AI models inside Appwrite Functions with providers like OpenAI and Anthropic. {% /cards_item %} diff --git a/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc b/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc new file mode 100644 index 00000000000..98565ae7231 --- /dev/null +++ b/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc @@ -0,0 +1,215 @@ +--- +layout: article +title: Build an MCP server +description: Build and deploy a custom Model Context Protocol server on Appwrite Functions using the Python MCP server template. +--- + +The Appwrite MCP server template lets you expose your own tools to AI clients over HTTPS. It provides the Model Context Protocol (MCP) transport, request handling, optional bearer authentication, and an Appwrite Function entrypoint. You only need to define the tools and the application logic behind them. + +Use this guide when you want an AI agent to call operations that belong to your application, such as looking up an order, querying a reporting database, checking a job, or triggering a controlled workflow. + +{% info title="Appwrite MCP server or MCP server template?" %} +The hosted [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) lets AI agents manage Appwrite projects and search Appwrite documentation. The template in this guide creates a separate MCP server with tools that you design and host. +{% /info %} + +# Prerequisites {% #prerequisites %} + +- An [Appwrite Cloud](https://cloud.appwrite.io) project +- A GitHub account for the Function repository +- An MCP client that supports remote servers over Streamable HTTP, such as Claude Code, Cursor, or Claude Desktop + +{% section #create-function step=1 title="Create the MCP server Function" %} + +1. Open your project in the Appwrite Console. +1. Select **Functions** in the sidebar, then select **Templates**. +1. Search for **MCP server** and select **Create**. +1. Choose a name and Python runtime for the Function. +1. Connect a new or existing GitHub repository. +1. Select the production branch and root directory, then create the Function. + +Appwrite deploys a working MCP server with two sample tools, `echo` and `add`. After the first deployment becomes active, the Function's generated domain is the URL your MCP clients will use: + +```text +https://..appwrite.run +``` + +The Function uses `src/main.py` as its entrypoint and installs dependencies from `requirements.txt`. The template pins the official Python MCP SDK because its serverless adapter depends on specific SDK behavior. + +{% /section %} + +{% section #understand-template step=2 title="Review the template" %} + +The generated repository contains these important files: + +| Path | Purpose | +| --- | --- | +| `src/main.py` | Appwrite Function entrypoint that passes requests to the MCP adapter. | +| `src/app.py` | MCP server definition and tools. Edit this file to add your application logic. | +| `src/appwrite_mcp/` | Stateless HTTP transport and bearer-authentication helpers. | +| `requirements.txt` | Python dependencies, including the pinned MCP SDK. | + +The default tools in `src/app.py` demonstrate how the server maps Python functions to MCP tools: + +```python +from mcp.server.mcpserver import MCPServer + +server = MCPServer(name="my-mcp", version="0.1.0") + +@server.tool(description="Echo text back to the caller.") +def echo(text: str) -> str: + return text + +@server.tool(description="Add two numbers.") +def add(a: float, b: float) -> float: + return a + b +``` + +Python type hints become the tool's input schema. Tool descriptions help the model decide when to call each tool and which arguments to provide. + +{% /section %} + +{% section #write-tools step=3 title="Define your tools" %} + +Replace the sample tools with small, explicit operations. Each tool should have one responsibility, validate its inputs, and return structured data when the result contains multiple fields. + +This example calculates an order total without giving the agent control over how the calculation works: + +```python +from mcp.server.mcpserver import MCPServer + +server = MCPServer( + name="order-tools", + version="1.0.0", + instructions="Tools for validated order calculations.", +) + +@server.tool( + description=( + "Calculate an order total from a unit price, quantity, and optional " + "discount percentage between 0 and 100." + ) +) +def calculate_order_total( + unit_price: float, + quantity: int, + discount_percent: float = 0, +) -> dict: + if unit_price < 0: + raise ValueError("unit_price must be zero or greater") + if quantity < 1: + raise ValueError("quantity must be at least 1") + if not 0 <= discount_percent <= 100: + raise ValueError("discount_percent must be between 0 and 100") + + subtotal = unit_price * quantity + discount = subtotal * (discount_percent / 100) + + return { + "subtotal": round(subtotal, 2), + "discount": round(discount, 2), + "total": round(subtotal - discount, 2), + } +``` + +Avoid a single general-purpose tool that accepts arbitrary commands or queries. Narrow tools give you clearer validation, smaller permissions, and more predictable results. + +Do not name a source module `server.py`. Appwrite Open Runtimes already provides a top-level module with that name. + +{% /section %} + +{% section #access-appwrite step=4 title="Access Appwrite services from a tool" %} + +Tools can call Appwrite services in the same project without storing a long-lived API key. During each execution, Appwrite passes a [dynamic API key](/docs/products/functions/develop#dynamic-api-key) in the `x-appwrite-key` header. Its permissions are limited to the scopes configured for the Function. + +Open the Function's **Settings** page and select only the scopes your tools need. For example, a read-only reporting server can use `databases.read`, `tables.read`, and `rows.read` without receiving write access. + +Add the Appwrite Python SDK to `requirements.txt`: + +```text +appwrite +``` + +Then initialize its client from the tool context: + +```python +import os + +from appwrite.client import Client +from mcp.server.mcpserver import Context + +def appwrite_client(ctx: Context) -> Client: + api_key = (ctx.headers or {}).get("x-appwrite-key") + if not api_key: + raise ValueError("No dynamic Appwrite API key was provided") + + return ( + Client() + .set_endpoint(os.environ["APPWRITE_FUNCTION_API_ENDPOINT"]) + .set_project(os.environ["APPWRITE_FUNCTION_PROJECT_ID"]) + .set_key(api_key) + ) +``` + +Add `ctx: Context` to any tool that needs the client. Appwrite supplies the endpoint and project ID as Function environment variables. + +{% /section %} + +{% section #secure-server step=5 title="Secure the MCP endpoint" %} + +The template is open by default, which is useful for an initial transport test. Before exposing internal tools or data, add these environment variables in the Function settings: + +| Variable | Value | Purpose | +| --- | --- | --- | +| `MCP_AUTH_MODE` | `bearer` | Requires bearer authentication for MCP requests. | +| `MCP_AUTH_TOKEN` | A long random secret | Shared token that clients must send. | +| `MCP_SERVER_NAME` | Your server name | Name returned to clients during initialization. | +| `MCP_TOOL_TIMEOUT` | `25` | Returns a controlled timeout before the Function's 30-second limit. | + +The bearer token protects access to the MCP endpoint. Function scopes separately control which Appwrite APIs the tools can call. Use both layers. + +{% /section %} + +{% section #deploy-server step=6 title="Deploy the server" %} + +Commit your changes and push them to the Function's production branch. Appwrite creates and activates a new deployment automatically. + +After the deployment succeeds, open the Function in the Appwrite Console and copy its domain. Review the execution logs if initialization or a tool call fails. + +{% /section %} + +{% section #connect-client step=7 title="Connect an MCP client" %} + +Add the Function domain and bearer token to your client's MCP configuration: + +```json +{ + "mcpServers": { + "my-mcp": { + "url": "https://..appwrite.run", + "headers": { + "Authorization": "Bearer " + } + } + } +} +``` + +For Claude Code, you can add a server without bearer authentication from the command line: + +```bash +claude mcp add --transport http my-mcp https://..appwrite.run +``` + +Reconnect the client, list the server's tools, and call one with known inputs. For the example above, ask the client to calculate the total for three items at $20 each with a 10% discount. Verify both the arguments selected by the model and the structured result returned by the tool. + +{% /section %} + +# Design for Appwrite Functions {% #function-constraints %} + +The template uses stateless request and response handling. It does not provide long-lived SSE sessions, streamed progress updates, or server-initiated messages such as sampling. Each tool call returns one final result. + +Requests through a Function domain are [synchronous executions](/docs/products/functions/execute#synchronous-executions) with a 30-second limit. Keep tools focused and leave `MCP_TOOL_TIMEOUT` at 25 seconds so the server can return a clean error first. For longer work, create one tool that starts a job and returns an ID, then another tool that checks the job's status. + +{% arrow_link href="/blog/post/financial-reporting-mcp-server" %} +See a complete financial reporting MCP server built with this template +{% /arrow_link %} diff --git a/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc b/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc index c45b72e6e55..b398ec98cb0 100644 --- a/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc +++ b/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc @@ -27,6 +27,18 @@ Appwrite offers a single MCP server that covers both the Appwrite API and docume {% /cards %} +# Build your own MCP server + +Use the MCP server Function template to expose your application's own tools to AI clients over HTTPS. Appwrite provides the stateless transport, deployment, Function domain, and optional bearer authentication. + +{% cards %} + +{% cards_item href="/docs/tooling/ai/build-mcp-server" title="Build an MCP server" %} +Create, secure, deploy, and connect a custom MCP server on Appwrite Functions. +{% /cards_item %} + +{% /cards %} + ## Why use the Appwrite MCP server? Some **popular use cases** for the Appwrite MCP server include: @@ -35,4 +47,4 @@ Some **popular use cases** for the Appwrite MCP server include: - **Documentation lookup**: Quickly find relevant documentation for specific API endpoints or SDK features. - **Project management**: Create, update, or delete resources in your Appwrite project using natural language commands. - **Debugging assistance**: Get help with debugging issues by providing context about your project and recent changes. -- **Learning and exploration**: Explore Appwrite's features and capabilities through interactive conversations with LLMs. \ No newline at end of file +- **Learning and exploration**: Explore Appwrite's features and capabilities through interactive conversations with LLMs. From c169f4955f4fb34d012ef10795377a68ebfe0fb5 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 00:21:59 +0530 Subject: [PATCH 07/13] Update MCP launch dates to August 6 --- .../blog/post/announcing-mcp-server-template/+page.markdoc | 2 +- .../blog/post/financial-reporting-mcp-server/+page.markdoc | 2 +- .../(entries)/{2026-08-05.markdoc => 2026-08-06.markdoc} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/routes/changelog/(entries)/{2026-08-05.markdoc => 2026-08-06.markdoc} (98%) diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc index f27702dc81e..f6d96fb1531 100644 --- a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -2,7 +2,7 @@ layout: post title: "Build and deploy an MCP server with Appwrite Functions" description: Deploy your own MCP server on Appwrite Functions with the new Python template. Expose custom tools to Claude Code, Cursor, and other AI clients over HTTPS. -date: 2026-08-05 +date: 2026-08-06 cover: /images/blog/announcing-mcp-server-template/cover.avif timeToRead: 6 author: chirag-aggarwal diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc index 221c891d325..b1cd02cad4d 100644 --- a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc +++ b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc @@ -2,7 +2,7 @@ layout: post title: "Build your own AI financial analyst with Appwrite MCP" description: Learn how to build a financial reporting MCP server with Appwrite Functions, TablesDB, and custom tools for statements, cash flow, and portfolio insights. -date: 2026-08-05 +date: 2026-08-06 cover: /images/blog/financial-reporting-mcp-server/cover.avif timeToRead: 8 author: aditya-oberai diff --git a/src/routes/changelog/(entries)/2026-08-05.markdoc b/src/routes/changelog/(entries)/2026-08-06.markdoc similarity index 98% rename from src/routes/changelog/(entries)/2026-08-05.markdoc rename to src/routes/changelog/(entries)/2026-08-06.markdoc index b69ccbdea3e..76be882b65a 100644 --- a/src/routes/changelog/(entries)/2026-08-05.markdoc +++ b/src/routes/changelog/(entries)/2026-08-06.markdoc @@ -1,7 +1,7 @@ --- layout: changelog title: "Deploy your own MCP server with the new Functions template" -date: 2026-08-05 +date: 2026-08-06 cover: /images/blog/announcing-mcp-server-template/cover.avif --- From 9666436d7cdcb48a90fd35ae20c21475c4a0ef47 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 00:40:17 +0530 Subject: [PATCH 08/13] docs: add AI section to main navigation --- src/routes/docs/Sidebar.svelte | 46 ++++++++++++++++--- src/routes/docs/tooling/ai/+layout.svelte | 2 +- .../docs/tooling/ai/mcp-servers/+page.markdoc | 20 ++++---- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/routes/docs/Sidebar.svelte b/src/routes/docs/Sidebar.svelte index e63faa47152..adfc632e2f8 100644 --- a/src/routes/docs/Sidebar.svelte +++ b/src/routes/docs/Sidebar.svelte @@ -119,6 +119,46 @@ } ] }, + { + label: 'AI', + items: [ + { + label: 'Overview', + href: '/docs/tooling/ai', + icon: 'icon-view-grid' + }, + { + label: 'Quick start prompts', + href: '/docs/tooling/ai/quickstart-prompts', + icon: 'icon-sparkles', + isParent: true + }, + { + label: 'MCP server', + href: '/docs/tooling/ai/mcp-servers', + icon: 'icon-globe-alt', + isParent: true + }, + { + label: 'Agent skills', + href: '/docs/tooling/ai/skills', + icon: 'icon-puzzle', + isParent: true + }, + { + label: 'AGENTS.md', + href: '/docs/tooling/ai/agents-md', + icon: 'icon-document-text', + isParent: true + }, + { + label: 'Appwrite Arena', + href: '/docs/tooling/ai/arena', + icon: 'icon-cube', + isParent: true + } + ] + }, { label: 'APIS', items: [ @@ -148,12 +188,6 @@ { label: 'Tooling', items: [ - { - label: 'AI', - href: '/docs/tooling/ai', - icon: 'icon-sparkles', - isParent: true - }, { label: 'CLI', href: '/docs/tooling/command-line/installation', diff --git a/src/routes/docs/tooling/ai/+layout.svelte b/src/routes/docs/tooling/ai/+layout.svelte index e54ab1d0573..c868501ed99 100644 --- a/src/routes/docs/tooling/ai/+layout.svelte +++ b/src/routes/docs/tooling/ai/+layout.svelte @@ -25,7 +25,7 @@ label: 'Tooling', items: [ { - label: 'MCP servers', + label: 'MCP server', href: '/docs/tooling/ai/mcp-servers' }, { diff --git a/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc b/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc index b398ec98cb0..89f3eb96509 100644 --- a/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc +++ b/src/routes/docs/tooling/ai/mcp-servers/+page.markdoc @@ -27,6 +27,16 @@ Appwrite offers a single MCP server that covers both the Appwrite API and docume {% /cards %} +## Why use the Appwrite MCP server? + +Some **popular use cases** for the Appwrite MCP server include: + +- **Code generation**: Automatically generate code snippets or entire files based on user input and context. +- **Documentation lookup**: Quickly find relevant documentation for specific API endpoints or SDK features. +- **Project management**: Create, update, or delete resources in your Appwrite project using natural language commands. +- **Debugging assistance**: Get help with debugging issues by providing context about your project and recent changes. +- **Learning and exploration**: Explore Appwrite's features and capabilities through interactive conversations with LLMs. + # Build your own MCP server Use the MCP server Function template to expose your application's own tools to AI clients over HTTPS. Appwrite provides the stateless transport, deployment, Function domain, and optional bearer authentication. @@ -38,13 +48,3 @@ Create, secure, deploy, and connect a custom MCP server on Appwrite Functions. {% /cards_item %} {% /cards %} - -## Why use the Appwrite MCP server? - -Some **popular use cases** for the Appwrite MCP server include: - -- **Code generation**: Automatically generate code snippets or entire files based on user input and context. -- **Documentation lookup**: Quickly find relevant documentation for specific API endpoints or SDK features. -- **Project management**: Create, update, or delete resources in your Appwrite project using natural language commands. -- **Debugging assistance**: Get help with debugging issues by providing context about your project and recent changes. -- **Learning and exploration**: Explore Appwrite's features and capabilities through interactive conversations with LLMs. From 4ec885827c8eeb6128c2c5738648002e6688bde8 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 19:26:30 +0530 Subject: [PATCH 09/13] revert sidebar + add mcp to main nav --- src/routes/docs/Sidebar.svelte | 52 ++++++++-------------------------- 1 file changed, 12 insertions(+), 40 deletions(-) diff --git a/src/routes/docs/Sidebar.svelte b/src/routes/docs/Sidebar.svelte index adfc632e2f8..b36a28d1d05 100644 --- a/src/routes/docs/Sidebar.svelte +++ b/src/routes/docs/Sidebar.svelte @@ -119,46 +119,6 @@ } ] }, - { - label: 'AI', - items: [ - { - label: 'Overview', - href: '/docs/tooling/ai', - icon: 'icon-view-grid' - }, - { - label: 'Quick start prompts', - href: '/docs/tooling/ai/quickstart-prompts', - icon: 'icon-sparkles', - isParent: true - }, - { - label: 'MCP server', - href: '/docs/tooling/ai/mcp-servers', - icon: 'icon-globe-alt', - isParent: true - }, - { - label: 'Agent skills', - href: '/docs/tooling/ai/skills', - icon: 'icon-puzzle', - isParent: true - }, - { - label: 'AGENTS.md', - href: '/docs/tooling/ai/agents-md', - icon: 'icon-document-text', - isParent: true - }, - { - label: 'Appwrite Arena', - href: '/docs/tooling/ai/arena', - icon: 'icon-cube', - isParent: true - } - ] - }, { label: 'APIS', items: [ @@ -188,6 +148,18 @@ { label: 'Tooling', items: [ + { + label: 'AI', + href: '/docs/tooling/ai', + icon: 'icon-sparkles', + isParent: true + }, + { + label: 'MCP server', + href: '/docs/tooling/ai/mcp-servers', + icon: 'icon-globe-alt', + isParent: true + }, { label: 'CLI', href: '/docs/tooling/command-line/installation', From c3000fe7ed85779fb08948eb009958a9a5eb601d Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 19:33:09 +0530 Subject: [PATCH 10/13] update blog title --- .../blog/post/financial-reporting-mcp-server/+page.markdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc index b1cd02cad4d..8bbaab2ac7a 100644 --- a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc +++ b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc @@ -1,6 +1,6 @@ --- layout: post -title: "Build your own AI financial analyst with Appwrite MCP" +title: "Build a financial reporting MCP server with Appwrite Functions" description: Learn how to build a financial reporting MCP server with Appwrite Functions, TablesDB, and custom tools for statements, cash flow, and portfolio insights. date: 2026-08-06 cover: /images/blog/financial-reporting-mcp-server/cover.avif From f3c3b7999777b04dfaedf41cf74893e64bf940b9 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 19:34:54 +0530 Subject: [PATCH 11/13] Add missing AI IDEs on docs homepage --- src/routes/docs/+page.svelte | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/routes/docs/+page.svelte b/src/routes/docs/+page.svelte index 29767b8e501..154bfbb3e42 100644 --- a/src/routes/docs/+page.svelte +++ b/src/routes/docs/+page.svelte @@ -58,6 +58,13 @@ logoLight: '/images/docs/mcp/logos/vscode.svg', event: 'docs-ai-ide_vscode-click' }, + { + href: '/docs/tooling/ai/agents/zed', + title: 'Zed', + logoDark: '/images/docs/mcp/logos/dark/zed.svg', + logoLight: '/images/docs/mcp/logos/zed.svg', + event: 'docs-ai-ide_zed-click' + }, { href: '/docs/tooling/mcp/opencode', title: 'OpenCode', @@ -71,6 +78,13 @@ logoDark: '/images/docs/mcp/logos/dark/google-antigravity.svg', logoLight: '/images/docs/mcp/logos/google-antigravity.svg', event: 'docs-ai-ide_antigravity-click' + }, + { + href: '/docs/tooling/ai/agents/grok-build', + title: 'Grok Build', + logoDark: '/images/docs/mcp/logos/dark/grok-build.svg', + logoLight: '/images/docs/mcp/logos/grok-build.svg', + event: 'docs-ai-ide_grok-build-click' } ]; From d8ee424b486835755bb12755a91fa758db847421 Mon Sep 17 00:00:00 2001 From: adityaoberai Date: Thu, 6 Aug 2026 19:46:13 +0530 Subject: [PATCH 12/13] update cover image, title, and faq --- .optimize-cache.json | 2 +- .../+page.markdoc | 5 ++--- .../financial-reporting-mcp-server/cover.avif | Bin 23669 -> 24329 bytes 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.optimize-cache.json b/.optimize-cache.json index 0bca72d4577..5a35abcaec0 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -643,7 +643,7 @@ "static/images/blog/february-and-march-product-update-realtime-queries-appwrite-skills-and-new-database-features/Introducing_Realtime_queries.png": "0b632e9ceac3a763f5ba2ed50ab54fffe389fde34fcdfb7ad99599ec7ae83b9e", "static/images/blog/february-and-march-product-update-realtime-queries-appwrite-skills-and-new-database-features/Relationship_queries.png": "2d9772691f05b1be3ec6cb954d77babc10d5666c9994fe3975d2a078facc87b8", "static/images/blog/file-tokens.png": "23d2fa4a88db2d9548f43f95df15b5ca60d512481570ed2d1b3d66ce1b1f504f", - "static/images/blog/financial-reporting-mcp-server/cover.png": "d5e7d26b27799982db7106eb3209207f29ef78004907b2cb65f9d96fd61bd901", + "static/images/blog/financial-reporting-mcp-server/cover.png": "b0e9dfac0480c1715b8b985b879db26aef157cf31af4d99e8a9863ae180a3709", "static/images/blog/firebase-vs-open-source-tradeoffs/cover.png": "1be4185b4fa90c5f37e96003a74b8b55c31956d0258c70000fdec0990f2496eb", "static/images/blog/first-pr.png": "f369419a756ccb2c784dac916d79a1cc33317fa4c43f37c7f41ae62bf0a603dd", "static/images/blog/first-pr1.png": "256144fd88d0564c239cb73c16882113e4fe2cb23156fcbc4f15f6f70437faaf", diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc index 8bbaab2ac7a..d6cf626c228 100644 --- a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc +++ b/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc @@ -8,16 +8,15 @@ timeToRead: 8 author: aditya-oberai category: tutorial, ai featured: false -unlisted: true faqs: - - question: "What is a financial reporting MCP server?" - answer: "A financial reporting MCP server exposes controlled reporting operations as tools that an AI client can call. Instead of giving the model unrestricted database access, you can define tools for tasks such as portfolio summaries, account statements, transaction searches, and monthly cash-flow reports." - question: "What does the Appwrite MCP server template include?" answer: "The template includes a Python MCP server, stateless Streamable HTTP transport, example `echo` and `add` tools, optional bearer authentication, configurable tool timeouts, and the adapter needed to run the server as an Appwrite Function. Replace the example tools with your own domain-specific operations." - question: "How does the Appwrite MCP server differ from the MCP server template?" answer: "The [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) lets an AI agent manage Appwrite resources, so you can use it to create the database schema and seed demo data. The MCP server template lets you build and host your own domain-specific server, such as the financial reporting server in this tutorial." - question: "Which AI clients can connect to an MCP server hosted on Appwrite?" answer: "Any MCP client that supports remote servers over Streamable HTTP can connect to the Function's generated domain. This includes clients such as Claude Code, Cursor, and Claude Desktop. If bearer authentication is enabled, configure the client to send the token in its `Authorization` header." + - question: "What does the financial reporting MCP server in this tutorial do?" + answer: "It exposes controlled reporting operations as tools that an AI client can call. The server runs as an Appwrite Function and defines eight read-only tools over financial data in TablesDB, including portfolio summaries, account statements, spending by category, monthly cash flow, and transaction search. The AI client gets useful reports without unrestricted database access." - question: "How does the financial reporting function access Appwrite TablesDB?" answer: "Appwrite passes a dynamic API key to each Function execution in the `x-appwrite-key` request header. The server uses that key with the supplied project endpoint and project ID. The demo limits the key to `databases.read`, `tables.read`, and `rows.read`, which allows reporting without granting write access." - question: "How should a financial MCP server handle multiple currencies?" diff --git a/static/images/blog/financial-reporting-mcp-server/cover.avif b/static/images/blog/financial-reporting-mcp-server/cover.avif index 64e21d8f7365b4fee55ab5caeca4d99cd3166b01..e0b3d5b5e993ad19b999aa91bde9f2a1f855a8c8 100644 GIT binary patch delta 24038 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�`!ShB*_7_lr7rDPDL-`a0l|T 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 o2perQ5IVuj2gSztY2KNm)gwKmem Date: Thu, 6 Aug 2026 20:00:37 +0530 Subject: [PATCH 13/13] name and slug update --- .../+page.markdoc | 2 +- .../+page.markdoc | 28 +++++++++--------- .../tooling/ai/build-mcp-server/+page.markdoc | 4 +-- .../cover.avif | Bin 4 files changed, 17 insertions(+), 17 deletions(-) rename src/routes/blog/post/{financial-reporting-mcp-server => financial-analysis-mcp-server}/+page.markdoc (92%) rename static/images/blog/{financial-reporting-mcp-server => financial-analysis-mcp-server}/cover.avif (100%) diff --git a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc index f6d96fb1531..4baed8e6af7 100644 --- a/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc +++ b/src/routes/blog/post/announcing-mcp-server-template/+page.markdoc @@ -148,7 +148,7 @@ If streaming or long-running synchronous calls are hard requirements, a containe The MCP server template is available now on [Appwrite Cloud](https://cloud.appwrite.io) and for self-hosted instances. Open your project, head to **Functions** > **Templates**, search for **MCP server**, and you will have a live endpoint your AI tools can call in a few minutes. If you are new to the Model Context Protocol, our [complete guide to MCP](/blog/post/what-is-mcp-a-complete-guide-for-developers) covers how the protocol works before you start building on it. -To see the template applied to a realistic use case, follow our [financial analysis MCP server tutorial](/blog/post/financial-reporting-mcp-server). It shows how to turn account and transaction data into controlled tools for portfolio summaries, statements, spending analysis, and cash-flow reports. +To see the template applied to a realistic use case, follow our [financial analysis MCP server tutorial](/blog/post/financial-analysis-mcp-server). It shows how to turn account and transaction data into controlled tools for portfolio summaries, statements, spending analysis, and cash-flow reports. - [Build an MCP server guide](/docs/tooling/ai/build-mcp-server) - [Appwrite Functions development guide](/docs/products/functions/develop) diff --git a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc b/src/routes/blog/post/financial-analysis-mcp-server/+page.markdoc similarity index 92% rename from src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc rename to src/routes/blog/post/financial-analysis-mcp-server/+page.markdoc index d6cf626c228..935f500af1a 100644 --- a/src/routes/blog/post/financial-reporting-mcp-server/+page.markdoc +++ b/src/routes/blog/post/financial-analysis-mcp-server/+page.markdoc @@ -1,23 +1,23 @@ --- layout: post -title: "Build a financial reporting MCP server with Appwrite Functions" -description: Learn how to build a financial reporting MCP server with Appwrite Functions, TablesDB, and custom tools for statements, cash flow, and portfolio insights. +title: "Build a financial analysis MCP server with Appwrite Functions" +description: Learn how to build a financial analysis MCP server with Appwrite Functions, TablesDB, and custom tools for statements, cash flow, and portfolio insights. date: 2026-08-06 -cover: /images/blog/financial-reporting-mcp-server/cover.avif +cover: /images/blog/financial-analysis-mcp-server/cover.avif timeToRead: 8 author: aditya-oberai category: tutorial, ai featured: false faqs: - question: "What does the Appwrite MCP server template include?" - answer: "The template includes a Python MCP server, stateless Streamable HTTP transport, example `echo` and `add` tools, optional bearer authentication, configurable tool timeouts, and the adapter needed to run the server as an Appwrite Function. Replace the example tools with your own domain-specific operations." + answer: "The template includes a Python MCP server, stateless Streamable HTTP transport, optional bearer authentication, configurable tool timeouts, and the adapter needed to run the server as an Appwrite Function. Replace the example tools with your own domain-specific operations." - question: "How does the Appwrite MCP server differ from the MCP server template?" - answer: "The [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) lets an AI agent manage Appwrite resources, so you can use it to create the database schema and seed demo data. The MCP server template lets you build and host your own domain-specific server, such as the financial reporting server in this tutorial." + answer: "The [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) lets an AI agent manage Appwrite resources, so you can use it to create the database schema and seed demo data. The MCP server template lets you build and host your own domain-specific server, such as the financial analysis server in this tutorial." - question: "Which AI clients can connect to an MCP server hosted on Appwrite?" answer: "Any MCP client that supports remote servers over Streamable HTTP can connect to the Function's generated domain. This includes clients such as Claude Code, Cursor, and Claude Desktop. If bearer authentication is enabled, configure the client to send the token in its `Authorization` header." - - question: "What does the financial reporting MCP server in this tutorial do?" + - question: "What does the financial analysis MCP server in this tutorial do?" answer: "It exposes controlled reporting operations as tools that an AI client can call. The server runs as an Appwrite Function and defines eight read-only tools over financial data in TablesDB, including portfolio summaries, account statements, spending by category, monthly cash flow, and transaction search. The AI client gets useful reports without unrestricted database access." - - question: "How does the financial reporting function access Appwrite TablesDB?" + - question: "How does the financial analysis function access Appwrite TablesDB?" answer: "Appwrite passes a dynamic API key to each Function execution in the `x-appwrite-key` request header. The server uses that key with the supplied project endpoint and project ID. The demo limits the key to `databases.read`, `tables.read`, and `rows.read`, which allows reporting without granting write access." - question: "How should a financial MCP server handle multiple currencies?" answer: "Keep totals grouped by currency unless you have an explicit exchange-rate source and conversion policy. The demo reports USD, EUR, and GBP separately so it never adds unlike monetary values or implies a conversion rate that was not supplied." @@ -25,7 +25,7 @@ faqs: answer: "The architecture can be adapted for real data, but the demo is not a production banking system. Before using sensitive data, add user-specific authorization, audit logging, data minimization, stricter secret management, and compliance controls appropriate to your jurisdiction and use case." --- -MCP is moving AI beyond isolated chat experiences. It gives models a standard, controlled way to work with the systems that run real products, from support platforms and internal operations to commerce and financial reporting. Instead of pasting data into a prompt, developers can expose focused tools that retrieve live information, enforce business rules, and return structured results. +MCP is moving AI beyond isolated chat experiences. It gives models a standard, controlled way to work with the systems that run real products, from support platforms and internal operations to commerce and financial analysis. Instead of pasting data into a prompt, developers can expose focused tools that retrieve live information, enforce business rules, and return structured results. We wanted to test that impact with a scenario where accuracy and controlled access matter. Using our new [MCP server Function template](/blog/post/announcing-mcp-server-template), we developed a **financial analysis MCP server** that can summarize a portfolio, generate account statements, analyze spending, calculate monthly cash flow, and search transactions from an AI client. @@ -36,7 +36,7 @@ We built the entire scenario on Appwrite. First, we used the [Appwrite MCP serve The project uses two MCP servers with different responsibilities: - **Appwrite MCP server:** Connects your AI coding agent to Appwrite so it can create the TablesDB schema and seed test data. -- **Your financial reporting MCP server:** Runs as an Appwrite Function and exposes only the reporting tools you define. +- **Your financial analysis MCP server:** Runs as an Appwrite Function and exposes only the reporting tools you define. The second server never needs a long-lived Appwrite API key. Appwrite Functions receive a dynamic API key for each execution, and its permissions are limited by the Function scopes you select. This lets the AI client request useful reports without receiving unrestricted database access. @@ -162,9 +162,9 @@ Set `MCP_AUTH_MODE` to `bearer`, add a long random value as `MCP_AUTH_TOKEN`, an Also set `FINDB_DATABASE_ID=findb` if you changed the default in the code. Keep `MCP_TOOL_TIMEOUT` at 25 seconds so a slow tool can return a clean error before the Function reaches its 30-second execution limit. -# Extend the template with financial reporting tools +# Extend the template with financial analysis tools -The template includes `echo` and `add` tools to prove the transport works. Replace them in `src/app.py` with a server configured for financial reporting: +The template includes `echo` and `add` tools to prove the transport works. Replace them in `src/app.py` with a server configured for financial analysis: ```python import os @@ -176,7 +176,7 @@ server = MCPServer( name=os.environ.get("MCP_SERVER_NAME") or "findb-reporting", version="1.0.0", instructions=( - "Read-only financial reporting over customers, accounts, cards, " + "Read-only financial analysis over customers, accounts, cards, " "categories, and transactions. Group totals by currency and never " "convert currencies." ), @@ -274,7 +274,7 @@ flow. Keep currencies separate and state which tools you used. The final prompt lets the client combine deterministic reports into a readable answer without receiving unrestricted access to TablesDB. -# Harden financial reporting before using real data +# Harden financial analysis before using real data This project uses fictional data, shared bearer authentication, and whole-dataset reporting. Treat it as a technical pattern, not a production banking system. @@ -289,4 +289,4 @@ Build agentic apps on [Appwrite Cloud](https://cloud.appwrite.io) with data, per - [Appwrite MCP server documentation](/docs/tooling/ai/mcp-servers/api) - [MCP server template announcement](/blog/post/announcing-mcp-server-template) - [Appwrite database queries](/docs/products/databases/queries) -- [Financial reporting MCP demo](https://github.com/appwrite-community/finance-mcp-demo) +- [Financial analysis MCP demo](https://github.com/appwrite-community/finance-mcp-demo) diff --git a/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc b/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc index 98565ae7231..c9b4eb35f14 100644 --- a/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc +++ b/src/routes/docs/tooling/ai/build-mcp-server/+page.markdoc @@ -210,6 +210,6 @@ The template uses stateless request and response handling. It does not provide l Requests through a Function domain are [synchronous executions](/docs/products/functions/execute#synchronous-executions) with a 30-second limit. Keep tools focused and leave `MCP_TOOL_TIMEOUT` at 25 seconds so the server can return a clean error first. For longer work, create one tool that starts a job and returns an ID, then another tool that checks the job's status. -{% arrow_link href="/blog/post/financial-reporting-mcp-server" %} -See a complete financial reporting MCP server built with this template +{% arrow_link href="/blog/post/financial-analysis-mcp-server" %} +See a complete financial analysis MCP server built with this template {% /arrow_link %} diff --git a/static/images/blog/financial-reporting-mcp-server/cover.avif b/static/images/blog/financial-analysis-mcp-server/cover.avif similarity index 100% rename from static/images/blog/financial-reporting-mcp-server/cover.avif rename to static/images/blog/financial-analysis-mcp-server/cover.avif