Skip to content

Commit 08db5e8

Browse files
committed
merge latest from upstream
1 parent 04c83dc commit 08db5e8

2 files changed

Lines changed: 29 additions & 59 deletions

File tree

src/basic_memory/mcp/tools/chatgpt_tools.py

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
"""ChatGPT-compatible MCP tools for Basic Memory.
22
3-
This module provides simplified 'search' and 'fetch' tools that adapt Basic Memory's
4-
rich MCP interface to ChatGPT's expected naming conventions and MCP content array format.
5-
6-
ChatGPT's MCP integration expects:
7-
- search(query: str) -> MCP content array with JSON-encoded results
8-
- fetch(id: str) -> MCP content array with JSON-encoded document
9-
10-
These tools wrap our existing search_notes and read_note functions and format
11-
responses according to OpenAI's MCP specification.
3+
These adapters expose Basic Memory's search/fetch functionality using the exact
4+
tool names and response structure OpenAI's MCP clients expect: each call returns
5+
a list containing a single `{"type": "text", "text": "{...json...}"}` item.
126
"""
137

148
import json
@@ -83,27 +77,15 @@ async def search(
8377
query: str,
8478
context: Context | None = None,
8579
) -> List[Dict[str, Any]]:
86-
"""Search for content across the knowledge base.
87-
88-
This tool provides a simplified search interface optimized for ChatGPT's
89-
MCP integration. It returns results in the required MCP content array format.
80+
"""ChatGPT/OpenAI MCP search adapter returning a single text content item.
9081
9182
Args:
92-
query: Search query string (supports boolean operators, phrases)
93-
context: MCP context for authentication and routing
83+
query: Search query (full-text syntax supported by `search_notes`)
84+
context: Optional FastMCP context passed through for auth/session data
9485
9586
Returns:
96-
MCP content array with exactly one item containing JSON-encoded search results
97-
98-
The response follows OpenAI's MCP specification:
99-
{
100-
"content": [
101-
{
102-
"type": "text",
103-
"text": "{\"results\":[{\"id\":\"doc-1\",\"title\":\"...\",\"url\":\"...\"}]}"
104-
}
105-
]
106-
}
87+
List with one dict: `{ "type": "text", "text": "{...JSON...}" }`
88+
where the JSON body contains `results`, `total_count`, and echo of `query`.
10789
"""
10890
logger.info(f"ChatGPT search request: query='{query}'")
10991

@@ -165,27 +147,15 @@ async def fetch(
165147
id: str,
166148
context: Context | None = None,
167149
) -> List[Dict[str, Any]]:
168-
"""Fetch the full content of a specific document.
169-
170-
This tool provides a simplified fetch interface optimized for ChatGPT's
171-
MCP integration. It returns document content in the required MCP content array format.
150+
"""ChatGPT/OpenAI MCP fetch adapter returning a single text content item.
172151
173152
Args:
174-
id: Document identifier (permalink, title, or memory:// URL)
175-
context: MCP context for authentication and routing
153+
id: Document identifier (permalink, title, or memory URL)
154+
context: Optional FastMCP context passed through for auth/session data
176155
177156
Returns:
178-
MCP content array with exactly one item containing JSON-encoded document
179-
180-
The response follows OpenAI's MCP specification:
181-
{
182-
"content": [
183-
{
184-
"type": "text",
185-
"text": "{\"id\":\"doc-1\",\"title\":\"...\",\"text\":\"full text...\",\"url\":\"...\",\"metadata\":{}}"
186-
}
187-
]
188-
}
157+
List with one dict: `{ "type": "text", "text": "{...JSON...}" }`
158+
where the JSON body includes `id`, `title`, `text`, `url`, and metadata.
189159
"""
190160
logger.info(f"ChatGPT fetch request: id='{id}'")
191161

@@ -225,4 +195,4 @@ async def fetch(
225195
"type": "text",
226196
"text": json.dumps(error_document, ensure_ascii=False)
227197
}
228-
]
198+
]

src/basic_memory/mcp/tools/read_note.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ async def read_note(
2525
page_size: int = 10,
2626
context: Context | None = None,
2727
) -> str:
28-
"""Read a markdown note from the knowledge base.
28+
"""Return the raw markdown for a note, or guidance text if no match is found.
2929
3030
Finds and retrieves a note by its title, permalink, or content search,
3131
returning the raw markdown content including observations, relations, and metadata.
@@ -171,25 +171,25 @@ def format_not_found_message(project: str | None, identifier: str) -> str:
171171
"""Format a helpful message when no note was found."""
172172
return dedent(f"""
173173
# Note Not Found in {project}: "{identifier}"
174-
174+
175175
I couldn't find any notes matching "{identifier}". Here are some suggestions:
176-
176+
177177
## Check Identifier Type
178178
- If you provided a title, try using the exact permalink instead
179179
- If you provided a permalink, check for typos or try a broader search
180-
180+
181181
## Search Instead
182182
Try searching for related content:
183183
```
184184
search_notes(project="{project}", query="{identifier}")
185185
```
186-
186+
187187
## Recent Activity
188188
Check recently modified notes:
189189
```
190190
recent_activity(timeframe="7d")
191191
```
192-
192+
193193
## Create New Note
194194
This might be a good opportunity to create a new note on this topic:
195195
```
@@ -198,13 +198,13 @@ def format_not_found_message(project: str | None, identifier: str) -> str:
198198
title="{identifier.capitalize()}",
199199
content='''
200200
# {identifier.capitalize()}
201-
201+
202202
## Overview
203203
[Your content here]
204-
204+
205205
## Observations
206206
- [category] [Observation about {identifier}]
207-
207+
208208
## Relations
209209
- relates_to [[Related Topic]]
210210
''',
@@ -218,34 +218,34 @@ def format_related_results(project: str | None, identifier: str, results) -> str
218218
"""Format a helpful message with related results when an exact match wasn't found."""
219219
message = dedent(f"""
220220
# Note Not Found in {project}: "{identifier}"
221-
221+
222222
I couldn't find an exact match for "{identifier}", but I found some related notes:
223-
223+
224224
""")
225225

226226
for i, result in enumerate(results):
227227
message += dedent(f"""
228228
## {i + 1}. {result.title}
229229
- **Type**: {result.type.value}
230230
- **Permalink**: {result.permalink}
231-
231+
232232
You can read this note with:
233233
```
234234
read_note(project="{project}", {result.permalink}")
235235
```
236-
236+
237237
""")
238238

239239
message += dedent(f"""
240240
## Try More Specific Lookup
241241
For exact matches, try using the full permalink from one of the results above.
242-
242+
243243
## Search For More Results
244244
To see more related content:
245245
```
246246
search_notes(project="{project}", query="{identifier}")
247247
```
248-
248+
249249
## Create New Note
250250
If none of these match what you're looking for, consider creating a new note:
251251
```

0 commit comments

Comments
 (0)