Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e37a74d657 | |||
| f5764c01fc | |||
| 8c7c2a4407 | |||
| 978de5e9a4 | |||
| 4e9859117c | |||
| a134a0fc08 | |||
| 6df58af0c3 |
@@ -49,7 +49,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
# Override MCP container environment for OpenAI + vector sync
|
# Override MCP container environment for OpenAI + vector sync
|
||||||
VECTOR_SYNC_ENABLED: "true"
|
VECTOR_SYNC_ENABLED: "true"
|
||||||
VECTOR_SYNC_SCAN_INTERVAL: "30"
|
VECTOR_SYNC_SCAN_INTERVAL: "5"
|
||||||
OPENAI_API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
OPENAI_API_KEY: ${{ secrets.GITHUB_TOKEN }}
|
||||||
OPENAI_BASE_URL: "https://models.github.ai/inference"
|
OPENAI_BASE_URL: "https://models.github.ai/inference"
|
||||||
OPENAI_EMBEDDING_MODEL: ${{ inputs.embedding_model }}
|
OPENAI_EMBEDDING_MODEL: ${{ inputs.embedding_model }}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
## v0.48.2 (2025-11-23)
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- Share vector sync state with FastMCP session lifespan via module singleton
|
||||||
|
- Share vector sync state with FastMCP session lifespan via module singleton
|
||||||
|
|
||||||
## v0.48.1 (2025-11-23)
|
## v0.48.1 (2025-11-23)
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
|
```markdown
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="astrolabe.svg" alt="Nextcloud MCP Server" width="128" height="128">
|
<img src="astrolabe.svg" alt="Nextcloud MCP Server" width="128" height="128">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Nextcloud MCP Server
|
# Nextcloud MCP Server
|
||||||
|
|
||||||
[](https://github.com/cbcoutinho/nextcloud-mcp-server/pkgs/container/nextcloud-mcp-server)
|
|
||||||
[](https://smithery.ai/server/@cbcoutinho/nextcloud-mcp-server)
|
[](https://smithery.ai/server/@cbcoutinho/nextcloud-mcp-server)
|
||||||
|
[](https://github.com/cbcoutinho/nextcloud-mcp-server/pkgs/container/nextcloud-mcp-server)
|
||||||
|
|
||||||
**A production-ready MCP server that connects AI assistants to your Nextcloud instance.**
|
**A production-ready MCP server that connects AI assistants to your Nextcloud instance.**
|
||||||
|
|
||||||
@@ -223,3 +224,4 @@ This project is licensed under the AGPL-3.0 License. See [LICENSE](./LICENSE) fo
|
|||||||
- [Model Context Protocol](https://github.com/modelcontextprotocol)
|
- [Model Context Protocol](https://github.com/modelcontextprotocol)
|
||||||
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
|
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
|
||||||
- [Nextcloud](https://nextcloud.com/)
|
- [Nextcloud](https://nextcloud.com/)
|
||||||
|
```
|
||||||
@@ -2,8 +2,8 @@ apiVersion: v2
|
|||||||
name: nextcloud-mcp-server
|
name: nextcloud-mcp-server
|
||||||
description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud
|
description: A Helm chart for Nextcloud MCP Server - enables AI assistants to interact with Nextcloud
|
||||||
type: application
|
type: application
|
||||||
version: 0.48.1
|
version: 0.48.2
|
||||||
appVersion: "0.48.1"
|
appVersion: "0.48.2"
|
||||||
keywords:
|
keywords:
|
||||||
- nextcloud
|
- nextcloud
|
||||||
- mcp
|
- mcp
|
||||||
|
|||||||
@@ -243,6 +243,25 @@ def validate_pkce_support(discovery: dict, discovery_url: str) -> None:
|
|||||||
click.echo(f"✓ PKCE support validated: {code_challenge_methods}")
|
click.echo(f"✓ PKCE support validated: {code_challenge_methods}")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VectorSyncState:
|
||||||
|
"""
|
||||||
|
Module-level state for vector sync background tasks.
|
||||||
|
|
||||||
|
This singleton bridges the Starlette server lifespan (where background tasks run)
|
||||||
|
and FastMCP session lifespans (where MCP tools need access to the streams).
|
||||||
|
"""
|
||||||
|
|
||||||
|
document_send_stream: Optional[MemoryObjectSendStream] = None
|
||||||
|
document_receive_stream: Optional[MemoryObjectReceiveStream] = None
|
||||||
|
shutdown_event: Optional[anyio.Event] = None
|
||||||
|
scanner_wake_event: Optional[anyio.Event] = None
|
||||||
|
|
||||||
|
|
||||||
|
# Module-level singleton for vector sync state
|
||||||
|
_vector_sync_state = VectorSyncState()
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class AppContext:
|
class AppContext:
|
||||||
"""Application context for BasicAuth mode."""
|
"""Application context for BasicAuth mode."""
|
||||||
@@ -580,8 +599,16 @@ async def app_lifespan_basic(server: FastMCP) -> AsyncIterator[AppContext]:
|
|||||||
initialize_document_processors()
|
initialize_document_processors()
|
||||||
|
|
||||||
# Yield client context - scanner runs at server level (starlette_lifespan)
|
# Yield client context - scanner runs at server level (starlette_lifespan)
|
||||||
|
# Include vector sync state from module singleton (set by starlette_lifespan)
|
||||||
try:
|
try:
|
||||||
yield AppContext(client=client, storage=storage)
|
yield AppContext(
|
||||||
|
client=client,
|
||||||
|
storage=storage,
|
||||||
|
document_send_stream=_vector_sync_state.document_send_stream,
|
||||||
|
document_receive_stream=_vector_sync_state.document_receive_stream,
|
||||||
|
shutdown_event=_vector_sync_state.shutdown_event,
|
||||||
|
scanner_wake_event=_vector_sync_state.scanner_wake_event,
|
||||||
|
)
|
||||||
finally:
|
finally:
|
||||||
logger.info("Shutting down BasicAuth session")
|
logger.info("Shutting down BasicAuth session")
|
||||||
await client.close()
|
await client.close()
|
||||||
@@ -1228,6 +1255,13 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
|
|||||||
app.state.shutdown_event = shutdown_event
|
app.state.shutdown_event = shutdown_event
|
||||||
app.state.scanner_wake_event = scanner_wake_event
|
app.state.scanner_wake_event = scanner_wake_event
|
||||||
|
|
||||||
|
# Also store in module singleton for FastMCP session lifespans
|
||||||
|
_vector_sync_state.document_send_stream = send_stream
|
||||||
|
_vector_sync_state.document_receive_stream = receive_stream
|
||||||
|
_vector_sync_state.shutdown_event = shutdown_event
|
||||||
|
_vector_sync_state.scanner_wake_event = scanner_wake_event
|
||||||
|
logger.info("Vector sync state stored in module singleton")
|
||||||
|
|
||||||
# Also share with browser_app for /app route
|
# Also share with browser_app for /app route
|
||||||
for route in app.routes:
|
for route in app.routes:
|
||||||
if isinstance(route, Mount) and route.path == "/app":
|
if isinstance(route, Mount) and route.path == "/app":
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "nextcloud-mcp-server"
|
name = "nextcloud-mcp-server"
|
||||||
version = "0.48.1"
|
version = "0.48.2"
|
||||||
description = "Model Context Protocol (MCP) server for Nextcloud integration - enables AI assistants to interact with Nextcloud data"
|
description = "Model Context Protocol (MCP) server for Nextcloud integration - enables AI assistants to interact with Nextcloud data"
|
||||||
authors = [
|
authors = [
|
||||||
{name = "Chris Coutinho", email = "chris@coutinho.io"}
|
{name = "Chris Coutinho", email = "chris@coutinho.io"}
|
||||||
|
|||||||
@@ -1936,7 +1936,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nextcloud-mcp-server"
|
name = "nextcloud-mcp-server"
|
||||||
version = "0.48.1"
|
version = "0.48.2"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiosqlite" },
|
{ name = "aiosqlite" },
|
||||||
|
|||||||
Reference in New Issue
Block a user