MCP, Asynchronus vs. Synchronus#3105
Conversation
Appwrite WebsiteProject ID: Website (appwrite/website)Project ID: Tip Schedule functions to run as often as every minute with cron expressions |
Greptile SummaryThis PR adds two new SEO blog posts — one on asynchronous vs. synchronous programming and one on the Model Context Protocol — along with their cover images and cache entries in
Confidence Score: 4/5Safe to merge after removing the orphaned what-is-crud-explained cache entry from .optimize-cache.json. The orphaned cache entry for what-is-crud-explained/cover.png points to an image that was deleted from the repository in a prior commit. If the image optimization pipeline attempts to process that entry, it will either error or behave unexpectedly. Everything else in the PR is clean. .optimize-cache.json — contains a stale entry for a deleted image that should be removed before merging. Important Files Changed
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
.optimize-cache.json:1274
**Stale cache entry for deleted image**
A new cache entry for `static/images/blog/what-is-crud-explained/cover.png` was added here, but the corresponding image file (`cover.avif`) was deleted from the repo in an earlier commit (`1eada5add`). The file doesn't exist at the referenced path, which means the image optimization pipeline will either error or silently skip it. The `what-is-crud-explained` post and its cover image were removed from the branch — this cache entry should be removed as well.
Reviews (6): Last reviewed commit: "Update +page.markdoc" | Re-trigger Greptile |
| # Handling synchronous and asynchronous work with Appwrite | ||
|
|
||
| Once you move this decision from a single function into a real backend, you need infrastructure that supports both models cleanly. [Appwrite Functions](/docs/products/functions) is built around exactly this distinction. | ||
|
|
||
| When you [execute a function](/docs/products/functions/execute), you choose the mode explicitly. A **synchronous execution** makes the caller wait for the result and is capped at a 30-second timeout, which suits API endpoints and short tasks where you need the response immediately. An **asynchronous execution** returns an execution ID right away and runs the work in the background, which suits long-running jobs like batch processing, email delivery, or upload post-processing. | ||
|
|
||
| ```javascript | ||
| const execution = await functions.createExecution({ | ||
| functionId: '<FUNCTION_ID>', | ||
| async: true, // returns immediately, runs in the background | ||
| }); | ||
| ``` | ||
|
|
||
| Beyond Functions, the same non-blocking philosophy runs through the platform. [Appwrite Realtime](/docs/apis/realtime) pushes updates to clients over subscriptions instead of forcing them to poll, and [Appwrite Messaging](/docs/products/messaging) handles email, SMS, and push delivery as background work so your request path stays fast. Together they let you keep user-facing calls synchronous and responsive while heavy work happens asynchronously out of the critical path. | ||
|
|
||
| To go deeper on structuring this well, read the [complete guide to Appwrite Functions](/blog/post/appwrite-functions-guide) for triggers and execution modes, and [serverless functions best practices](/blog/post/serverless-functions-best-practices) for patterns that keep async work reliable in production. | ||
|
|
||
| # Getting started with Appwrite Functions | ||
|
|
||
| Choosing between synchronous and asynchronous execution is not about picking a favorite. It is about matching the model to the work: synchronous for fast, CPU-bound, order-dependent tasks, and asynchronous for anything that waits on I/O or runs long. Get that mapping right and both your servers and your users stop waiting on work that never needed to block them. |
There was a problem hiding this comment.
If we're talking about Appwrite, we should talk about DevEx and our SDKs. This doesn't exactly make sense right now. Our SDKs use async functions, so we can mention that,
We can then make a Functions-specific section if we want, but the whole article doesn't really allude to how we have it framed right now so it feels off.
|
|
||
| MCP is an open protocol that defines how AI applications connect to external tools, data sources, and APIs through a uniform interface. Instead of teaching a model a new integration for every service, you expose your capabilities through an **MCP server**, and any MCP-compatible client can use them. | ||
|
|
||
| MCP was developed by [Anthropic](https://www.anthropic.com/news/model-context-protocol) and released as an open standard in November 2024. It has since been adopted across IDE assistants, desktop clients, and backend platforms, and the specification is maintained openly at [modelcontextprotocol.io](https://modelcontextprotocol.io). |
There was a problem hiding this comment.
While Anthropic started MCP, it is now maintained by the Agentic AI Foundation (https://aaif.io/)
| # How to start building with MCP | ||
|
|
||
| You do not need to implement the protocol by hand. The MCP project ships official [SDKs](https://modelcontextprotocol.io/docs/sdk) for TypeScript, Python, and other languages that handle the JSON-RPC layer, the handshake, and the transport for you. Building a server usually comes down to declaring your tools, resources, and prompts and wiring them to real logic. | ||
|
|
||
| If you are using MCP rather than authoring a server, the workflow is simpler: pick a client, point it at a server, and start prompting. The client handles discovery and tool calls automatically. | ||
|
|
||
| Two good ways to get hands-on: | ||
|
|
||
| * **Use existing servers.** Attach servers for the tools you already work with. Our roundup of the [best MCP servers and clients](/blog/post/10-best-mcp-server-client) is a good starting point for what is available. | ||
| * **Connect your backend.** If you build on Appwrite, the [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) exposes your project to any MCP-compatible client so an AI agent can manage [Databases](/docs/products/databases), create users through [Auth](/docs/products/auth), upload files to [Storage](/docs/products/storage), and deploy [Functions](/docs/products/functions) directly from a chat. |
There was a problem hiding this comment.
This should instead refer to how to build an MCP server
| * **Use existing servers.** Attach servers for the tools you already work with. Our roundup of the [best MCP servers and clients](/blog/post/10-best-mcp-server-client) is a good starting point for what is available. | ||
| * **Connect your backend.** If you build on Appwrite, the [Appwrite MCP server](/docs/tooling/ai/mcp-servers/api) exposes your project to any MCP-compatible client so an AI agent can manage [Databases](/docs/products/databases), create users through [Auth](/docs/products/auth), upload files to [Storage](/docs/products/storage), and deploy [Functions](/docs/products/functions) directly from a chat. | ||
|
|
||
| # MCP security best practices |
There was a problem hiding this comment.
This can be a separate blog
There was a problem hiding this comment.
i'll start working on this
|
|
||
| Scope API keys to the minimum permissions the task needs, prefer local stdio servers when you want credentials to stay on your machine, and use staging projects for exploratory work. Before connecting any server, audit which tools it exposes. An MCP server is only as safe as the access you hand it. | ||
|
|
||
| # Getting started with the Appwrite MCP server |
Co-authored-by: Aditya Oberai <adityaoberai1@gmail.com>
Co-authored-by: Aditya Oberai <adityaoberai1@gmail.com>
| @@ -1271,8 +1272,10 @@ | |||
| "static/images/blog/what-is-ciam/cover.png": "45a5261ae1bb8a38777f60a21ea60426c0832e3d58bf3164100548400d388ce1", | |||
| "static/images/blog/what-is-cicd-a-complete-guide-for-developers/cover.png": "7abddce55b1467188faab83abd58189173bf9aba84de3d9f28fff0be8c6e9276", | |||
| "static/images/blog/what-is-cloud-storage-an-expert-guide-for-developers/cover.png": "b7f545dbe9334d60f214e748ddfcea47484530a97f30ecf579d064a053c2821d", | |||
There was a problem hiding this comment.
Stale cache entry for deleted image
A new cache entry for static/images/blog/what-is-crud-explained/cover.png was added here, but the corresponding image file (cover.avif) was deleted from the repo in an earlier commit (1eada5add). The file doesn't exist at the referenced path, which means the image optimization pipeline will either error or silently skip it. The what-is-crud-explained post and its cover image were removed from the branch — this cache entry should be removed as well.
Rule Used: In .optimize-cache.json, do not flag mismatches ... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: .optimize-cache.json
Line: 1274
Comment:
**Stale cache entry for deleted image**
A new cache entry for `static/images/blog/what-is-crud-explained/cover.png` was added here, but the corresponding image file (`cover.avif`) was deleted from the repo in an earlier commit (`1eada5add`). The file doesn't exist at the referenced path, which means the image optimization pipeline will either error or silently skip it. The `what-is-crud-explained` post and its cover image were removed from the branch — this cache entry should be removed as well.
**Rule Used:** In `.optimize-cache.json`, do not flag mismatches ... ([source](https://app.greptile.com/appwrite/github/appwrite/website/-/custom-context?memory=b83b4185-daa5-46e1-9b79-52ffe23250c9))
How can I resolve this? If you propose a fix, please make it concise.

Latest SEO Blogs