1717
1818
1919@mcp .tool (
20- description = "Create or update a markdown note. Returns the permalink for referencing ." ,
20+ description = "Create or update a markdown note. Returns a markdown formatted summary of the semantic content ." ,
2121)
2222async def write_note (
2323 title : str ,
2424 content : str ,
2525 folder : str ,
2626 tags : Optional [List [str ]] = None ,
27- verbose : bool = False ,
28- ) -> EntityResponse | str :
27+ ) -> str :
2928 """Write a markdown note to the knowledge base.
3029
3130 The content can include semantic observations and relations using markdown syntax.
@@ -53,14 +52,16 @@ async def write_note(
5352 content: Markdown content for the note, can include observations and relations
5453 folder: the folder where the file should be saved
5554 tags: Optional list of tags to categorize the note
56- verbose: If True, returns full EntityResponse with semantic info
5755
5856 Returns:
59- If verbose=False: Permalink that can be used to reference the note
60- If verbose=True: EntityResponse with full semantic details
57+ A markdown formatted summary of the semantic content, including:
58+ - Creation/update status
59+ - File path and checksum
60+ - Observation counts by category
61+ - Relation counts (resolved/unresolved)
62+ - Tags if present
6163
6264 Examples:
63- # Note with both explicit and inline relations
6465 write_note(
6566 title="Search Implementation",
6667 content="# Search Component\\ n\\ n"
@@ -73,20 +74,6 @@ async def write_note(
7374 "- depends_on [[Database Schema]]",
7475 folder="docs/components"
7576 )
76-
77- # Note with tags
78- write_note(
79- title="Error Handling Design",
80- content="# Error Handling\\ n\\ n"
81- "This design builds on [[Reliability Design]].\\ n\\ n"
82- "## Approach\\ n"
83- "- [design] Use error codes #architecture\\ n"
84- "- [tech] Implement retry logic #implementation\\ n\\ n"
85- "## Relations\\ n"
86- "- extends [[Base Error Handling]]",
87- folder="docs/design",
88- tags=["architecture", "reliability"]
89- )
9077 """
9178 logger .info (f"Writing note folder:'{ folder } ' title: '{ title } '" )
9279
@@ -101,12 +88,43 @@ async def write_note(
10188 entity_metadata = metadata ,
10289 )
10390
104- # Use existing knowledge tool
91+ # Create or update via knowledge API
10592 logger .info (f"Creating { entity .permalink } " )
10693 url = f"/knowledge/entities/{ entity .permalink } "
10794 response = await call_put (client , url , json = entity .model_dump ())
10895 result = EntityResponse .model_validate (response .json ())
109- return result if verbose else result .permalink
96+
97+ # Format semantic summary based on status code
98+ action = "Created" if response .status_code == 201 else "Updated"
99+ assert result .checksum is not None
100+ summary = [
101+ f"# { action } { result .file_path } ({ result .checksum [:8 ]} )" ,
102+ f"permalink: { result .permalink } " ,
103+ ]
104+
105+ if result .observations :
106+ categories = {}
107+ for obs in result .observations :
108+ categories [obs .category ] = categories .get (obs .category , 0 ) + 1
109+
110+ summary .append ("\n ## Observations" )
111+ for category , count in sorted (categories .items ()):
112+ summary .append (f"- { category } : { count } " )
113+
114+ if result .relations :
115+ unresolved = sum (1 for r in result .relations if not r .to_id )
116+ resolved = len (result .relations ) - unresolved
117+
118+ summary .append ("\n ## Relations" )
119+ summary .append (f"- Resolved: { resolved } " )
120+ if unresolved :
121+ summary .append (f"- Unresolved: { unresolved } " )
122+ summary .append ("\n Unresolved relations will be retried on next sync." )
123+
124+ if tags :
125+ summary .append (f"\n ## Tags\n - { ', ' .join (tags )} " )
126+
127+ return "\n " .join (summary )
110128
111129
112130@mcp .tool (description = "Read note content by title, permalink, relation, or pattern" )
0 commit comments