fix: address PR review feedback
Address all reviewer comments from PR #387: 1. ✅ Add unit tests for annotations (tests/server/test_annotations.py) - 10 comprehensive test functions validating all annotation patterns - Tests for titles, read-only, destructive, idempotent operations - Validates specific ADR-017 decisions (webdav write, semantic search) - Cross-category consistency checks 2. ✅ Fix nc_webdav_write_file idempotency classification - Changed from idempotentHint=False to idempotentHint=True - Rationale: Uses HTTP PUT without version control - Writing same content to same path = same end state (idempotent) 3. ✅ Fix semantic search openWorldHint inconsistency - Changed from openWorldHint=False to openWorldHint=True - Rationale: Consistent with other Nextcloud tools - Nextcloud is external to MCP server (indexed data is implementation detail) 4. ✅ Update ADR-017 with resolved decisions - Converted Open Questions to Resolved Questions - Added detailed rationale for webdav write and semantic search - Updated status from Proposed to Implemented - Added decision timeline with dates 5. ✅ Add MCP Tool Annotations guidelines to CLAUDE.md - Comprehensive section with code examples for all patterns - Key principles documented (idempotency, destructive, open world) - References ADR-017 for detailed rationale All OAuth tools verified to have proper annotations (oauth_tools.py lines 686-751).
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
Implemented
|
||||
|
||||
## Context
|
||||
|
||||
@@ -67,10 +67,12 @@ async def tool(
|
||||
- **Deletes**: `delete_note(id=1)` → note deleted
|
||||
- Second call → 404 or success (same end state: note doesn't exist)
|
||||
- Note: May return different status code, but end state is identical
|
||||
- **Full resource PUT without version control**: Would be idempotent (we don't have these)
|
||||
- **Full resource PUT without version control**: `write_file(path="/test.txt", content="Hello")` → file has "Hello"
|
||||
- Second call → file still has "Hello" (same end state)
|
||||
- Example: `nc_webdav_write_file` uses HTTP PUT without etags/version control
|
||||
- **Set operations**: `set_property(id=1, value="X")` → property = X
|
||||
- Second call → property still = X (same result)
|
||||
- Note: Nextcloud updates use etags, so not applicable
|
||||
- Note: Nextcloud updates with etags use version control, so not idempotent
|
||||
|
||||
**Read-Only** (always idempotent, never destructive):
|
||||
- All list, search, get operations
|
||||
@@ -471,11 +473,23 @@ def test_notes_tools_have_annotations():
|
||||
- Add annotation guidelines to CLAUDE.md
|
||||
- Include examples in developer documentation
|
||||
|
||||
## Open Questions
|
||||
## Resolved Questions
|
||||
|
||||
1. **WebDAV write_file idempotency** (Resolved: 2025-12-11)
|
||||
- **Decision**: Mark as `idempotentHint=True`
|
||||
- **Rationale**: Uses HTTP PUT without version control. Writing same content to same path repeatedly produces identical end state, which is the definition of idempotency in HTTP semantics.
|
||||
|
||||
2. **Semantic search openWorldHint** (Resolved: 2025-12-11)
|
||||
- **Decision**: Mark as `openWorldHint=True`
|
||||
- **Rationale**: For consistency with other Nextcloud tools. While the data being searched is "indexed/internal", Nextcloud itself is external to the MCP server. The fact that data is indexed is an implementation detail, not a fundamental difference from other Nextcloud queries.
|
||||
|
||||
1. **Icons**: Should we add visual icons for tools? (Requires design work)
|
||||
2. **Semantic search openWorldHint**: False (internal data only) or True (Nextcloud is external)?
|
||||
3. **Read-only with side effects**: Should tools that log analytics still be readOnlyHint=true?
|
||||
- **Decision**: Yes. Logging/analytics are non-visible side effects that don't change user-observable state. Read-only refers to data modifications that affect the user's content.
|
||||
|
||||
## Future Considerations
|
||||
|
||||
1. **Icons**: Visual icons for tools (requires design work, deferred to future ADR)
|
||||
2. **Parameter descriptions**: Add Pydantic `Field(description=...)` for better auto-completion (Phase 3, future work)
|
||||
|
||||
## References
|
||||
|
||||
@@ -487,6 +501,6 @@ def test_notes_tools_have_annotations():
|
||||
## Decision Timeline
|
||||
|
||||
- **Proposed**: 2025-12-11
|
||||
- **Reviewed**: TBD
|
||||
- **Accepted**: TBD
|
||||
- **Implemented**: TBD
|
||||
- **Reviewed**: 2025-12-11 (Self-review during implementation)
|
||||
- **Accepted**: 2025-12-11
|
||||
- **Implemented**: 2025-12-11 (Phase 1 & 2 complete)
|
||||
|
||||
Reference in New Issue
Block a user