Give the write path a CLI and an MCP face
remember / supersede / forget now reach the one Python writer from a terminal, from MCP, and from HTTP. The server, not the caller, decides who owns a memory. - cli: remember, supersede, forget. --holder falls back to settings.default_holder until the holder registry lands. Timestamps are parsed once with one clear message. - ingestion: import pymupdf as fitz. The deprecated fitz import printed a warning to stdout, so every CLI command's JSON answer was unparseable. - mcp: remember, supersede_memory and forget_memory forward to the Python writer over HTTP (ELY_EYE_API, default http://127.0.0.1:8765). SQLite stays read-only to the Go side, so the write rules live in one place. - mcp reads follow schema v2: atoms.time became ingested_at, and reads go through v_atoms_current, so a superseded memory stops being findable. holder, origin, scenario and event_time now show up in fetch_atom and search_atoms. - scripts/mcp_write_smoke.sh proves the loop end to end: remember, search, supersede, forget, then not found. Evidence: 92 pytest passed; go build, go vet and go test clean; mypy clean on the 10 touched source files with a fresh cache; ruff clean except a pre-existing B008 at cli.py:292, identical at HEAD.
This commit is contained in:
1 parent
181f6bf57e
commit
3d792417cf
20 files changed
+1425
-33
No files matched your search
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ZacharyZhang-NY/ely-eye/ely-eye-mcp/internal/apiclient"
|
||||
"github.com/ZacharyZhang-NY/ely-eye/ely-eye-mcp/internal/config"
|
||||
"github.com/ZacharyZhang-NY/ely-eye/ely-eye-mcp/internal/store"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
type Server struct {
|
||||
cfg config.Config
|
||||
store *store.Store
|
||||
api *apiclient.Client
|
||||
version string
|
||||
}
|
||||
|
||||
@@ -25,15 +27,16 @@ func Run(ctx context.Context, cfg config.Config, version string) error {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
server := &Server{cfg: cfg, store: db, version: version}
|
||||
server := &Server{cfg: cfg, store: db, api: apiclient.New(cfg.APIBaseURL), version: version}
|
||||
mcpServer := mcp.NewServer(&mcp.Implementation{
|
||||
Name: "ely-eye",
|
||||
Title: "Ely-Eye Context Cartridge MCP",
|
||||
Version: version,
|
||||
}, &mcp.ServerOptions{
|
||||
Instructions: "Use Ely-Eye tools to retrieve local cartridge context, evidence atoms, proof suites, and compiled evidence packs. Tools read local Ely-Eye state and do not mutate the production database.",
|
||||
Instructions: "Use Ely-Eye tools to retrieve local cartridge context, evidence atoms, proof suites, and compiled evidence packs. Read tools mirror local Ely-Eye state without writing. remember, supersede_memory and forget_memory mutate memory through the Ely-Eye API, which must be running (`ely-eye serve`); the server, not the caller, decides who owns a memory.",
|
||||
})
|
||||
server.registerTools(mcpServer)
|
||||
server.registerWriteTools(mcpServer)
|
||||
server.registerResources(mcpServer)
|
||||
if err := mcpServer.Run(ctx, &mcp.StdioTransport{}); err != nil {
|
||||
if errors.Is(err, io.EOF) || strings.HasSuffix(err.Error(), "EOF") {
|
||||
|
||||
Reference in new issue
Block a user