affine-chatgpt-mcp-bridge
Allows read-only search and retrieval of documents from an AFFiNE Cloud workspace via the doc_search and read_document tools.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@affine-chatgpt-mcp-bridgesearch my AFFiNE workspace for the project brief"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AFFiNE ↔ ChatGPT MCP Bridge
Read-only ChatGPT ↔ AFFiNE Cloud bridge over MCP, running on Cloudflare Workers with GitHub OAuth.
This is an independent community project. It is not affiliated with or endorsed by AFFiNE, OpenAI, GitHub, or Cloudflare.
A read-only cloud bridge that lets ChatGPT search and read an AFFiNE Cloud workspace over MCP without keeping a Mac, local proxy, or tunnel client running.
Руководство: организация пространства, распознавание контекста и работа с ИИ
The bridge runs on Cloudflare Workers, authenticates the human user with GitHub OAuth, and applies an explicit GitHub username allowlist. Version 1.3.5 includes eight read-only tools:
Tool | Purpose |
| Search persisted documents through native AFFiNE MCP. |
| Read document text through native AFFiNE MCP. |
| Read headings, frames, groups and section context. |
| List image blocks with document and section context. |
| Return actual image bytes for visual inspection. |
| Read tables, rows, fields, tags and references. |
| Check capabilities and permissions without writing. |
| Check WebSocket sync stages without sending changes. |
The last six tools are restricted to the configured owner and require an existing AFFiNE web-session cookie as well as a successful native-MCP document read. Additional allowlisted accounts receive only the two text tools.
Architecture
ChatGPT authenticates with the Worker through GitHub OAuth. The Worker uses native AFFiNE MCP for text and document authorization. Owner-only tools then use the fixed AFFiNE Cloud REST, asset and WebSocket endpoints with the stored web session. Credentials are never accepted as tool arguments or returned to ChatGPT.
No always-on Mac, VPS, Cloudflare Zero Trust subscription, or OpenAI API key is required for this cloud path.
Related MCP server: Confluence MCP Server
Status
This project is deliberately read-only. It does not create, edit, move, or delete AFFiNE content.
In the September 16, 2026 live check, both selected documents reached WebSocket,
Engine.IO and Socket.IO connection, then timed out at document_join. No snapshot
was received. sync_read_verified, ready_for_write and persistence_verified
were all false. Reading and Doc.Update permission do not prove write delivery
or persistence. See validation.
This public edition replaces private workspace and document identifiers with examples. Configure your own owner and workspace before enabling the extra tools. Publishing this repository does not deploy or change an existing Worker.
It was extracted from a working AFFiNE Cloud ↔ ChatGPT setup and uses Cloudflare's OAuth provider / MCP agent stack. AFFiNE and ChatGPT are evolving products, so UI labels and upstream MCP behavior can change.
Tested stack
The first public version is pinned to the versions used while building the working bridge:
agents0.17.4@modelcontextprotocol/sdk1.29.0@cloudflare/workers-oauth-provider0.8.1wrangler4.131.1@cloudflare/workers-types5.20260914.1zod4.4.3
Requirements
AFFiNE Cloud workspace with MCP enabled
dedicated read-only AFFiNE MCP credential
Cloudflare account with Workers available
GitHub account
ChatGPT account/workspace that supports custom remote MCP apps/plugins
Node.js 24.11+ and npm for deployment
1. Clone and install
git clone https://github.com/excitingadventures8/affine-chatgpt-mcp-bridge.git
cd affine-chatgpt-mcp-bridge
npm ci
npx wrangler login2. Create the OAuth KV namespace
npx wrangler kv namespace create OAUTH_KVCopy the returned namespace ID into wrangler.jsonc:
"kv_namespaces": [
{
"binding": "OAUTH_KV",
"id": "YOUR_KV_NAMESPACE_ID"
}
]Keep the binding name exactly OAUTH_KV.
3. Deploy once to obtain the Worker URL
Optionally change name in wrangler.jsonc, then run:
npm run deployYou will get a URL similar to:
https://affine-chatgpt-mcp-bridge.<your-subdomain>.workers.dev4. Create a GitHub OAuth App
GitHub → Settings → Developer settings → OAuth Apps → New OAuth App
Use your Worker URL:
Homepage URL:
https://<your-worker>.workers.dev
Authorization callback URL:
https://<your-worker>.workers.dev/callbackSave the Client ID and generate a Client Secret.
Only GitHub's read:user scope is requested by the bridge.
5. Create a read-only AFFiNE MCP credential
In the target AFFiNE workspace, create a dedicated MCP credential with read-only access.
You need:
AFFiNE MCP URL
https://app.affine.pro/api/workspaces/<workspace-id>/mcpand the full authorization value issued for that credential, normally beginning with:
Bearer ...Do not reuse a write-capable credential.
6. Configure Worker secrets
Runtime values are stored as Worker secrets so they are not committed to Git and are not replaced by later wrangler deploy operations.
npx wrangler secret put AFFINE_MCP_URL
npx wrangler secret put AFFINE_AUTH_HEADER
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
npx wrangler secret put ALLOWED_GITHUB_USERSEnter:
AFFINE_MCP_URL— full AFFiNE MCP endpointAFFINE_AUTH_HEADER— complete authorization value, normallyBearer ...GITHUB_CLIENT_ID— GitHub OAuth App Client IDGITHUB_CLIENT_SECRET— GitHub OAuth App Client SecretALLOWED_GITHUB_USERS— comma-separated GitHub logins allowed to use this bridge
Example allowlist:
alice,bobThe server fails closed if ALLOWED_GITHUB_USERS is empty.
7. Configure optional owner-only tools and deploy
For media, table structure and diagnostics, configure the two public placeholders:
OWNER_LOGINinsrc/affine-media/bridge.mjs: exact GitHub login returned by OAuth;WORKSPACE_IDinsrc/affine-media/media.mjs: the same workspace used byAFFINE_MCP_URL.
Keep the owner in ALLOWED_GITHUB_USERS. Store an existing authorized web session
in the Worker secret AFFINE_SESSION_COOKIE; never put cookie contents in source:
npx wrangler secret put AFFINE_SESSION_COOKIE
npm test
npm run type-checkThe source placeholders are intentional. Keep deployment-specific edits local; do not push private workspace identifiers to a public fork. The pilot document constant is a synthetic test fixture, not a required live document.
For an existing Worker, preserve its current name, KV binding, migrations and
secrets. Do not replace a working wrangler.jsonc with this new-install template.
npm run deploy8. Verify OAuth protection
Without an OAuth access token, /mcp must reject the request:
curl -i https://<your-worker>.workers.dev/mcpExpected behavior:
HTTP 401
WWW-Authenticate: Bearer ...Protected-resource metadata should also be available:
curl https://<your-worker>.workers.dev/.well-known/oauth-protected-resource/mcpThe response should identify your /mcp endpoint and authorization server.
9. Connect ChatGPT
Create a custom remote MCP app/plugin in ChatGPT:
Server URL:
https://<your-worker>.workers.dev/mcp
Authentication:
OAuthDuring connection:
ChatGPT discovers the OAuth metadata.
The Worker redirects your browser to GitHub.
GitHub authenticates you.
The Worker checks your exact GitHub login against
ALLOWED_GITHUB_USERS.ChatGPT receives an OAuth token for the Worker.
The AFFiNE credential remains hidden inside Cloudflare.
For an ordinary allowlisted account the tool scan exposes:
doc_search
read_documentFor the configured owner it exposes all eight tools listed above. Refresh the connector's tool catalog after upgrading if the client caches the previous list.
Example prompts
Find the AFFiNE document "Project Notes" and summarize it.Search my AFFiNE workspace for notes about cinematography.Local development
Copy the example environment file:
cp .dev.vars.example .dev.varsFill it with test credentials, then run:
npm run dev.dev.vars is ignored by Git. Never commit real secrets.
Security model
GitHub OAuth authenticates the person connecting the MCP client.
ALLOWED_GITHUB_USERSrestricts access to explicit GitHub accounts.OAuth state is random, short-lived, stored in Cloudflare KV, and bound to the browser with an HttpOnly/Secure cookie.
The AFFiNE bearer credential is stored only as a Cloudflare Worker secret.
The AFFiNE credential should be read-only.
All eight tools are read-only; the six owner-only tools recheck native document access.
The optional AFFiNE web session is separate from the read-only MCP credential.
The AFFiNE bearer credential is never returned to ChatGPT or GitHub.
If a credential appears in a public issue, commit, screenshot, chat, or CI log, revoke it immediately and create a new one.
See SECURITY.md.
Troubleshooting
AFFiNE returns 401
Recreate a read-only AFFiNE MCP credential and put the exact working value into AFFINE_AUTH_HEADER. Do not shorten, redact, or reconstruct it manually.
OAuth succeeds but the bridge returns 403
Check ALLOWED_GITHUB_USERS. It must contain the exact GitHub login returned by GitHub, not a display name.
OAUTH_KV errors
The KV binding name must remain OAUTH_KV, even if the namespace itself has another name.
npm dependency conflict around @cloudflare/workers-types
This repository pins the 5.x Workers types release used with the tested Wrangler version. Older Cloudflare examples may still reference a 4.x package and can trigger ERESOLVE with current Wrangler releases.
ChatGPT does not see the tools
Check these in order:
/mcpreturns401without a token, not404or500./.well-known/oauth-protected-resource/mcpreturns JSON metadata.GitHub OAuth callback URL exactly matches
https://<worker>/callback.your login is in
ALLOWED_GITHUB_USERS.the AFFiNE MCP credential is still valid.
Upstream / attribution
The OAuth/MCP architecture is based on Cloudflare's public remote MCP examples and libraries. Cloudflare's cloudflare/ai examples are MIT licensed.
Cloudflare MCP docs: https://developers.cloudflare.com/agents/model-context-protocol/
Cloudflare GitHub OAuth MCP example: https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-github-oauth
AFFiNE MCP: https://affine.pro/mcp
Documentation
License
MIT. See LICENSE.
Third-party notices: THIRD_PARTY_NOTICES.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Search your Glasp web and Kindle highlights, notes, and AI memories from any MCP client. Read-only.
Let Claude or ChatGPT search, read and send your WhatsApp messages over MCP. OAuth sign-in.
Related MCP Servers
AlicenseAqualityCmaintenanceEnables AI assistants to query end-to-end encrypted memories from Cognia workspace via MCP. Supports search, retrieval, and action execution against connected services like Slack, Notion, and GitHub.510 npmMIT- AlicenseNot gradedqualityDmaintenanceEnables GitHub Copilot to read, write, search, and manage Confluence pages, spaces, attachments, and diagrams through MCP tools.MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI-powered GitHub interactions including repository analysis, code search, PR reviews, and more through the MCP protocol.4MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to search, read, and query Notion workspaces, databases, and pages through an MCP gateway.188 npmMIT