mirror of
https://github.com/mruwnik/memory.git
synced 2025-06-08 13:24:41 +02:00
better file return
This commit is contained in:
parent
7ac16031bb
commit
f8090634c7
@ -148,6 +148,8 @@ services:
|
|||||||
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
|
POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
|
||||||
QDRANT_URL: http://qdrant:6333
|
QDRANT_URL: http://qdrant:6333
|
||||||
secrets: [postgres_password]
|
secrets: [postgres_password]
|
||||||
|
volumes:
|
||||||
|
- ./memory_files:/app/memory_files:rw
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "curl -fs http://localhost:8000/health || exit 1"]
|
test: ["CMD-SHELL", "curl -fs http://localhost:8000/health || exit 1"]
|
||||||
interval: 15s
|
interval: 15s
|
||||||
|
@ -5,6 +5,7 @@ MCP tools for the epistemic sparring partner system.
|
|||||||
import logging
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
import mimetypes
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@ -385,20 +386,67 @@ async def note_files(path: str = "/"):
|
|||||||
|
|
||||||
|
|
||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
def fetch_file(filename: str):
|
def fetch_file(filename: str) -> dict:
|
||||||
"""
|
"""
|
||||||
Read file content from user's storage.
|
Read file content with automatic type detection.
|
||||||
Use when you need to access specific content of a file that's been referenced.
|
Returns dict with content, mime_type, is_text, file_size.
|
||||||
|
Text content as string, binary as base64.
|
||||||
Args:
|
|
||||||
filename: Path to file (e.g., "/notes/project.md", "/documents/report.pdf")
|
|
||||||
Path should start with "/" and use forward slashes
|
|
||||||
|
|
||||||
Returns: Raw bytes content (decode as UTF-8 for text files)
|
|
||||||
Raises FileNotFoundError if file doesn't exist.
|
|
||||||
"""
|
"""
|
||||||
path = settings.FILE_STORAGE_DIR / filename.lstrip("/")
|
path = settings.FILE_STORAGE_DIR / filename.lstrip("/")
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
raise FileNotFoundError(f"File not found: {filename}")
|
raise FileNotFoundError(f"File not found: {filename}")
|
||||||
|
|
||||||
return path.read_bytes()
|
mime_type, _ = mimetypes.guess_type(str(path))
|
||||||
|
mime_type = mime_type or "application/octet-stream"
|
||||||
|
|
||||||
|
text_extensions = {
|
||||||
|
".md",
|
||||||
|
".txt",
|
||||||
|
".py",
|
||||||
|
".js",
|
||||||
|
".html",
|
||||||
|
".css",
|
||||||
|
".json",
|
||||||
|
".xml",
|
||||||
|
".yaml",
|
||||||
|
".yml",
|
||||||
|
".toml",
|
||||||
|
".ini",
|
||||||
|
".cfg",
|
||||||
|
".conf",
|
||||||
|
}
|
||||||
|
text_mimes = {
|
||||||
|
"application/json",
|
||||||
|
"application/xml",
|
||||||
|
"application/javascript",
|
||||||
|
"application/x-yaml",
|
||||||
|
"application/yaml",
|
||||||
|
}
|
||||||
|
is_text = (
|
||||||
|
mime_type.startswith("text/")
|
||||||
|
or mime_type in text_mimes
|
||||||
|
or path.suffix.lower() in text_extensions
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
content = (
|
||||||
|
path.read_text(encoding="utf-8")
|
||||||
|
if is_text
|
||||||
|
else __import__("base64").b64encode(path.read_bytes()).decode("ascii")
|
||||||
|
)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
import base64
|
||||||
|
|
||||||
|
content = base64.b64encode(path.read_bytes()).decode("ascii")
|
||||||
|
is_text = False
|
||||||
|
mime_type = (
|
||||||
|
"application/octet-stream" if mime_type.startswith("text/") else mime_type
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"content": content,
|
||||||
|
"mime_type": mime_type,
|
||||||
|
"is_text": is_text,
|
||||||
|
"file_size": path.stat().st_size,
|
||||||
|
"filename": filename,
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user