nextcloud-agent 2.3.2__tar.gz → 2.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/PKG-INFO +9 -15
  2. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/README.md +6 -8
  3. nextcloud_agent-2.3.4/nextcloud_agent/__init__.py +11 -0
  4. nextcloud_agent-2.3.4/nextcloud_agent/__main__.py +4 -0
  5. nextcloud_agent-2.3.4/nextcloud_agent/connector_sources.py +82 -0
  6. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/kg_ingest.py +5 -59
  7. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/mcp_server.py +0 -68
  8. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/certification.json +6 -9
  9. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/mappings/source.yaml +1 -1
  10. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/nextcloud.ttl +10 -11
  11. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/prompts/file_steward.json +0 -2
  12. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent.egg-info/PKG-INFO +9 -15
  13. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent.egg-info/SOURCES.txt +1 -9
  14. nextcloud_agent-2.3.4/nextcloud_agent.egg-info/entry_points.txt +8 -0
  15. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent.egg-info/requires.txt +1 -7
  16. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent.egg-info/top_level.txt +0 -1
  17. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/pyproject.toml +14 -17
  18. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_fleet_name.py +3 -14
  19. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_init.py +2 -2
  20. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_kg_ingest.py +2 -2
  21. nextcloud_agent-2.3.4/tests/test_mcp_server.py +52 -0
  22. nextcloud_agent-2.3.2/nextcloud_agent/__init__.py +0 -1
  23. nextcloud_agent-2.3.2/nextcloud_agent/__main__.py +0 -4
  24. nextcloud_agent-2.3.2/nextcloud_agent/connectors/__init__.py +0 -0
  25. nextcloud_agent-2.3.2/nextcloud_agent/connectors/mcp_source_presets.json +0 -14
  26. nextcloud_agent-2.3.2/nextcloud_agent/connectors/tool_schema_fingerprints.json +0 -8
  27. nextcloud_agent-2.3.2/nextcloud_agent/prompts/__init__.py +0 -0
  28. nextcloud_agent-2.3.2/nextcloud_agent/skills/__init__.py +0 -0
  29. nextcloud_agent-2.3.2/nextcloud_agent.egg-info/entry_points.txt +0 -17
  30. nextcloud_agent-2.3.2/scripts/security_sanitizer.py +0 -318
  31. nextcloud_agent-2.3.2/scripts/verify_api_integration.py +0 -320
  32. nextcloud_agent-2.3.2/tests/test_cli_server.py +0 -18
  33. nextcloud_agent-2.3.2/tests/test_default_content_surfaces.py +0 -43
  34. nextcloud_agent-2.3.2/tests/test_mcp_server.py +0 -100
  35. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/LICENSE +0 -0
  36. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/__init__.py +0 -0
  37. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/api_client_base.py +0 -0
  38. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/api_client_calendar.py +0 -0
  39. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/api_client_contacts.py +0 -0
  40. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/api_client_files.py +0 -0
  41. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api/xml_security.py +0 -0
  42. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/api_client.py +0 -0
  43. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/auth.py +0 -0
  44. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/mcp_config.json +0 -0
  45. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/__init__.py +0 -0
  46. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/fixtures/records.json +0 -0
  47. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/migrations/manifest.json +0 -0
  48. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/ontology/shapes/connector.shacl.ttl +0 -0
  49. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-agent-operations/SKILL.md +0 -0
  50. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-agent-operations/agents/openai.yaml +0 -0
  51. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-agent-operations/references/catalog.md +0 -0
  52. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-files/SKILL.md +0 -0
  53. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-files/WORKFLOW.md +0 -0
  54. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-ingest/SKILL.md +0 -0
  55. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-ingest/WORKFLOW.md +0 -0
  56. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-shares/SKILL.md +0 -0
  57. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent/skills/nextcloud-shares/WORKFLOW.md +0 -0
  58. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/nextcloud_agent.egg-info/dependency_links.txt +0 -0
  59. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/setup.cfg +0 -0
  60. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/conftest.py +0 -0
  61. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_api_client.py +0 -0
  62. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_auth.py +0 -0
  63. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_init_dynamics.py +0 -0
  64. {nextcloud_agent-2.3.2 → nextcloud_agent-2.3.4}/tests/test_xml_security.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextcloud-agent
3
- Version: 2.3.2
3
+ Version: 2.3.4
4
4
  Summary: Nextcloud MCP Server for Agentic AI!
5
- Author-email: Project Maintainers <maintainers@users.noreply.github.com>
5
+ Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
7
7
  Classifier: Development Status :: 3 - Alpha
8
8
  Classifier: License :: OSI Approved :: MIT License
@@ -12,16 +12,12 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.12
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18
15
+ Requires-Dist: agent-connector-sdk[mcp]<0.6.0,>=0.5.4
16
16
  Requires-Dist: requests>=2.34.2
17
17
  Requires-Dist: defusedxml>=0.7.1
18
18
  Requires-Dist: python-dateutil>=2.9.0.post0
19
19
  Requires-Dist: icalendar>=7.3.0
20
20
  Requires-Dist: vobject>=0.9.9
21
- Provides-Extra: mcp
22
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "mcp"
23
- Provides-Extra: all
24
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "all"
25
21
  Provides-Extra: test
26
22
  Requires-Dist: pytest-xdist>=3.8.0; extra == "test"
27
23
  Requires-Dist: pytest>=9.1.1; extra == "test"
@@ -51,8 +47,6 @@ Dynamic: license-file
51
47
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/nextcloud-agent)
52
48
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/nextcloud-agent)
53
49
 
54
- *Version: 2.3.2*
55
-
56
50
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
57
51
  > interfaces, and guidance for provisioning the backing Nextcloud instance are
58
52
  > maintained in the [official documentation](https://knuckles-team.github.io/nextcloud-agent/).
@@ -353,7 +347,7 @@ services:
353
347
  max-file: "3"
354
348
 
355
349
  nextcloud-agent-agent:
356
- image: knucklessg1/nextcloud-agent:2.3.2
350
+ image: knucklessg1/nextcloud-agent:2.3.3
357
351
  container_name: nextcloud-agent-agent
358
352
  hostname: nextcloud-agent-agent
359
353
  restart: always
@@ -524,15 +518,15 @@ One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `
524
518
  | Image tag | Build target | Contents | Entrypoint |
525
519
  |-----------|--------------|----------|------------|
526
520
  | `knucklessg1/nextcloud-agent:mcp` | `--target mcp` | `nextcloud-agent[mcp]` — **connector-focused**, includes `epistemic-graph[full]`; no model-orchestration stack | `nextcloud-mcp` |
527
- | `knucklessg1/nextcloud-agent:2.3.2` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
521
+ | `knucklessg1/nextcloud-agent:2.3.3` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
528
522
 
529
523
  ```bash
530
524
  docker build --target mcp -t knucklessg1/nextcloud-agent:mcp docker/ # connector-focused MCP server
531
- docker build --target agent -t knucklessg1/nextcloud-agent:2.3.2 docker/ # agent runtime
525
+ docker build --target agent -t knucklessg1/nextcloud-agent:2.3.3 docker/ # agent runtime
532
526
  ```
533
527
 
534
528
  `docker/mcp.compose.yml` runs the connector-focused `:mcp` server; `docker/agent.compose.yml` runs the
535
- agent (`:2.3.2`) with a co-located `:mcp` sidecar.
529
+ agent (`:2.3.3`) with a co-located `:mcp` sidecar.
536
530
 
537
531
  ### Knowledge-graph database (`epistemic-graph`)
538
532
 
@@ -596,7 +590,7 @@ to just this package. Ask your agent to **"deploy `nextcloud-agent` with agent-o
596
590
  |------|---------|
597
591
  | Bare-metal, prod (PyPI) | `uvx nextcloud-mcp` · or `uv tool install nextcloud-agent` |
598
592
  | Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
599
- | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.2` via docker-compose / swarm / podman / podman-compose / kubernetes |
593
+ | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.3` via docker-compose / swarm / podman / podman-compose / kubernetes |
600
594
  | Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
601
595
 
602
596
  Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
@@ -617,7 +611,7 @@ to **"deploy `nextcloud-agent` with agent-connector-sdk-deployment"**.
617
611
  |------|---------|
618
612
  | Installed package | `uv tool install "nextcloud-agent[mcp]"`, then run `nextcloud-mcp` |
619
613
  | Editable source | `uv pip install -e ".[agent]"`, then run `nextcloud-mcp` |
620
- | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.2` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
614
+ | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.3` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
621
615
 
622
616
  The repository embeds no deployment profile, credential value, certificate path, or
623
617
  environment-specific endpoint. Supply those at runtime through `AgentConfig` and the
@@ -20,8 +20,6 @@
20
20
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/nextcloud-agent)
21
21
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/nextcloud-agent)
22
22
 
23
- *Version: 2.3.2*
24
-
25
23
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
26
24
  > interfaces, and guidance for provisioning the backing Nextcloud instance are
27
25
  > maintained in the [official documentation](https://knuckles-team.github.io/nextcloud-agent/).
@@ -322,7 +320,7 @@ services:
322
320
  max-file: "3"
323
321
 
324
322
  nextcloud-agent-agent:
325
- image: knucklessg1/nextcloud-agent:2.3.2
323
+ image: knucklessg1/nextcloud-agent:2.3.3
326
324
  container_name: nextcloud-agent-agent
327
325
  hostname: nextcloud-agent-agent
328
326
  restart: always
@@ -493,15 +491,15 @@ One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `
493
491
  | Image tag | Build target | Contents | Entrypoint |
494
492
  |-----------|--------------|----------|------------|
495
493
  | `knucklessg1/nextcloud-agent:mcp` | `--target mcp` | `nextcloud-agent[mcp]` — **connector-focused**, includes `epistemic-graph[full]`; no model-orchestration stack | `nextcloud-mcp` |
496
- | `knucklessg1/nextcloud-agent:2.3.2` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
494
+ | `knucklessg1/nextcloud-agent:2.3.3` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
497
495
 
498
496
  ```bash
499
497
  docker build --target mcp -t knucklessg1/nextcloud-agent:mcp docker/ # connector-focused MCP server
500
- docker build --target agent -t knucklessg1/nextcloud-agent:2.3.2 docker/ # agent runtime
498
+ docker build --target agent -t knucklessg1/nextcloud-agent:2.3.3 docker/ # agent runtime
501
499
  ```
502
500
 
503
501
  `docker/mcp.compose.yml` runs the connector-focused `:mcp` server; `docker/agent.compose.yml` runs the
504
- agent (`:2.3.2`) with a co-located `:mcp` sidecar.
502
+ agent (`:2.3.3`) with a co-located `:mcp` sidecar.
505
503
 
506
504
  ### Knowledge-graph database (`epistemic-graph`)
507
505
 
@@ -565,7 +563,7 @@ to just this package. Ask your agent to **"deploy `nextcloud-agent` with agent-o
565
563
  |------|---------|
566
564
  | Bare-metal, prod (PyPI) | `uvx nextcloud-mcp` · or `uv tool install nextcloud-agent` |
567
565
  | Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
568
- | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.2` via docker-compose / swarm / podman / podman-compose / kubernetes |
566
+ | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.3` via docker-compose / swarm / podman / podman-compose / kubernetes |
569
567
  | Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
570
568
 
571
569
  Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
@@ -586,7 +584,7 @@ to **"deploy `nextcloud-agent` with agent-connector-sdk-deployment"**.
586
584
  |------|---------|
587
585
  | Installed package | `uv tool install "nextcloud-agent[mcp]"`, then run `nextcloud-mcp` |
588
586
  | Editable source | `uv pip install -e ".[agent]"`, then run `nextcloud-mcp` |
589
- | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.2` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
587
+ | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.3` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
590
588
 
591
589
  The repository embeds no deployment profile, credential value, certificate path, or
592
590
  environment-specific endpoint. Supply those at runtime through `AgentConfig` and the
@@ -0,0 +1,11 @@
1
+ from agent_connector_sdk.connector import Connector
2
+
3
+ from nextcloud_agent.api_client import NextcloudAPI
4
+ from nextcloud_agent.auth import get_client
5
+
6
+ connector = Connector(
7
+ api=NextcloudAPI,
8
+ get_client=get_client,
9
+ tools="nextcloud_agent.mcp_server",
10
+ instructions="nextcloud-agent MCP Server — Condensed Action-Routed Tools.",
11
+ )
@@ -0,0 +1,4 @@
1
+ from agent_connector_sdk import run
2
+
3
+ if __name__ == "__main__":
4
+ run()
@@ -0,0 +1,82 @@
1
+ """Data sources of this connector, declared by tool name (generated by connector-ontology-map migrate).
2
+
3
+ Served live as ``connector://resources``. Regenerate by editing the declarations, not the tools.
4
+ """
5
+
6
+ # ruff: noqa: E501
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ from agent_connector_sdk.ingest.live_declaration import source_meta
12
+
13
+ SOURCES: tuple[Any, ...] = (
14
+ source_meta(
15
+ tool="nextcloud_list_files",
16
+ source_id="nextcloud-files",
17
+ record_type="File",
18
+ id_field="file_id",
19
+ cursor_field="last_modified",
20
+ preset={
21
+ "doc_type": "file",
22
+ "params_style": "args",
23
+ },
24
+ records_path="",
25
+ server="nextcloud-mcp",
26
+ text_field="name",
27
+ title_field="name",
28
+ ),
29
+ )
30
+
31
+ SCHEMA_VERSION = 2
32
+
33
+ FIELD_SETS: dict[str, dict[str, str]] = {
34
+ "fields_1": {
35
+ "mimeType": "xsd:string",
36
+ "modifiedAt": "xsd:string",
37
+ "path": "xsd:string",
38
+ "sizeBytes": "xsd:integer",
39
+ },
40
+ }
41
+
42
+ SCHEMA_MAPPINGS: dict[str, Any] = {
43
+ "CalendarEvent": {
44
+ "field_sets": ["fields_1"],
45
+ "ontology_class": "Event",
46
+ },
47
+ "File": {
48
+ "field_sets": ["fields_1"],
49
+ "ontology_class": "File",
50
+ },
51
+ "Folder": {
52
+ "field_sets": ["fields_1"],
53
+ "ontology_class": None,
54
+ },
55
+ "Share": {
56
+ "field_sets": ["fields_1"],
57
+ "ontology_class": None,
58
+ },
59
+ }
60
+
61
+ RESOURCES: tuple[dict[str, str], ...] = (
62
+ {
63
+ "id_prefix": "calendarevent",
64
+ "label": "Calendar Event",
65
+ "name": "CalendarEvent",
66
+ },
67
+ {
68
+ "id_prefix": "file",
69
+ "label": "Nextcloud File",
70
+ "name": "File",
71
+ },
72
+ {
73
+ "id_prefix": "folder",
74
+ "label": "Nextcloud Folder",
75
+ "name": "Folder",
76
+ },
77
+ {
78
+ "id_prefix": "share",
79
+ "label": "Nextcloud Share",
80
+ "name": "Share",
81
+ },
82
+ )
@@ -17,65 +17,11 @@ import posixpath
17
17
  from typing import Any
18
18
 
19
19
  from agent_connector_sdk.ingest import (
20
- ChangeSet,
21
- Entity,
22
- IngestBinding,
23
- IngestError,
24
20
  KnowledgeIngest,
25
- Relationship,
26
- current_ingest,
21
+ SourceStream,
27
22
  )
28
23
 
29
- _BINDING = IngestBinding(connector="nextcloud-mcp", stream="nextcloud")
30
-
31
- _ENTITY_RESERVED_KEYS = frozenset({"id", "node_type"})
32
- _RELATIONSHIP_RESERVED_KEYS = frozenset({"source", "target", "relationship"})
33
-
34
-
35
- def _to_entity(record: dict[str, Any]) -> Entity:
36
- return Entity(
37
- id=record.get("id"),
38
- node_type=record.get("node_type"),
39
- properties={
40
- key: value
41
- for key, value in record.items()
42
- if key not in _ENTITY_RESERVED_KEYS
43
- },
44
- )
45
-
46
-
47
- def _to_relationship(record: dict[str, Any]) -> Relationship:
48
- properties = {
49
- key: value
50
- for key, value in record.items()
51
- if key not in _RELATIONSHIP_RESERVED_KEYS
52
- }
53
- return Relationship(
54
- source=record["source"],
55
- target=record["target"],
56
- relationship=record["relationship"],
57
- properties=properties or None,
58
- )
59
-
60
-
61
- async def _ingest(
62
- entities: list[dict[str, Any]],
63
- relationships: list[dict[str, Any]] | None = None,
64
- *,
65
- ingest: KnowledgeIngest | None = None,
66
- ) -> dict[str, int]:
67
- """Route typed nodes/edges through the SDK ingest facade (injectable for tests)."""
68
- if not entities:
69
- raise IngestError("ingest needs at least one entity")
70
- change_set = ChangeSet(
71
- entities=tuple(_to_entity(entity) for entity in entities),
72
- relationships=tuple(
73
- _to_relationship(relationship) for relationship in relationships or ()
74
- ),
75
- )
76
- service = ingest or current_ingest()
77
- receipt = await service.submit(_BINDING, change_set)
78
- return {"nodes": receipt.affected_count, "edges": receipt.relationship_count}
24
+ STREAM = SourceStream.for_package(__package__.split(".")[0], "nextcloud")
79
25
 
80
26
 
81
27
  async def ingest_listing(
@@ -143,7 +89,7 @@ async def ingest_listing(
143
89
  {"source": node["id"], "target": parent_id, "relationship": "inFolder"}
144
90
  )
145
91
 
146
- return await _ingest(entities, relationships, ingest=ingest)
92
+ return await STREAM.entities(entities, relationships, ingest=ingest)
147
93
 
148
94
 
149
95
  async def ingest_shares(
@@ -192,7 +138,7 @@ async def ingest_shares(
192
138
  )
193
139
  if not entities:
194
140
  return None
195
- return await _ingest(entities, relationships, ingest=ingest)
141
+ return await STREAM.entities(entities, relationships, ingest=ingest)
196
142
 
197
143
 
198
144
  async def ingest_calendar_events(
@@ -218,4 +164,4 @@ async def ingest_calendar_events(
218
164
  )
219
165
  if not entities:
220
166
  return None
221
- return await _ingest(entities, None, ingest=ingest)
167
+ return await STREAM.entities(entities, None, ingest=ingest)
@@ -3,7 +3,6 @@ import warnings
3
3
 
4
4
  from fastmcp import Context, FastMCP
5
5
  from fastmcp.dependencies import Depends
6
- from fastmcp.utilities.logging import get_logger
7
6
  from pydantic import Field
8
7
 
9
8
  # Filter RequestsDependencyWarning early to prevent log spam
@@ -19,26 +18,12 @@ with warnings.catch_warnings():
19
18
  warnings.filterwarnings("ignore", message=".*urllib3.*or chardet.*")
20
19
  warnings.filterwarnings("ignore", message=".*urllib3.*or charset_normalizer.*")
21
20
 
22
- import logging
23
- import sys
24
- from typing import Any
25
21
 
26
- from agent_connector_sdk.config import load_config
27
22
  from agent_connector_sdk.mcp.action_dispatch import resolve_action
28
23
  from agent_connector_sdk.mcp.concurrency import run_blocking
29
- from agent_connector_sdk.mcp.server import create_mcp_server
30
- from agent_connector_sdk.mcp.tool_surface import register_tool_surface
31
- from starlette.requests import Request
32
- from starlette.responses import JSONResponse
33
24
 
34
- from nextcloud_agent.api_client import NextcloudAPI
35
25
  from nextcloud_agent.auth import get_client
36
26
 
37
- __version__ = "2.3.2"
38
-
39
- logger = get_logger(name="nextcloud-agent")
40
- logger.setLevel(logging.INFO)
41
-
42
27
 
43
28
  def register_files_tools(mcp: FastMCP):
44
29
  """
@@ -303,56 +288,3 @@ def register_contacts_tools(mcp: FastMCP):
303
288
  if action == "create_contact":
304
289
  return await run_blocking(client.create_contact, **kwargs)
305
290
  raise ValueError(f"Unknown action: {action}")
306
-
307
-
308
- def get_mcp_instance() -> tuple[Any, ...]:
309
- """
310
- Initialize and return the MCP instance.
311
- """
312
- load_config()
313
- args, mcp, middlewares = create_mcp_server(
314
- name="nextcloud-agent MCP",
315
- version=__version__,
316
- instructions="nextcloud-agent MCP Server — Condensed Action-Routed Tools.",
317
- )
318
-
319
- @mcp.custom_route("/health", methods=["GET"])
320
- async def health_check(request: Request) -> JSONResponse:
321
- return JSONResponse({"status": "OK"})
322
-
323
- register_tool_surface(
324
- mcp,
325
- client_cls=NextcloudAPI,
326
- get_client=get_client,
327
- service="nextcloud-agent",
328
- tools_module=sys.modules[__name__],
329
- )
330
-
331
- for mw in middlewares:
332
- mcp.add_middleware(mw)
333
- return mcp, args, middlewares
334
-
335
-
336
- def mcp_server() -> None:
337
- """
338
- Launch the MCP server process.
339
- """
340
- mcp, args, middlewares = get_mcp_instance()
341
- print(f"nextcloud-agent MCP v{__version__}", file=sys.stderr)
342
- print("\nStarting MCP Server", file=sys.stderr)
343
- print(f" Transport: {args.transport.upper()}", file=sys.stderr)
344
- print(f" Auth: {args.auth_type}", file=sys.stderr)
345
-
346
- if args.transport == "stdio":
347
- mcp.run(transport="stdio")
348
- elif args.transport == "streamable-http":
349
- mcp.run(transport="streamable-http", host=args.host, port=args.port)
350
- elif args.transport == "sse":
351
- mcp.run(transport="sse", host=args.host, port=args.port)
352
- else:
353
- logger.error("Invalid transport", extra={"transport": args.transport})
354
- sys.exit(1)
355
-
356
-
357
- if __name__ == "__main__":
358
- mcp_server()
@@ -1,13 +1,10 @@
1
1
  {
2
- "api_version": "arbora.io/v1",
2
+ "api_version": "graphos.io/v1",
3
3
  "artifacts": {
4
- "connector_manifest.yml": "3ce0f7ad3717ff79b1a269b91f29f09159309cdadc3663daa22e982b18b85a41",
5
- "nextcloud_agent/connectors/mcp_source_presets.json": "c414c7c710127203405dd518135916111e0b2f197f4e4edcc25588c0d281f8ce",
6
- "nextcloud_agent/connectors/tool_schema_fingerprints.json": "f1b99eb4cb9c36df8c61b3beb915c95c45204cbca82de59098c0bcc2f9c814ec",
7
4
  "nextcloud_agent/ontology/fixtures/records.json": "aeff7048eae4bc5068dcd2070ad0f0e02b1de63bf9fd5dbecf6a51c5ebd26dc7",
8
- "nextcloud_agent/ontology/mappings/source.yaml": "eac08da9aa72d040d223652f0d55ec6b3847527630fde0291601e1b77b216739",
5
+ "nextcloud_agent/ontology/mappings/source.yaml": "88a1d3c331f53626adcb3998eb8f262a33a59065ad8f99ad70e7a82a14c41d49",
9
6
  "nextcloud_agent/ontology/migrations/manifest.json": "25716b991f14c59cc202177dfa6d410b396e18a5c9accc92238e5433825535e7",
10
- "nextcloud_agent/ontology/nextcloud.ttl": "1f2f60e44e2e7f49bb86365d488668ce08724f114e67364d21ec302fcc516956",
7
+ "nextcloud_agent/ontology/nextcloud.ttl": "19a6a86795f930ab216e58fa59f02aa4f26ccf0cd08a3dee859383b640d1f30f",
11
8
  "nextcloud_agent/ontology/shapes/connector.shacl.ttl": "9a8192289bd6b9a24b4d215cf0fe0391d7e706cf461704dff4c537b5f82724f6"
12
9
  },
13
10
  "checks": {
@@ -18,11 +15,11 @@
18
15
  "synthetic_fixture_contract": "passed"
19
16
  },
20
17
  "compatibility": {
21
- "agent_connector_sdk": ">=2.5.0,<3",
18
+ "agent_utilities": ">=2.5.0,<3",
22
19
  "bundle_schema": "2",
23
20
  "epistemic_graph": ">=2.27.0,<3"
24
21
  },
25
- "connector": "nextcloud-mcp",
22
+ "connector": "nextcloud-agent",
26
23
  "kind": "ConnectorSourceAttestation",
27
24
  "live_certified": false,
28
25
  "mode": "offline-source",
@@ -32,5 +29,5 @@
32
29
  "signer": "UNSIGNED-PREVIEW",
33
30
  "signing_public_key": "",
34
31
  "status": "source-validated",
35
- "validated_at": "2026-08-26T13:42:55Z"
32
+ "validated_at": "2026-10-24T13:49:17Z"
36
33
  }
@@ -1,5 +1,5 @@
1
1
  schema_version: '1'
2
- connector: nextcloud-agent
2
+ connector: nextcloud-mcp
3
3
  ontology_source: nextcloud
4
4
  sync:
5
5
  - preset: nextcloud-files
@@ -14,21 +14,18 @@
14
14
  # :AssetOccurrence / :Blob / :Document are defined by the hub base ontology and are only
15
15
  # REFERENCED here (never redefined).
16
16
 
17
- :File a owl:Class ;
18
- rdfs:label "Nextcloud File" ;
19
- rdfs:comment "A file stored in Nextcloud (WebDAV resource). Carries its raw bytes as a :AssetOccurrence/:Blob via :hasBlob and its extracted text as a :Document (nextcloud_files read_file)." .
17
+ :File a owl:Class .
18
+
19
+
20
+ :Folder a owl:Class .
20
21
 
21
- :Folder a owl:Class ;
22
- rdfs:label "Nextcloud Folder" ;
23
- rdfs:comment "A WebDAV collection (directory) that contains files and subfolders (nextcloud_files list_files)." .
24
22
 
25
23
  :Share a owl:Class ;
26
24
  rdfs:label "Nextcloud Share" ;
27
25
  rdfs:comment "A sharing grant on a file or folder — public link, user, or group (nextcloud_sharing list_shares)." .
28
26
 
29
- :CalendarEvent a owl:Class ;
30
- rdfs:label "Calendar Event" ;
31
- rdfs:comment "A CalDAV calendar event (.ics) hosted in Nextcloud (nextcloud_calendar list_calendar_events)." .
27
+ :CalendarEvent a owl:Class .
28
+
32
29
 
33
30
  # --- links (owl:ObjectProperty) ---
34
31
 
@@ -88,5 +85,7 @@
88
85
  rdfs:comment """Nextcloud file-storage and collaboration model — files, folders, shares
89
86
  and calendar events over WebDAV/CalDAV — federated into the agent-connector-sdk
90
87
  knowledge-graph hub. Files carry their raw bytes as federated :AssetOccurrence/:Blob
91
- (via :hasBlob) and their extracted text as federated :Document nodes.""" ;
92
- owl:imports <http://knuckles.team/kg> .
88
+ (via :hasBlob) and their extracted text as federated :Document nodes.""" .
89
+
90
+ # ontology-codemod R4
91
+ <http://knuckles.team/kg#Share> rdfs:subClassOf <http://knuckles.team/kg#Resource> .
@@ -4,8 +4,6 @@
4
4
  "schema_version": "1.0",
5
5
  "prompt_version": "0.1.0",
6
6
  "source": "nextcloud-agent",
7
- "extends": "agent-connector-sdk:base",
8
- "compose": "append",
9
7
  "description": "Nextcloud file steward: browse, share, and natively ingest files and folders into the knowledge graph over the nextcloud-agent MCP server.",
10
8
  "metadata": {
11
9
  "topic": "Nextcloud file stewardship",
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nextcloud-agent
3
- Version: 2.3.2
3
+ Version: 2.3.4
4
4
  Summary: Nextcloud MCP Server for Agentic AI!
5
- Author-email: Project Maintainers <maintainers@users.noreply.github.com>
5
+ Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
7
7
  Classifier: Development Status :: 3 - Alpha
8
8
  Classifier: License :: OSI Approved :: MIT License
@@ -12,16 +12,12 @@ Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.12
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18
15
+ Requires-Dist: agent-connector-sdk[mcp]<0.6.0,>=0.5.4
16
16
  Requires-Dist: requests>=2.34.2
17
17
  Requires-Dist: defusedxml>=0.7.1
18
18
  Requires-Dist: python-dateutil>=2.9.0.post0
19
19
  Requires-Dist: icalendar>=7.3.0
20
20
  Requires-Dist: vobject>=0.9.9
21
- Provides-Extra: mcp
22
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "mcp"
23
- Provides-Extra: all
24
- Requires-Dist: agent-connector-sdk[mcp]<1.0.0,>=0.3.18; extra == "all"
25
21
  Provides-Extra: test
26
22
  Requires-Dist: pytest-xdist>=3.8.0; extra == "test"
27
23
  Requires-Dist: pytest>=9.1.1; extra == "test"
@@ -51,8 +47,6 @@ Dynamic: license-file
51
47
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/nextcloud-agent)
52
48
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/nextcloud-agent)
53
49
 
54
- *Version: 2.3.2*
55
-
56
50
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
57
51
  > interfaces, and guidance for provisioning the backing Nextcloud instance are
58
52
  > maintained in the [official documentation](https://knuckles-team.github.io/nextcloud-agent/).
@@ -353,7 +347,7 @@ services:
353
347
  max-file: "3"
354
348
 
355
349
  nextcloud-agent-agent:
356
- image: knucklessg1/nextcloud-agent:2.3.2
350
+ image: knucklessg1/nextcloud-agent:2.3.3
357
351
  container_name: nextcloud-agent-agent
358
352
  hostname: nextcloud-agent-agent
359
353
  restart: always
@@ -524,15 +518,15 @@ One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `
524
518
  | Image tag | Build target | Contents | Entrypoint |
525
519
  |-----------|--------------|----------|------------|
526
520
  | `knucklessg1/nextcloud-agent:mcp` | `--target mcp` | `nextcloud-agent[mcp]` — **connector-focused**, includes `epistemic-graph[full]`; no model-orchestration stack | `nextcloud-mcp` |
527
- | `knucklessg1/nextcloud-agent:2.3.2` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
521
+ | `knucklessg1/nextcloud-agent:2.3.3` | `--target agent` (default) | `nextcloud-agent[agent]` — **agent runtime**, model orchestration + `epistemic-graph[full]` | `nextcloud-agent` |
528
522
 
529
523
  ```bash
530
524
  docker build --target mcp -t knucklessg1/nextcloud-agent:mcp docker/ # connector-focused MCP server
531
- docker build --target agent -t knucklessg1/nextcloud-agent:2.3.2 docker/ # agent runtime
525
+ docker build --target agent -t knucklessg1/nextcloud-agent:2.3.3 docker/ # agent runtime
532
526
  ```
533
527
 
534
528
  `docker/mcp.compose.yml` runs the connector-focused `:mcp` server; `docker/agent.compose.yml` runs the
535
- agent (`:2.3.2`) with a co-located `:mcp` sidecar.
529
+ agent (`:2.3.3`) with a co-located `:mcp` sidecar.
536
530
 
537
531
  ### Knowledge-graph database (`epistemic-graph`)
538
532
 
@@ -596,7 +590,7 @@ to just this package. Ask your agent to **"deploy `nextcloud-agent` with agent-o
596
590
  |------|---------|
597
591
  | Bare-metal, prod (PyPI) | `uvx nextcloud-mcp` · or `uv tool install nextcloud-agent` |
598
592
  | Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
599
- | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.2` via docker-compose / swarm / podman / podman-compose / kubernetes |
593
+ | Container, prod | deploy `knucklessg1/nextcloud-agent:2.3.3` via docker-compose / swarm / podman / podman-compose / kubernetes |
600
594
  | Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
601
595
 
602
596
  Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
@@ -617,7 +611,7 @@ to **"deploy `nextcloud-agent` with agent-connector-sdk-deployment"**.
617
611
  |------|---------|
618
612
  | Installed package | `uv tool install "nextcloud-agent[mcp]"`, then run `nextcloud-mcp` |
619
613
  | Editable source | `uv pip install -e ".[agent]"`, then run `nextcloud-mcp` |
620
- | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.2` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
614
+ | Immutable container | deploy `knucklessg1/nextcloud-agent:2.3.3` (or a pinned `@sha256:<digest>`) through the operator-selected orchestrator |
621
615
 
622
616
  The repository embeds no deployment profile, credential value, certificate path, or
623
617
  environment-specific endpoint. Supply those at runtime through `AgentConfig` and the
@@ -5,6 +5,7 @@ nextcloud_agent/__init__.py
5
5
  nextcloud_agent/__main__.py
6
6
  nextcloud_agent/api_client.py
7
7
  nextcloud_agent/auth.py
8
+ nextcloud_agent/connector_sources.py
8
9
  nextcloud_agent/kg_ingest.py
9
10
  nextcloud_agent/mcp_config.json
10
11
  nextcloud_agent/mcp_server.py
@@ -20,9 +21,6 @@ nextcloud_agent/api/api_client_calendar.py
20
21
  nextcloud_agent/api/api_client_contacts.py
21
22
  nextcloud_agent/api/api_client_files.py
22
23
  nextcloud_agent/api/xml_security.py
23
- nextcloud_agent/connectors/__init__.py
24
- nextcloud_agent/connectors/mcp_source_presets.json
25
- nextcloud_agent/connectors/tool_schema_fingerprints.json
26
24
  nextcloud_agent/ontology/__init__.py
27
25
  nextcloud_agent/ontology/certification.json
28
26
  nextcloud_agent/ontology/nextcloud.ttl
@@ -30,9 +28,7 @@ nextcloud_agent/ontology/fixtures/records.json
30
28
  nextcloud_agent/ontology/mappings/source.yaml
31
29
  nextcloud_agent/ontology/migrations/manifest.json
32
30
  nextcloud_agent/ontology/shapes/connector.shacl.ttl
33
- nextcloud_agent/prompts/__init__.py
34
31
  nextcloud_agent/prompts/file_steward.json
35
- nextcloud_agent/skills/__init__.py
36
32
  nextcloud_agent/skills/nextcloud-agent-operations/SKILL.md
37
33
  nextcloud_agent/skills/nextcloud-agent-operations/agents/openai.yaml
38
34
  nextcloud_agent/skills/nextcloud-agent-operations/references/catalog.md
@@ -42,13 +38,9 @@ nextcloud_agent/skills/nextcloud-ingest/SKILL.md
42
38
  nextcloud_agent/skills/nextcloud-ingest/WORKFLOW.md
43
39
  nextcloud_agent/skills/nextcloud-shares/SKILL.md
44
40
  nextcloud_agent/skills/nextcloud-shares/WORKFLOW.md
45
- scripts/security_sanitizer.py
46
- scripts/verify_api_integration.py
47
41
  tests/conftest.py
48
42
  tests/test_api_client.py
49
43
  tests/test_auth.py
50
- tests/test_cli_server.py
51
- tests/test_default_content_surfaces.py
52
44
  tests/test_fleet_name.py
53
45
  tests/test_init.py
54
46
  tests/test_init_dynamics.py
@@ -0,0 +1,8 @@
1
+ [agent_connector_sdk.connector]
2
+ nextcloud-mcp = nextcloud_agent:connector
3
+
4
+ [agent_connector_sdk.prompt_providers]
5
+ nextcloud-agent = nextcloud_agent.prompts
6
+
7
+ [console_scripts]
8
+ nextcloud-mcp = agent_connector_sdk.cli:serve