fix: Add proper datetime JSON schema format annotations for MCP validation (#312)

Signed-off-by: Claude Code <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Paul Hernandez <phernandez@users.noreply.github.com>
This commit is contained in:
Paul Hernandez
2025-10-03 22:47:02 -05:00
committed by GitHub
parent 903591384d
commit a7bf42ef49
5 changed files with 55 additions and 29 deletions
+11 -4
View File
@@ -103,10 +103,17 @@ def format_prompt_context(context: PromptContext) -> str:
added_permalinks.add(primary_permalink)
memory_url = normalize_memory_url(primary_permalink)
# Use permalink if available, otherwise use file_path
if primary_permalink:
memory_url = normalize_memory_url(primary_permalink)
read_command = f'read_note("{primary_permalink}")'
else:
memory_url = f"file://{primary.file_path}"
read_command = f'read_file("{primary.file_path}")'
section = dedent(f"""
--- {memory_url}
## {primary.title}
- **Type**: {primary.type}
""")
@@ -121,8 +128,8 @@ def format_prompt_context(context: PromptContext) -> str:
section += f"\n**Excerpt**:\n{content}\n"
section += dedent(f"""
You can read this document with: `read_note("{primary_permalink}")`
You can read this document with: `{read_command}`
""")
sections.append(section)
+26 -11
View File
@@ -26,6 +26,7 @@ def validate_memory_url_path(path: str) -> bool:
>>> validate_memory_url_path("invalid://test") # Contains protocol
False
"""
# Empty paths are not valid
if not path or not path.strip():
return False
@@ -68,7 +69,13 @@ def normalize_memory_url(url: str | None) -> str:
ValueError: Invalid memory URL path: 'memory//test' contains double slashes
"""
if not url:
return ""
raise ValueError("Memory URL cannot be empty")
# Strip whitespace for consistency
url = url.strip()
if not url:
raise ValueError("Memory URL cannot be empty or whitespace")
clean_path = url.removeprefix("memory://")
@@ -79,8 +86,6 @@ def normalize_memory_url(url: str | None) -> str:
raise ValueError(f"Invalid memory URL path: '{clean_path}' contains protocol scheme")
elif "//" in clean_path:
raise ValueError(f"Invalid memory URL path: '{clean_path}' contains double slashes")
elif not clean_path.strip():
raise ValueError("Memory URL path cannot be empty or whitespace")
else:
raise ValueError(f"Invalid memory URL path: '{clean_path}' contains invalid characters")
@@ -123,7 +128,9 @@ class EntitySummary(BaseModel):
title: str
content: Optional[str] = None
file_path: str
created_at: datetime
created_at: Annotated[
datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})
]
@field_serializer("created_at")
def serialize_created_at(self, dt: datetime) -> str:
@@ -140,7 +147,9 @@ class RelationSummary(BaseModel):
relation_type: str
from_entity: Optional[str] = None
to_entity: Optional[str] = None
created_at: datetime
created_at: Annotated[
datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})
]
@field_serializer("created_at")
def serialize_created_at(self, dt: datetime) -> str:
@@ -156,7 +165,9 @@ class ObservationSummary(BaseModel):
permalink: str
category: str
content: str
created_at: datetime
created_at: Annotated[
datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})
]
@field_serializer("created_at")
def serialize_created_at(self, dt: datetime) -> str:
@@ -170,7 +181,9 @@ class MemoryMetadata(BaseModel):
types: Optional[List[SearchItemType]] = None
depth: int
timeframe: Optional[str] = None
generated_at: datetime
generated_at: Annotated[
datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})
]
primary_count: Optional[int] = None # Changed field name
related_count: Optional[int] = None # Changed field name
total_results: Optional[int] = None # For backward compatibility
@@ -235,9 +248,9 @@ class ProjectActivity(BaseModel):
project_path: str
activity: GraphContext = Field(description="The actual activity data for this project")
item_count: int = Field(description="Total items in this project's activity")
last_activity: Optional[datetime] = Field(
default=None, description="Most recent activity timestamp"
)
last_activity: Optional[
Annotated[datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})]
] = Field(default=None, description="Most recent activity timestamp")
active_folders: List[str] = Field(default_factory=list, description="Most active folders")
@field_serializer("last_activity")
@@ -253,7 +266,9 @@ class ProjectActivitySummary(BaseModel):
)
summary: ActivityStats
timeframe: str = Field(description="The timeframe used for the query")
generated_at: datetime
generated_at: Annotated[
datetime, Field(json_schema_extra={"type": "string", "format": "date-time"})
]
guidance: Optional[str] = Field(
default=None, description="Assistant guidance for project selection and session management"
)