65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
"""Minimal task-owned attachment server. Run through ARTEMIS, not as a shell tool."""
|
|
|
|
import hashlib
|
|
import os
|
|
from pathlib import Path
|
|
import time
|
|
import uuid
|
|
|
|
from mcp.server.fastmcp import FastMCP
|
|
from mcp.types import CallToolResult, TextContent, ToolAnnotations
|
|
|
|
mcp = FastMCP("evidence-demo")
|
|
|
|
|
|
@mcp.tool(
|
|
annotations=ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False)
|
|
)
|
|
def write_note(text: str) -> CallToolResult:
|
|
"""Save at most 16 KiB of user-requested text as a new task attachment."""
|
|
encoded = text.encode("utf-8")
|
|
root = os.environ.get("ARTEMIS_ARTIFACTS_DIR")
|
|
if not root or len(encoded) > 16384:
|
|
return CallToolResult(
|
|
isError=True,
|
|
content=[TextContent(type="text", text="任务目录缺失或内容超过 16 KiB;未写文件。")],
|
|
structuredContent={
|
|
"artemis": {
|
|
"version": 1,
|
|
"execution": "not_started",
|
|
"side_effect": "none",
|
|
"error_code": "invalid_input",
|
|
"retryable": False,
|
|
}
|
|
},
|
|
)
|
|
directory = Path(root)
|
|
directory.mkdir(parents=True, exist_ok=True)
|
|
name = f"note-{uuid.uuid4().hex}.txt"
|
|
path = directory / name
|
|
with path.open("xb") as handle:
|
|
handle.write(encoded)
|
|
digest = hashlib.sha256(path.read_bytes()).hexdigest()
|
|
return CallToolResult(
|
|
content=[TextContent(type="text", text=f"已保存并读回校验:{name}")],
|
|
structuredContent={
|
|
"artemis": {
|
|
"version": 1,
|
|
"execution": "completed",
|
|
"side_effect": "confirmed",
|
|
"retryable": False,
|
|
"source": {
|
|
"kind": "file",
|
|
"target_id": "task-artifacts",
|
|
"label": "任务文件",
|
|
"captured_at": time.time(),
|
|
},
|
|
"attachments": [{"name": name, "sha256": digest, "media_type": "text/plain"}],
|
|
}
|
|
},
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
mcp.run(transport="stdio")
|