작성자: 최진호 수정일: 2026-06-16
MCP 도구 상세는 SKILL.md 참조.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /mcp | Streamable HTTP. JSON-RPC 요청 수신. MCP-Session-Id 헤더 필요 (초기 initialize 제외) |
| GET | /mcp | Streamable HTTP. SSE 스트림 열기. 서버 측 푸시용 |
| DELETE | /mcp | Streamable HTTP. 세션 명시적 종료 |
| GET | /sse | Legacy SSE. 세션 생성. accessKey 쿼리 파라미터로 인증 |
| POST | /message?sessionId= | Legacy SSE. JSON-RPC 요청 수신. 응답은 SSE 스트림으로 전달 |
| GET | /health | 헬스 체크. DB 쿼리(SELECT 1), 세션 상태, Redis 연결을 확인하고 JSON으로 반환. REDIS_ENABLED=false 시 Redis는 disabled로 표시되며 200 반환. DB 장애 시 503 |
| GET | /metrics | Prometheus 메트릭. prom-client가 수집한 HTTP 요청 카운터, 세션 게이지 등 |
| GET | /openapi.json | OpenAPI 3.1.0 스펙. 인증 필수. master key는 Admin REST API 포함 전체 경로를 반환하며, API key는 해당 키의 permissions 배열에 맞게 도구 목록이 필터된 스펙을 반환. ENABLE_OPENAPI=true 환경변수로 활성화. 비활성 시 404 반환. |
| GET | /.well-known/oauth-authorization-server | OAuth 2.0 인가 서버 메타데이터 |
| GET | /.well-known/oauth-protected-resource | OAuth 2.0 보호 리소스 메타데이터 |
| GET | /authorize | OAuth 2.0 인가 엔드포인트. PKCE code_challenge 필요 |
| POST | /token | OAuth 2.0 토큰 엔드포인트. authorization_code 교환 |
| GET | /v1/internal/model/nothing | Admin SPA. app shell HTML 제공(인증 불필요). 데이터 API는 마스터 키 인증 필요 |
| GET | /v1/internal/model/nothing/assets/* | Admin 정적 파일 (admin.css, admin.js). 인증 불필요 |
| POST | /v1/internal/model/nothing/auth | 마스터 키 검증 엔드포인트 |
| GET | /v1/internal/model/nothing/stats | 대시보드 통계 (파편 수, API 호출량, 시스템 메트릭, searchMetrics, observability, queues, healthFlags) |
| GET | /v1/internal/model/nothing/activity | 최근 파편 활동 로그 (10건) |
| GET | /v1/internal/model/nothing/keys | API 키 목록 조회 |
| POST | /v1/internal/model/nothing/keys | API 키 생성. 원시 키는 응답에서 단 1회 반환 |
| PUT | /v1/internal/model/nothing/keys/:id | API 키 상태 변경 (active ↔ inactive) |
| PUT | /v1/internal/model/nothing/keys/:id/daily-limit | API 키 일일 호출 제한 변경. 마스터 키 인증 필요 |
| PATCH | /v1/internal/model/nothing/keys/:id/workspace | API 키의 default_workspace 변경. { workspace: "name" } 또는 { workspace: null } (null=해제) |
| DELETE | /v1/internal/model/nothing/keys/:id | API 키 삭제 |
| GET | /v1/internal/model/nothing/groups | 키 그룹 목록 |
| POST | /v1/internal/model/nothing/groups | 키 그룹 생성 |
| DELETE | /v1/internal/model/nothing/groups/:id | 키 그룹 삭제 |
| GET | /v1/internal/model/nothing/groups/:id/members | 그룹 멤버 목록 |
| POST | /v1/internal/model/nothing/groups/:id/members | 키를 그룹에 추가 |
| DELETE | /v1/internal/model/nothing/groups/:gid/members/:kid | 그룹에서 키 제거 |
| GET | /v1/internal/model/nothing/memory/overview | 메모리 전체 현황 (유형/토픽 분포, 품질 미검증, superseded, 최근 활동) |
| GET | /v1/internal/model/nothing/memory/search-events?days=N | 검색 이벤트 분석 (총 검색 수, 실패 쿼리, 피드백 통계) |
| GET | /v1/internal/model/nothing/memory/fragments | 파편 검색/필터링 (topic, type, key_id, workspace, page, limit) |
| GET | /v1/internal/model/nothing/memory/anomalies | 이상 탐지 결과 |
| GET | /v1/internal/model/nothing/sessions | 세션 목록 (활동 enrichment, 미반영 세션 수) |
| GET | /v1/internal/model/nothing/sessions/:id | 세션 상세 (검색 이벤트, 도구 피드백) |
| POST | /v1/internal/model/nothing/sessions/:id/reflect | 수동 reflect 실행 |
| DELETE | /v1/internal/model/nothing/sessions/:id | 세션 종료 |
| POST | /v1/internal/model/nothing/sessions/cleanup | 만료 세션 정리 |
| POST | /v1/internal/model/nothing/sessions/reflect-all | 미반영 세션 일괄 reflect |
| GET | /v1/internal/model/nothing/logs/files | 로그 파일 목록 (크기 포함) |
| GET | /v1/internal/model/nothing/logs/read | 로그 내용 조회 (file, tail, level, search 파라미터) |
| GET | /v1/internal/model/nothing/logs/stats | 로그 통계 (레벨별 카운트, 최근 에러, 디스크 사용량) |
| GET | /v1/internal/model/nothing/memory/graph?topic=&limit= | 지식 그래프 데이터 (nodes + edges) |
| GET | /v1/internal/model/nothing/export?key_id=&topic= | 파편 JSON Lines 스트림 내보내기 |
| POST | /v1/internal/model/nothing/import | 파편 JSON 배열 가져오기 |
| 의존성 | 분류 | down 시 응답 |
|---|---|---|
| PostgreSQL | 필수 | 503 (degraded) |
| Redis | 선택 | 200 (healthy, warnings 포함) |
Redis가 비활성화(REDIS_ENABLED=false)되거나 연결 실패해도 서버는 healthy(200)를 반환합니다.
L1 캐시와 Working Memory가 비활성화되지만 핵심 기억 저장/검색은 PostgreSQL만으로 동작합니다.
인증 방식은 두 가지다. Streamable HTTP는 initialize 요청 시 Authorization: Bearer <MEMENTO_ACCESS_KEY> 헤더로 인증하며 이후 세션으로 유지된다. Legacy SSE는 /sse?accessKey=<MEMENTO_ACCESS_KEY> 쿼리 파라미터로 인증한다.
할당량(fragment_limit)이 설정된 API 키로 MCP 도구를 호출할 때 아래 헤더가 응답에 포함된다.
| 헤더 | 설명 |
|---|---|
X-RateLimit-Limit |
키에 설정된 파편 총 허용 수 |
X-RateLimit-Remaining |
현재 남은 파편 수 |
X-RateLimit-Resource |
측정 대상 리소스 식별자 (fragments) |
master key (keyId=null) 또는 limit=null인 키는 헤더를 생략한다. 사용량 캐시 TTL은 10초이다.
클라이언트 소비 예시 (curl):
HTTP/1.1 200 OK
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4880
X-RateLimit-Resource: fragments
모든 MCP 도구 호출은 RBAC 검증을 통과해야 한다.
- master key (
MEMENTO_ACCESS_KEY):permissions=null로 처리되며 모든 도구를 호출할 수 있다. - API key (
mmcp_xxx): 키 생성 시 지정된permissions배열 기준으로 도구 접근이 제한된다. 배열에 필요한 권한이 없으면 즉시 거부된다. TOOL_PERMISSIONS맵에 등록된 도구는 해당 권한 레벨이 요구된다. 맵에 등록되지 않은 도구명은required=null로 간주되어 권한 검사를 통과한다. 도구를 RBAC 경계에 편입하려면TOOL_PERMISSIONS맵에 명시적으로 등록해야 한다.- 권한 레벨은 세 가지다:
read(recall/context/memory_stats 등),write(remember/forget/amend 등),admin(memory_consolidate/apply_update 등).admin권한을 가진 키는 모든 레벨을 호출할 수 있다. - 권한이 없는 도구를 호출하면 JSON-RPC 오류
-32600이 반환되며message는Internal error다. 거부 사유(Permission denied: '<도구>' requires '<레벨>' permission)는 서버 로그에만 남는다. 따라서 클라이언트는 응답만으로 권한 부족과 서버 오류를 구분할 수 없으므로, 재시도 정책을 세울 때 이 점을 감안해야 한다.memory_consolidate와apply_update,check_update가 이 경로에 해당한다. - 타 테넌트(다른 API 키)가 소유한 파편에 forget/amend/link 요청 시
"Fragment not found"에러가 반환된다. SQL 레벨에서key_id조건으로 격리되므로 존재 여부조차 노출되지 않는다.
보호된 리소스에 인증 없이 접근하면 401 Unauthorized와 함께 WWW-Authenticate: Bearer resource_metadata="</.well-known/oauth-protected-resource URL>" 헤더가 반환된다.
X-Memento-Mode 헤더 또는 initialize 요청의 params.mode로 세션 동작 모드를 지정할 수 있다. admin console에서 api_keys.default_mode를 설정하면 키 단위 기본값을 고정할 수 있다.
| Preset | 설명 | 허용 도구 |
|---|---|---|
recall-only |
읽기 전용 세션. 기억 저장·수정 도구 차단. 검색 전용 에이전트에 사용. | recall, context, memory_stats, graph_explore, fragment_history, reconstruct_history, search_traces, get_skill_guide, tool_feedback |
write-only |
저장 전용 세션. recall, context 차단. 데이터 수집 파이프라인에 사용. | remember, batch_remember, forget, amend, link, reflect |
onboarding |
사용자 안내 세션. get_skill_guide를 첫 도구로 강제 노출. | 전체 (get_skill_guide 우선 안내) |
audit |
읽기·추적 전용 세션. 쓰기 도구 전체 차단. 감사·컴플라이언스 목적. | recall, context, memory_stats, graph_explore, fragment_history, reconstruct_history, search_traces |
HTTP 헤더로 설정:
X-Memento-Mode: recall-only
initialize 파라미터로 설정:
{
"method": "initialize",
"params": {
"mode": "recall-only",
"protocolVersion": "2025-06-18"
}
}토큰 기반 세션 재사용이 활성화되어 있다. 클라이언트가 Mcp-Session-Id 없이 재연결하더라도 동일 Bearer 토큰이면 서버가 기존 세션을 자동으로 복구한다. 클라이언트 측에는 투명하게 동작하며 별도 설정이 필요하지 않다.
세션 세그먼트가 활성화된 경우(MEMENTO_SESSION_SEGMENT, 기본 true), 파편의 session_id는 전송계층 Mcp-Session-Id가 아니라 유휴·수명 기준으로 회전하는 파생 ID {전송세션ID}#{seq} 형식일 수 있다. 회전이 발생하면 직전 세그먼트가 자동 reflect된다.
세션 ID 탈취 의심 시 진행 중 상태를 유지한 채 세션 식별자만 재발급한다. Redis에 저장된 세션 데이터는 그대로 보존되고 ID만 교체되므로 기억 파편과 MCP 연결 상태에 영향 없다.
요청:
POST /session/rotate HTTP/1.1
Authorization: Bearer <API key or master key>
Mcp-Session-Id: <대상 sessionId>
Origin: https://example.com
Content-Type: application/json
{ "reason": "suspected_leak" }응답 (200):
{
"ok": true,
"oldSessionId": "aabbcc11-...-8899ddee",
"newSessionId": "ffeedd22-...-3344ccbb",
"reason": "suspected_leak",
"rotatedAt": "2026-04-21T12:34:56.789Z"
}정책:
- 인증:
Authorization: Bearer필수. 대상 세션 소유권이 일치하지 않으면 403 - CSRF 방어:
Origin헤더 필수. 누락 또는 허용 목록 외 Origin이면 403 - Rate limit: IP당 분당
MEMENTO_ROTATE_RATE_LIMIT_PER_MIN회 (기본 5). 초과 시 429 reason필드는 감사 로그용으로 최대 128자. 지정하지 않으면explicit_rotate- 메트릭:
mcp_session_rotation_total{reason}카운터 +mcp_rotate_rate_limited_total카운터 - CLI:
memento-mcp session rotate <sessionId>서브명령으로 동일 기능 호출. 자세한 사용법은docs/cli.md참조
각 도구의 tools/list 응답 항목은 meta 필드를 포함한다.
{
"name": "recall",
"description": "...",
"inputSchema": { ... },
"meta": {
"capabilities": ["search", "pagination", "caseMode"],
"riskLevel": "read",
"requiresMaster": false,
"beta": false,
"idempotent": true
}
}| 필드 | 타입 | 설명 |
|---|---|---|
capabilities |
string[] | 도구가 지원하는 기능 태그 목록 |
riskLevel |
string | 도구의 위험 등급. read / write / admin |
requiresMaster |
boolean | master key(MEMENTO_ACCESS_KEY)만 호출 가능 여부 |
beta |
boolean | 실험적 기능 여부. true 시 인터페이스가 변경될 수 있음 |
idempotent |
boolean | 동일 파라미터로 반복 호출해도 부작용이 없는지 여부 |
RFC 7591 Dynamic Client Registration 및 PKCE 기반 Authorization Code Flow를 지원한다.
서버 메타데이터 응답에 registration_endpoint가 포함된다.
{
"issuer": "https://{domain}",
"authorization_endpoint": "https://{domain}/authorize",
"token_endpoint": "https://{domain}/token",
"registration_endpoint": "https://{domain}/register",
"response_types_supported": ["code"],
"grant_types_supported": ["authorization_code"],
"code_challenge_methods_supported": ["S256"]
}RFC 7591 동적 클라이언트 등록. 인증 불필요.
요청 본문:
{
"client_name": "Claude",
"redirect_uris": ["https://claude.ai/api/mcp/auth_callback"]
}응답 201:
{
"client_id": "mmcp_...",
"client_name": "Claude",
"redirect_uris": ["https://claude.ai/api/mcp/auth_callback"],
"grant_types": ["authorization_code"],
"token_endpoint_auth_method": "none"
}API 키 바인딩:
Authorization: Bearer <API 키>헤더를 함께 전송하면client_id = "<name>_<keyIdHex8>"형식의 URL-safe 이름으로 자동 등록된다. 이후/authorize에서 해당 API 키의 tenant 격리 컨텍스트가 자동 복원된다. 헤더 없이 등록하면 랜덤client_id방식으로 fallback된다.
OAuth 2.0 인가 엔드포인트. PKCE code_challenge 및 code_challenge_method=S256 필수.
쿼리 파라미터: response_type=code, client_id, redirect_uri, code_challenge, code_challenge_method, state(선택).
사용자 동의 화면을 렌더링하며, 동의 후 redirect_uri로 code를 포함한 302 리다이렉트를 반환한다.
동의 화면에서 사용자가 허용 또는 거부를 선택할 때 폼 데이터로 제출된다.
| 필드 | 값 |
|---|---|
decision |
allow 또는 deny |
response_type |
원본 OAuth 파라미터 |
client_id |
원본 OAuth 파라미터 |
redirect_uri |
원본 OAuth 파라미터 |
code_challenge |
원본 OAuth 파라미터 |
code_challenge_method |
원본 OAuth 파라미터 |
state |
원본 OAuth 파라미터 (존재 시) |
decision=allow:redirect_uri?code=<code>&state=<state>로 302 리다이렉트decision=deny:redirect_uri?error=access_denied로 302 리다이렉트
API 키의 일일 호출 제한을 변경한다. 마스터 키 인증 필요.
요청 본문:
{ "daily_limit": 50000 }응답:
{ "success": true, "daily_limit": 50000 }미리 정의된 가이드라인으로 AI가 기억 시스템을 효율적으로 사용하도록 돕는다.
| 이름 | 설명 | 주요 역할 |
|---|---|---|
analyze-session |
세션 활동 분석 | 현재 대화에서 저장할 가치가 있는 결정, 에러, 절차를 자동으로 추출하도록 유도 |
retrieve-relevant-memory |
관련 기억 검색 가이드 | 특정 주제에 대해 키워드와 시맨틱 검색을 병행하여 최적의 컨텍스트를 찾도록 보조 |
onboarding |
시스템 사용법 안내 | AI가 AnchorMind의 도구들을 언제 어떻게 써야 하는지 스스로 학습 |
기억 시스템의 현재 상태를 실시간으로 조회할 수 있는 MCP 리소스.
| URI | 설명 | 데이터 소스 |
|---|---|---|
memory://stats |
시스템 통계 | fragments 테이블의 유형별, 계층별 카운트 및 유용성 점수 평균 |
memory://topics |
주제 목록 | fragments 테이블의 모든 고유한 topic 레이블 목록 |
memory://config |
시스템 설정 | MEMORY_CONFIG에 정의된 가중치 및 TTL 임계값 |
memory://active-session |
세션 활동 로그 | SessionActivityTracker(Redis)에 기록된 현재 세션의 도구 사용 이력 |
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| keywords | string[] | - | 키워드 검색 (L1→L2). text 미지정 시 keywords(+contextText) 합성 텍스트로 L3 시맨틱 보조 검색이 병렬 수행되어 저장 keywords에 없는 용어도 content 기반 회수된다 (semanticSearch.keywordFallback으로 제어, searchPath에 L3kw:N 세그먼트). |
| text | string | - | 자연어 쿼리 (L3 시맨틱) |
| topic | string | - | 주제 필터 |
| type | string | - | 타입 필터 (fact, decision, error, preference, procedure, relation, episode) |
| tokenBudget | number | - | 최대 반환 토큰. 기본 1000. |
| includeLinks | boolean | - | 연결된 파편 포함 (1-hop, resolved_by/caused_by 우선). 기본 true. |
| linkRelationType | string | - | 연결 파편 관계 유형 필터 (related, caused_by, resolved_by, part_of, contradicts) |
| threshold | number | - | similarity 임계값 (0~1) |
| includeSuperseded | boolean | - | 만료(superseded) 파편 포함. 기본 false. |
| includePeerAgents | boolean | - | true 시 같은 키/workspace 스코프 내 다른 agentId 파편 포함(멀티에이전트 협업용). 키·workspace 경계는 유지. 기본 false. |
| includeKeyName | boolean | - | true 시 각 파편에 key_id와 key_name(액세스 키 라벨)을 포함한다. 같은 키 그룹 스코프의 정보만 노출된다. 기본 false. |
| asOf | string | - | ISO 8601. 특정 시점 기준 유효 파편만. |
| excludeSeen | boolean | - | context()에서 이미 주입된 파편 제외. 기본 true. |
| includeKeywords | boolean | - | 각 파편의 keywords 배열을 응답에 포함 |
| includeContext | boolean | - | context_summary + 인접 파편(nearby_context) 포함. 조합할 재료가 있는 상위 3건에는 stitched_context도 함께 반환 |
| timeRange | object | - | {from, to} 시간 범위 필터 (ISO 8601 또는 자연어) |
| caseId | string | - | 케이스 ID 필터. 해당 케이스 파편만 반환. |
| resolutionStatus | string | - | 해결 상태 필터 (open / resolved / abandoned) |
| phase | string | - | 작업 단계 필터 (planning, debugging, verification 등) |
| caseMode | boolean | - | CBR 모드. 유사 파편을 case_id별로 그루핑하여 (goal, events, outcome) 트리플로 반환. 과거 유사 작업 해결 사례 참조 시 사용. |
| maxCases | number | - | caseMode에서 반환할 최대 케이스 수. 기본 5, 상한 10. |
| depth | string | - | 검색 깊이 필터. "high-level" / "detail" / "tool-level". 상세 설명은 아래 참조. |
| workspace | string | - | 검색 범위 제한. 지정 시 해당 workspace + 전역(NULL) 파편만 반환. |
| contextText | string | - | 현재 대화 맥락 텍스트. 관련 파편을 선제적으로 활성화 (ENABLE_SPREADING_ACTIVATION=true 시). |
| cursor | string | - | 페이지네이션 커서 |
| pageSize | number | - | 기본 20, 최대 50 |
| agentId | string | - | 에이전트 ID |
| minImportance | number | - | 최소 중요도 필터 (0~1). 이 값 이상의 importance를 가진 파편만 반환. |
| isAnchor | boolean | - | true 시 앵커(고정) 파편만 반환. 핵심 지식 조회에 유용. |
| affect | string | string[] | - | 정서 태그 필터. 단일 문자열 또는 배열. 해당 affect 값을 가진 파편만 반환. 유효값: neutral, frustration, confidence, surprise, doubt, satisfaction |
| fields | string[] | - | 응답에 포함할 파편 필드 목록. 미지정 시 전체 필드 반환. 지원 키: id / content / type / topic / keywords / importance / created_at / access_count / confidence / linked / explanations / workspace / context_summary / case_id / valid_to / affect / ema_activation |
각 반환 파편에는 key_id 필드가 포함된다. master key 호출 시 타 API 키 소유 파편도 반환될 수 있으며, 이 경우 key_id 값으로 소유 키를 식별할 수 있다. API key 호출 시에는 자신이 소유한 파편(key_id 일치) 또는 그룹 공유 파편만 반환된다.
affect 필드: 해당 파편에 태그된 정서 상태. 저장 시 지정한 값과 동일하게 반환된다.
stitched_context 필드: includeContext=true일 때 전후 시간 맥락과 인과 링크를 하나의 서사 구조로 묶어 반환한다. 조합할 재료가 실제로 있는 상위 3건에만 실리며, 응답 토큰 예산의 40%를 넘으면 전후 각 1건으로 축약된다.
{
"stitched_context": {
"target": { "id": "frag-abc", "created_at": "2026-08-25T14:02:00.000Z" },
"pre": [{ "id": "frag-pre", "content": "...", "type": "error", "created_at": "...", "delta_min": -4 }],
"post": [{ "id": "frag-post", "content": "...", "type": "procedure", "created_at": "...", "delta_min": 8 }],
"causal": [{ "id": "frag-cause", "relation_type": "resolved_by", "direction": "out", "content": "..." }]
}
}pre/post: 같은session_id에서 기준 파편 전후 30분 이내에 저장된 파편.delta_min은 기준 시각 대비 분 단위 차이이며 이전 시각은 음수다.causal:caused_by/resolved_by/contradicts/part_of링크. 자동 생성되는related/co_retrieved/temporal은 포함하지 않는다. 링크 방향과 무관하게 상대 파편을 반환하며direction으로 방향을 구분한다.
_meta: recall/context 응답 최상위의 메타데이터 래퍼.
searchEventId: 검색 이벤트 식별자. 후속tool_feedback호출 시 FK로 사용.hints: 검색 결과 신호 배열(no_results,topic_mismatch,contradiction_pending,stale_results,active_errors등).topic_mismatch는 지정한 topic으로 0건이면서 키 스코프 내에 유사 topic이 존재할 때 발화하며 제안된 topic으로의 재검색을 권고한다.contradiction_pending은 반환 파편에 미해결 contradicts 링크가 있을 때 발화하며 amend 정리를 권고한다.suggestion: 사용 패턴 기반 도구 제안.serverTime: 응답 생성 시점의 서버 시각. LLM 클라이언트의 학습 시점 시간 고착을 방지하기 위해 모든 recall/context 응답에 일관되게 포함된다.iso(UTC ISO 8601),epoch_ms(Unix ms),display_kst(Asia/Seoul 한국어 표기),timezone4필드 구성.
쓰기 도구(remember/amend/forget)의 성공 응답에도 _meta 블록이 실릴 수 있다. 이 경우 hints에는 feedback_sampled 신호 1건과 serverTime만 포함되며, searchEventId·suggestion은 없다. 상세는 피드백 샘플링 힌트를 참조한다.
{
"_meta": {
"searchEventId": 1234,
"hints": [
{
"signal" : "no_results",
"suggestion": "이 주제에 대한 기억이 없습니다. 중요한 내용이라면 remember로 저장하세요.",
"trigger" : "remember"
}
],
"suggestion": { "code": "empty_result_no_context", "recommendedTool": "recall" },
"serverTime": {
"iso" : "2026-05-15T06:32:11.000Z",
"epoch_ms" : 1747291931000,
"display_kst": "2026년 5월 15일 (목) 15:32",
"timezone" : "Asia/Seoul"
}
}
}| 필드 | 설명 |
|---|---|
_meta.searchEventId |
tool_feedback 호출 시 search_event_id 파라미터로 전달할 FK 값. commitSearchSideEffects가 영속화한 검색 이벤트 ID. |
_meta.hints |
시스템이 제안하는 검색 개선 힌트 배열 |
_meta.suggestion |
RecallSuggestionEngine 생성 힌트 객체 (감지된 문제 없으면 null) |
_meta.suggestion: RecallSuggestionEngine이 현재 검색 패턴을 분석하여 생성한 힌트 객체. 감지된 문제가 없으면 null이다.
{
"_suggestion": {
"code": "empty_result_no_context",
"message": "결과가 없습니다. contextText 파라미터로 현재 맥락을 전달하면 SpreadingActivation이 관련 파편을 선제 활성화합니다.",
"recommendedTool": "recall",
"recommendedArgs": { "contextText": "현재 작업 맥락 요약" }
}
}_suggestion 감지 규칙:
| code | 트리거 조건 | 권유 |
|---|---|---|
repeat_query |
keywords 쿼리가 5분 이내 3회 이상 반복 (query_type이 keywords 또는 mixed인 search_events 기준) | 케이스 타임라인 조회 — reconstruct_history(상위 case_id 존재 시) 또는 graph_explore |
empty_result_no_context |
결과 0건이고 contextText가 없는 경우 | contextText 추가 |
large_limit_no_budget |
limit 파라미터가 50 이상이고 tokenBudget 미지정인 경우. recall 스키마의 페이지 크기 파라미터는 pageSize이므로 현재 이 규칙은 발화하지 않는다 |
tokenBudget 명시로 응답 크기 제어 |
no_type_filter_noisy |
type 필터 없이 호출했고 해당 키 스코프의 총 파편 수가 100건을 초과하는 경우 (이번 호출의 반환 건수·depth는 판정에 쓰이지 않는다) | type 필터 추가 |
규칙은 위 순서대로 평가되어 최초 1건만 _meta.suggestion에 실린다. 조건에 해당하지 않으면 필드는 생략된다.
explanation (MEMENTO_SYMBOLIC_EXPLAIN=true 시에만 포함): 해당 파편이 검색 결과에 포함된 이유를 최대 3개 reason code로 설명한다.
{
"fragment": {
"id": "...",
"explanations": [
{ "code": "direct_keyword_match", "detail": "L2 형태소/키워드 매치", "ruleVersion": "v1" },
{ "code": "graph_neighbor_1hop", "detail": "그래프 이웃 1-hop", "ruleVersion": "v1" }
]
}
}reason code 목록 (최대 3개):
direct_keyword_match— L2 형태소/키워드 매칭으로 결과에 포함됨semantic_similarity— L3 pgvector 임베딩 유사도로 결과에 포함됨graph_neighbor_1hop— L2.5 그래프 이웃 1-hop으로 결과에 포함됨temporal_proximity— timeRange 필터 또는 ±24h 시간 인접성으로 결과에 포함됨case_cohort_member— caseMode 경로에서 동일 case_id 코호트로 결과에 포함됨recent_activity_ema— ema_activation 상위로 가점 부여되어 결과에 포함됨
| 값 | 대상 유형 | 용도 |
|---|---|---|
"high-level" |
decision, episode만 | Planner용. 전략 수립·방향 결정 시. |
"detail" |
전체 (기본값) | 일반 검색. 타입 제한 없음. |
"tool-level" |
procedure, error, fact만 | Executor용. 구체적 실행 단계·설정값 조회 시. |
caseMode=true 시 일반 fragments 외에 cases 배열이 추가로 반환된다.
{
"caseMode": true,
"cases": [{
"case_id": "abc-123",
"goal": "nginx 502 해결",
"outcome": "upstream 포트 불일치 수정",
"resolution_status": "resolved",
"events": [
{"event_type": "error_observed", "summary": "502 Bad Gateway"},
{"event_type": "fix_attempted", "summary": "nginx.conf 수정"},
{"event_type": "verification_passed", "summary": "200 OK 확인"}
],
"fragment_count": 5,
"relevance_score": 3
}],
"caseCount": 1
}| 값 | 설명 |
|---|---|
milestone_reached |
주요 마일스톤 달성 |
hypothesis_proposed |
가설 제안 |
hypothesis_rejected |
가설 기각 |
decision_committed |
의사결정 확정 |
error_observed |
에러 관측 |
fix_attempted |
수정 시도 |
verification_passed |
검증 통과 |
verification_failed |
검증 실패 |
파편 기반 기억 저장. 반드시 1~2문장 단위의 원자적 사실 하나만 저장한다. 내용이 많으면 여러 번 호출하여 각각 저장할 것.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| content | string | O | 기억할 내용 (1~3문장, 300자 이내 권장). 입력 자체는 최대 4000자까지 허용되며 초과 시 -32602 오류로 거부된다 |
| topic | string | O | 주제 (예: database, email, deployment, security) |
| type | string | O | 파편 유형. fact, decision, error, preference, procedure, relation, episode. episode 외 타입은 300자 초과 시 절삭. |
| keywords | string[] | - | 검색용 키워드. 지정해도 본문에서 추출한 키워드가 뒤에 병합되며(중복 제거, 최대 10개) 지정 키워드가 우선한다. 미입력 시 본문 추출만 사용 |
| importance | number | - | 중요도 0~1 (미입력 시 type별 기본값) |
| source | string | - | 출처 (세션 ID, 도구명 등) |
| linkedTo | string[] | - | 연결할 기존 파편 ID 목록 |
| scope | string | - | 저장 범위. permanent=장기 기억(기본), session=세션 워킹 메모리(세션 종료 시 소멸) |
| isAnchor | boolean | - | 중요 파편 고정 여부. true 시 중요도 감쇠(decay) 및 만료 삭제 대상에서 제외됨. |
| supersedes | string[] | - | 대체할 기존 파편 ID 목록. 지정된 파편은 valid_to가 설정되고 importance가 반감된다. |
| contextSummary | string | - | 이 기억이 생긴 맥락/배경 요약 (1-2문장). recall 시 함께 반환되어 전후관계를 복원한다. |
| sessionId | string | - | 현재 세션 ID. 같은 세션 파편을 시간 인접 번들로 묶는 데 사용. |
| workspace | string | - | 워크스페이스 이름. 미지정 시 키의 default_workspace 적용. |
| agentId | string | - | 에이전트 ID (RLS 격리용) |
| caseId | string | - | 이 파편이 속한 작업/케이스 식별자. 미설정 시 현재 session_id로 자동 설정. |
| goal | string | - | 에피소드 파편의 목표 (episode 타입 권장) |
| outcome | string | - | 에피소드 파편의 결과 |
| phase | string | - | 작업 단계 (예: planning, debugging, verification) |
| resolutionStatus | string | - | 작업 해결 상태 (open, resolved, abandoned) |
| assertionStatus | string | - | 파편의 신뢰도 수준 (observed, inferred, verified, rejected). 기본값: observed |
| affect | string | - | 기억 당시의 정서 상태 태그. 기본값: neutral. 유효값: neutral, frustration, confidence, surprise, doubt, satisfaction |
| idempotencyKey | string | - | 재시도 안전 식별자 (최대 128자). 같은 key_id 범위에서 동일 값으로 remember를 반복 호출하면 새 파편을 생성하지 않고 기존 파편 id를 반환한다. 클라이언트 재시도·네트워크 중복 방지 목적. |
| dryRun | boolean | - | true 설정 시 변경을 실제 적용하지 않고 실행 계획만 반환. 할당량·충돌 검사 결과를 파편 생성 없이 미리 확인할 수 있다. |
affect 사용 예:
{
"content": "Redis 연결 실패 원인이 REDIS_SENTINEL_ENABLED 미설정임을 확인했다.",
"topic": "redis",
"type": "error",
"affect": "frustration"
}dryRun=true 응답 (실제 저장 없음):
{
"dryRun": true,
"simulated": {
"fragment": { "content": "...", "type": "fact", "topic": "..." },
"conflicts": [],
"validation_warnings": [],
"quota": { "used": 120, "limit": 5000, "remaining": 4880 }
}
}violations 없는 경우 (정상 저장):
{
"success": true,
"id": "frag-...",
"keywords": ["..."],
"ttl_tier": "warm",
"scope": "permanent",
"conflicts": []
}violations 있는 경우 (soft gate — 저장됨):
{
"success": true,
"id": "frag-...",
"keywords": ["..."],
"ttl_tier": "warm",
"scope": "permanent",
"conflicts": [],
"validation_warnings": ["decisionHasRationale"]
}validation_warnings: PolicyRules soft gating violations rule 이름 string[]. violations 없으면 필드 자체 생략. MEMENTO_SYMBOLIC_POLICY_RULES=false (기본값) 시 항상 생략. atomic 경로(MEMENTO_REMEMBER_ATOMIC=true)와 non-atomic 경로 모두 동일한 _runPolicyGate 호출 경로를 거치므로 포맷이 동일하다. 활성화 시 다음 5가지 predicate 중 실패한 것이 누적된다:
decisionHasRationale— decision 타입이 linked_to 2건 이상 또는 근거 키워드 미포함errorHasResolutionPath— error 타입이 cause/fix 키워드 또는 resolution_status 미포함procedureHasStepMarkers— procedure 타입에 번호/단계 마커 부재caseIdHasResolutionStatus— case_id 보유 파편이 resolution_status 미설정assertionNotContradictory— 기존 assertion과 polarity 충돌fragmentHasWorkspace— workspace가 명시값·키 default 어느 쪽으로도 해석되지 않음 (severity: low)
경고는 soft gate이므로 저장을 차단하지 않는다. api_keys.symbolic_hard_gate=true 설정 시 경고 발생 파편은 저장 거부된다. 이 경우 아래 에러 코드가 반환된다. fragmentHasWorkspace는 MEMENTO_WORKSPACE_GATE=true일 때만 hard gate 대상에 포함되며, 기본값(false)에서는 hard gate 활성 키에서도 저장을 차단하지 않는다.
workspaceNotAllowed — 파편의 workspace가 API 키의 allowed_workspaces 허가 집합 밖일 때 기록되는 경고(severity: medium). MEMENTO_SYMBOLIC_POLICY_RULES 설정과 무관하게 항상 평가되며, 저장을 거부하지 않는 순수 경고로 hard gate 대상에서 항상 제외된다.
파편에는 workspace 해석 출처가 workspace_source로 함께 기록된다: explicit(요청에 workspace 명시) · key_default(API 키의 default_workspace 적용) · unscoped(둘 다 없어 미지정).
remember·amend·forget의 성공 응답에는 일정 확률로 tool_feedback 요청 힌트가 동봉된다. 표집되지 않으면 응답 형태는 이전과 동일하며 _meta 자체가 붙지 않는다.
{
"success": true,
"id": "frag-...",
"_meta": {
"hints": [
{
"signal": "feedback_sampled",
"suggestion": "방금 remember 결과가 의도한 대로 유용했는지 tool_feedback으로 평가해 주세요. relevant=false인 경우 irrelevance_reason도 함께 보내면 원인별 개선에 반영됩니다.",
"trigger": "tool_feedback",
"args": { "tool_name": "remember", "trigger_type": "sampled" }
}
],
"serverTime": { "iso": "..." }
}
}힌트를 받은 클라이언트는 hints[0].args를 그대로 tool_feedback 인자로 사용해 평가를 보내는 것이 권장된다(trigger_type="sampled"). 무관 판정 시에는 irrelevance_reason을 함께 보낸다.
표집 규칙은 config/memory.js의 feedback.sampling을 따른다. 도구별 확률은 remember 0.10, amend 0.25, forget 0.25이며, 세션당 최대 2건·직전 힌트 이후 900초 쿨다운이 적용된다(Redis 미가용 시 상한과 쿨다운은 적용되지 않는다). MEMENTO_FEEDBACK_SAMPLING=false로 전체 비활성화할 수 있다. remember(dryRun=true)·dryRun=true 호출(remember·forget)과 실제 갱신이 없었던 amend(updated=false)는 표집 대상에서 제외된다. recall은 자체 힌트 경로를 이미 갖고 있어 표집 대상이 아니다.
-32003(SYMBOLIC_POLICY_VIOLATION): Symbolic hard gate가 활성화된 키에서 PolicyRules violations 발생. 저장이 거부됨. MCP 도구 에러(isError: true)가 아닌 JSON-RPC 프로토콜 레벨 에러다.-32602(Invalid params):content길이가 4000자를 초과. JSON-RPC 프로토콜 레벨 에러다.
{
"jsonrpc": "2.0",
"id": 5,
"error": {
"code": -32003,
"message": "policy_violation: decisionHasRationale",
"data": {
"violations": ["decisionHasRationale"],
"fragmentType": "decision"
}
}
}여러 파편을 한번에 저장 (대량 기억 입력용). 단일 트랜잭션으로 최대 200건을 일괄 INSERT하여 HTTP 라운드트립을 최소화한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fragments | object[] | O | 저장할 파편 배열 (최대 200건). 각 항목은 content(string, 필수, 최대 4000자, 초과 시 해당 항목 -32602 거부), topic(string, 필수), type(string, 필수), importance(number), keywords(string[]), workspace(string), idempotencyKey(string, 최대 128자) 포함. |
| workspace | string | - | 배치 기본 워크스페이스. 개별 파편에 workspace 미지정 시 이 값으로 대체. 미지정 시 키의 default_workspace 적용. |
| agentId | string | - | 에이전트 ID (RLS 격리용) |
| stream | boolean | - | deprecated: 더 이상 SSE progress 이벤트를 보내지 않는다. batch_remember는 표준 단일 JSON 응답으로 반환된다. 이 파라미터는 하위 호환성을 위해 유지되지만 동작에 영향을 주지 않는다. |
| async | boolean | - | true 시 파이어앤포겟(비동기) 모드 (기본 false). 스키마 유효성·content_hash 중복·할당량 선검증만 동기 수행한 뒤 통과 파편을 Redis 큐에 적재하고 즉시 {async: true, accepted: N, rejected: N, jobId: "..."} 를 반환한다. 본 INSERT는 백그라운드 워커(BatchRememberWorker)가 처리한다. Redis 비활성(REDIS_ENABLED=false) 환경에서는 async=true여도 동기 모드로 폴백한다. |
{
"async": true,
"accepted": 5,
"rejected": 1,
"jobId": "batch-1750000000000-a1b2c3d4"
}동기 모드(기본)에서는 results[] 배열이 반환된다. jobId는 batch_status 도구로 처리 상태를 조회할 수 있다. 비동기 워커는 ack·재시도(최대 3회)·dead-letter·기동 복구(RPOPLPUSH reliable queue)로 at-least-once 처리를 보장한다.
각 파편은 INSERT 전 아래 조건을 검사한다. 실패한 파편은 results[i].success = false로 기록되며 배열의 나머지 파편 저장에는 영향을 주지 않는다.
| 에러 메시지 | 원인 |
|---|---|
content is required |
content 필드가 null 또는 undefined |
content length N exceeds max 4000 |
content 필드가 4000자 초과 |
type is required |
type 필드 누락 |
Content too short: length < 10 and word count < 3 |
FragmentFactory.validateContent 판정 실패 — 내용이 너무 짧음 |
fragment_limit_exceeded |
API 키 파편 할당량 초과 |
batch_remember(async: true)가 반환한 jobId의 처리 상태를 조회한다. 읽기 전용. Redis 비활성 시 status: null을 반환한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| jobId | string | O | batch_remember(async: true) 응답의 jobId |
| 필드 | 타입 | 설명 |
|---|---|---|
| jobId | string | 조회한 jobId |
| state | string | queued | processing | completed | dead |
| accepted | number | 큐에 적재된 파편 수 |
| processed | number | 처리 완료 파편 수 |
| failed | number | 처리 실패 파편 수 |
{
"jobId": "batch-1750000000000-a1b2c3d4",
"state": "completed",
"accepted": 5,
"processed": 5,
"failed": 0
}파편 기억 삭제. id 또는 topic 중 하나는 필수. permanent 계층 파편은 force 옵션이 필요.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | string | - | 삭제할 파편 ID |
| topic | string | - | 해당 주제의 파편 전체 삭제 |
| force | boolean | - | permanent 파편도 강제 삭제 (기본 false) |
| agentId | string | - | 에이전트 ID |
| dryRun | boolean | - | true 설정 시 실제 삭제 없이 삭제 대상 파편 정보와 연결 링크 수를 반환. |
호출 결과는 세 가지로 갈린다.
| 상황 | 응답 | isError |
|---|---|---|
| 삭제 성공 | {success: true, deleted: 1} |
false |
| permanent 계층 파편에 force 미지정 | {success: true, deleted: 0, protected: 1, reason: "permanent 파편은 force 옵션 필요"} |
false |
| 대상이 없거나 접근 권한 없음 | {success: true, deleted: 0, error: "Fragment not found or no permission"} |
true |
세 번째 경우는 페이로드의 success가 true인데 error 키가 함께 실리고, 그 키 때문에 MCP 봉투가 isError: true로 뒤집힌다. 이미 삭제된 대상을 재시도로 다시 지우면 이 응답을 받으므로, 클라이언트는 삭제 실패로 오인하지 않도록 deleted 값을 함께 봐야 한다.
두 파편 사이에 관계를 설정한다. 인과, 해결, 구성, 모순 관계를 명시.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| fromId | string | O | 시작 파편 ID |
| toId | string | O | 대상 파편 ID |
| relationType | string | - | 관계 유형 (related, caused_by, resolved_by, part_of, contradicts). 기본 related. |
| agentId | string | - | 에이전트 ID |
| weight | number | - | 관계 가중치 (0-1, 기본 1) |
| dryRun | boolean | - | true 설정 시 실제 링크 생성 없이 사이클 여부·소유권 검사 결과만 반환. |
기존 파편의 내용이나 메타데이터를 갱신한다. ID와 링크를 보존하면서 선택적으로 수정.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | string | O | 갱신 대상 파편 ID |
| content | string | - | 새 내용 (300자 초과 시 절삭). 입력 자체는 최대 4000자까지 허용되며 초과 시 -32602 오류로 거부된다 |
| topic | string | - | 새 주제 |
| keywords | string[] | - | 새 키워드 목록 |
| type | string | - | 새 유형 (fact, decision, error, preference, procedure, relation) |
| importance | number | - | 새 중요도 (0~1) |
| isAnchor | boolean | - | 고정 파편 여부 설정 |
| supersedes | boolean | - | true 시 기존 파편을 명시적으로 대체 (superseded_by 링크 생성 및 중요도 하향) |
| assertionStatus | string | - | 파편의 확인 상태 변경 (observed, inferred, verified, rejected). case_id가 있는 파편은 변경 시 verification_passed/verification_failed 이벤트가 자동 기록된다. |
| resolutionStatus | string | - | 케이스 해결 상태 변경 (open, resolved, abandoned). case_id가 있는 파편은 resolved 전환 시 case_closed 이벤트가 자동 기록된다. |
| outcome | string | - | 케이스 종결 결과 요약. resolutionStatus='resolved'와 함께 기록한다. |
| phase | string | - | 작업 단계 변경 (planning, debugging, implementation, verification 등). |
| agentId | string | - | 에이전트 ID |
| dryRun | boolean | - | true 설정 시 실제 변경 없이 패치 적용 후의 예상 파편 상태를 반환. |
세션 종료 시 학습 내용을 원자 파편으로 영속화한다. 각 배열 항목이 독립 파편으로 저장되므로 항목 하나에 하나의 사실/결정/절차만 담을 것.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| summary | string | string[] | - | 세션 개요 파편 목록. 배열 권장. 항목 1개 = 사실 1건 (1~2문장). |
| sessionId | string | - | 세션 ID. 전달 시 같은 세션의 파편만 종합하여 reflect 수행. |
| decisions | string[] | - | 기술/아키텍처 결정 목록. 항목 1개 = 결정 1건. |
| errors_resolved | string[] | - | 해결된 에러 목록. '원인: X → 해결: Y' 형식 권장. |
| new_procedures | string[] | - | 확립된 절차/워크플로우 목록. 항목 1개 = 절차 1개. |
| open_questions | string[] | - | 미해결 질문 목록. 항목 1개 = 질문 1건. |
| narrative_summary | string | - | 세션 전체를 3~5문장의 서사(narrative)로 요약. episode 파편으로 저장되어 세션 간 맥락 연속성에 기여. 생략 시 summary에서 자동 생성. |
| agentId | string | - | 에이전트 ID |
| workspace | string | - | 생성되는 모든 reflect 파편에 적용할 워크스페이스. 미지정 시 각 그룹 자체의 workspace, 그것도 없으면 API 키의 default_workspace, 그것도 없으면 전역(NULL). 명시하면 세션 종합으로 도출된 그룹별 workspace보다 우선한다. 멀티 프로젝트 환경에서 세션 요약의 교차 주입 방지에 권장. |
| task_effectiveness | object | - | 세션 작업 결과와 도구 사용 효과성 평가. outcome, evaluator, evidence, unmet_requirements, overall_success, tool_highlights, tool_pain_points로 구성된다. 아래 표 참조. |
| 이름 | 타입 | 설명 |
|---|---|---|
| outcome | string | 작업 종료 상태. completed(요구사항 전부 충족), partial(일부만 충족), blocked(외부 요인으로 진행 불가), abandoned(중단), unknown(판정 불가). 확신이 없으면 추정하지 말고 unknown을 쓴다. 열거값 밖의 값은 저장 시 폐기되어 미보고(NULL)로 기록된다. |
| evaluator | string | outcome 판정 주체. agent(에이전트 자기보고), automatic(테스트·빌드 등 자동 판정), human(사용자 확인). outcome이 기록될 때만 함께 저장되며 생략 시 agent. |
| evidence | string | outcome 판정 근거. 1000자 초과분은 절삭된다. |
| unmet_requirements | string[] | 충족하지 못한 요구사항 목록. 최대 20건, 각 항목 200자로 절삭된다. partial/blocked/abandoned일 때 남은 작업을 명시한다. |
| overall_success | boolean | 호환 유지 필드. 명시하면 그 값이 그대로 저장되고, 생략하면 outcome이 completed일 때 true, 그 외에는 false로 파생된다. |
| tool_highlights | string[] | 유용했던 도구 목록 |
| tool_pain_points | string[] | 불편했던 도구 목록 |
task_effectiveness는 agent_memory.task_feedback 테이블에 기록되며 outcome·evaluator·evidence·unmet_requirements 컬럼은 migration-039에서 추가됐다. 집계 결과는 memory_stats의 evaluation 블록에 반영된다.
{
"count": 5,
"fragments": [
{ "id": "frag-...", "content": "...", "type": "fact", "keywords": ["..."] }
],
"breakdown": {
"summary": 2,
"decisions": 1,
"errors": 0,
"procedures": 1,
"questions": 1,
"episode": 1
},
"groups": [
{ "workspace": "memento-mcp", "topic": "session_reflect", "caseId": "debug-recall-2026-08-16", "fragmentIds": ["frag-...", "frag-..."] }
]
}breakdown 필드는 카테고리별 저장된 파편 수를 나타낸다. episode는 narrative_summary가 있을 때만 포함된다. 내부적으로 5개 카테고리는 단일 batchRememberProcessor 호출로 처리되지만 결과는 _category 메타를 기반으로 카테고리별 재집계되므로 breakdown shape이 보존된다.
sessionId가 지정되면 세션 파편을 workspace → case_id → topic 경계로 그룹핑해 그룹마다 별도로 종합·영속화한다. groups 필드는 그룹별 결과(workspace, topic, caseId, 해당 그룹에서 생성된 파편 id 목록 fragmentIds — narrative_summary가 있으면 episode 파편 id 포함)를 배열로 반환하며, 그룹이 서로 다른 workspace를 가져도 각 파편에는 소속 그룹의 workspace가 개별 기록된다. sessionId가 없으면 params(summary/decisions/...) 자체가 단일 그룹으로 취급되는 레거시 경로로 동작한다.
세션 종료 시 자동 실행되는 AutoReflect는 Gemini CLI 호출에 GEMINI_TIMEOUT_MS 환경변수로 설정된 타임아웃(기본값 30000ms)을 적용한다. 외부 게이트웨이(예: claude.ai MCP 프록시) 60s 컷오프 대비 30s 마진을 확보하기 위해 30s로 설정되어 있다. 40000ms 이상으로 변경하지 않는다.
| 환경변수 | 기본값 | 설명 |
|---|---|---|
GEMINI_TIMEOUT_MS |
30000 | AutoReflect의 Gemini CLI 호출 타임아웃 (ms). lib/memory/processors/AutoReflect.js 상수 GEMINI_TIMEOUT_MS로 export됨 |
Core Memory + Working Memory + session_reflect를 분리 로드한다. 세션 시작 시 preference, error, procedure, decision 파편을 주입하여 맥락 유지.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| tokenBudget | number | - | 최대 토큰 수 (기본 2000) |
| types | string[] | - | 로드할 유형 목록 (기본: preference, error, procedure) |
| sessionId | string | - | 세션 ID (Working Memory 로드용) |
| agentId | string | - | 에이전트 ID |
| workspace | string | - | 워크스페이스 필터. 지정 시 해당 workspace 파편 + 전역(NULL) 파편만 반환. 미지정 시 키의 default_workspace 적용. |
| structured | boolean | - | true 시 계층적 트리 구조 반환, false/미지정 시 기존 flat list (기본값: false) |
| includeKeyName | boolean | - | true 시 fragments 각 항목에 key_id와 key_name(액세스 키 라벨)을 포함한다. 같은 키 그룹 스코프의 정보만 노출되며, structured=true 트리 응답에는 적용되지 않는다. 기본 false. |
도구 사용 결과에 대한 유용성 피드백. 대상 도구의 결과가 관련성 있었는지, 충분했는지를 평가한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| tool_name | string | O | 평가 대상 도구명 |
| relevant | boolean | O | 결과가 요청 의도와 관련 있었는가 |
| sufficient | boolean | O | 결과가 작업 완료에 충분했는가 |
| suggestion | string | - | 개선 제안 (100자 이내) |
| context | string | - | 사용 맥락 요약 (50자 이내) |
| session_id | string | - | 세션 ID |
| trigger_type | string | - | 트리거 유형. sampled=훅 샘플링 또는 쓰기 도구의 feedback_sampled 힌트 응답, voluntary=AI 자발적 (기본 voluntary) |
| irrelevance_reason | string | - | 무관 판정 원인. not_stored(저장된 적 없음), search_miss(저장됐으나 미검색), scope_leak(타 스코프 유입), topic_mismatch(주제 불일치), other(그 외). relevant=false일 때만 의미를 가지며, 그 외의 호출이나 열거값 밖의 값은 폐기되어 NULL로 기록된다. 원인별 분포는 memory_stats의 irrelevance_breakdown으로 집계된다. |
| search_event_id | integer | - | 직전 recall이 반환한 _meta.searchEventId. 검색 품질 분석에 사용. |
| fragment_ids | string[] | - | 피드백 대상 파편 ID 목록. 제공 시 해당 파편의 활성화 점수가 피드백에 따라 조정된다. |
파편 기억 시스템 통계 조회. 전체 파편 수, TTL 분포, 유형별 통계를 반환한다.
파라미터 없음.
검색 품질과 downstream 작업 결과 지표를 함께 반환한다. DB 미가용이거나 표본이 없으면 비율 필드는 null이다.
| 필드 | 타입 | 설명 |
|---|---|---|
| rolling_precision_at_5 | number | null | 최근 100세션 기준 rolling Precision@5 |
| sufficient_rate | number | null | tool_feedback의 sufficient=true 비율 |
| sample_sessions | number | precision 산출에 사용된 세션 수 |
| task_success_rate | number | null | 최근 30일 overall_success=true 비율. 분모는 전체 task_feedback 행 |
| task_sessions | number | 최근 30일 task_feedback 행 수 |
| task_completed_rate | number | null | 최근 30일 outcome='completed' 비율. 분모는 outcome을 실제로 보고한 세션만이다(미보고를 실패로 계산하지 않는다) |
| task_outcome_reported | number | outcome을 보고한 세션 수 |
| task_outcome_counts | object | null | outcome 분포. completed·partial·blocked·abandoned·unknown·unreported(미보고) |
| irrelevance_breakdown | object | null | relevant=false 피드백의 원인 분포. total_irrelevant(무관 판정 총건), reported(원인이 기록된 건), counts(not_stored·search_miss·scope_leak·topic_mismatch·other·unreported) |
irrelevance_breakdown.counts에서 not_stored 우세는 저장 습관, search_miss 우세는 검색 리콜, scope_leak 우세는 스코프 격리 문제를 가리킨다.
workspace 기입 현황과 세션당 파편 분포를 반환한다.
| 필드 | 타입 | 설명 |
|---|---|---|
| distribution.top | array | 상위 workspace별 파편 수 {workspace, count} 목록 (내림차순) |
| distribution.null_count | number | workspace 미기입(NULL, 전역) 파편 수 |
| distribution.distinct_count | number | 값이 있는 workspace의 고유 개수 |
| key_fill_rate | array | API 키별 workspace 기입률 {key_id, key_name, total, with_workspace, fill_rate}. fill_rate는 with_workspace / total |
| session_fragment_distribution | object | 최근 30일 세션당 파편 수 분포 {p50, p90, max, sample_sessions}. 표본이 없으면 p50·p90·max는 null |
파편 기억 유지보수 실행. TTL 전환, 중요도 감쇠, 만료 삭제, 중복 병합을 수행한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| stream | boolean | - | deprecated. SSE progress 이벤트를 더 이상 보내지 않는다. 하위 호환을 위해 스키마에 남아 있으며 동작에 영향을 주지 않는다. |
admin 권한이 필요하다. 일반 API 키로 호출하면 위의 RBAC 절에 적은 대로 -32600 Internal error가 반환된다.
전체 사이클은 20개 이상의 stage로 구성되며 파편 규모에 비례해 시간이 걸린다. 약 1만 3천 파편 규모에서 전 사이클 소요는 7분 안팎이다. 스케줄러가 기본 6시간 주기로 같은 경로를 실행하므로, 수동 호출은 점검 목적일 때만 쓴다.
시맨틱 중복 제거 단계에는 안전 게이트가 걸려 있다. 제거 대상의 변별 토큰이 승계자에 남지 않으면 해당 병합을 차단한다. 상세는 configuration을 참조한다.
현재 세션을 종료하고 새 sessionId를 발급한다. 토큰 탈취 의심 시 또는 주기적 로테이션에 사용한다. 동일 bound_key_id / workspace / permissions가 새 세션으로 이관된다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| reason | string | - | 회전 사유 (감사 로그 기록, 최대 256자). 예: scheduled_rotation, suspected_leak, user_request |
에러 파편 기점으로 인과 관계 체인을 추적한다. RCA(Root Cause Analysis) 전용. caused_by, resolved_by 관계를 1-hop 추적하여 에러 원인과 해결 절차를 연결한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| startId | string | O | 시작 파편 ID (error 파편 권장) |
| agentId | string | - | 에이전트 ID |
파편의 전체 변경 이력 조회. amend로 수정된 이전 버전과 superseded_by 체인을 반환한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| id | string | O | 조회할 파편 ID |
| agentId | string | - | 에이전트 ID |
| includePeerAgents | boolean | - | true 시 같은 API 키 스코프 내 다른 agentId의 파편 이력도 조회한다. 테넌트(키) 경계는 완화되지 않는다. 기본 false. |
AnchorMind 최적 활용 가이드를 반환한다. 기억 도구 사용법, 세션 생명주기, 키워드 규칙, 검색 전략, 경험적 기억 활용법 등 포괄적 스킬 레퍼런스.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| section | string | - | 특정 섹션만 조회. 미지정 시 전체 가이드 반환. 가능한 값: overview, lifecycle, keywords, search, episode, multiplatform, codex, tools, importance, experiential, cbr, triggers, antipatterns |
case_id 또는 entity 기반으로 작업 히스토리를 시간순으로 재구성한다. 인과 체인과 미해결 브랜치를 포함하여 서사를 복원한다.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| caseId | string | - | 재구성할 케이스 식별자 |
| entity | string | - | entity_key 필터 (caseId 없을 때 사용) |
| timeRange | object | - | ISO 8601 시간 범위. from(시작 시각), to(종료 시각) 포함. |
| query | string | - | 추가 키워드 필터 |
| limit | number | - | 기본 100, 최대 500 |
| workspace | string | - | 워크스페이스 필터. 지정 시 해당 workspace + 전역(NULL) 파편만 대상. |
ordered_timeline: 시간순 파편 배열. 각 항목에 agent_id가 포함되어 멀티에이전트 케이스에서 기여 에이전트를 식별할 수 있다.causal_chains: 인과 체인 배열.unresolved_branches: 미해결 브랜치.
fragments를 정확 매칭으로 탐색한다 (recall의 시맨틱 검색과 달리 content/type/case_id 텍스트 매칭). event_type, entity, 키워드로 필터링하여 전체 히스토리를 grep하듯 조회.
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
| event_type | string | - | 필터할 fragment type (fact, error, decision 등) |
| eventType | string | - | event_type의 camelCase alias |
| entity_key | string | - | topic ILIKE 필터 |
| entityKey | string | - | entity_key의 camelCase alias |
| keyword | string | - | content 내 키워드 검색 |
| case_id | string | - | 케이스 ID 필터 |
| caseId | string | - | case_id의 camelCase alias |
| session_id | string | - | 세션 ID 필터 |
| sessionId | string | - | session_id의 camelCase alias |
| time_range | object | - | 시간 범위 필터. from(시작 시각, ISO 8601), to(종료 시각, ISO 8601) 포함. |
| limit | number | - | 기본 20, 최대 100 |
| workspace | string | - | 워크스페이스 필터. 지정 시 해당 workspace + 전역(NULL) 파편만 대상. |
id, content, importance만 반환받아 토큰 절감:
curl -X POST https://anchormind.example.com/mcp \
-H "Authorization: Bearer $MEMENTO_KEY" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{
"name":"recall",
"arguments":{
"keywords":["nginx","502"],
"fields":["id","content","importance","type"]
}
}
}'MCP JSON-RPC 동등 호출:
{ "method": "tools/call", "params": { "name": "recall", "arguments": { "keywords": ["nginx","502"], "fields": ["id","content","importance","type"] } } }네트워크 오류 후 동일 요청 재전송 시 중복 생성 없음:
curl -X POST https://anchormind.example.com/mcp \
-H "Authorization: Bearer $MEMENTO_KEY" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{
"name":"remember",
"arguments":{
"content":"nginx upstream 포트를 8080에서 15001로 변경하여 502 해결",
"topic":"nginx",
"type":"procedure",
"importance":0.8,
"idempotencyKey":"nginx-fix-2026-04-20-001"
}
}
}'동일 idempotencyKey로 재호출 시 응답:
{ "success": true, "id": "frag-abc123", "idempotent": true }curl -X POST https://anchormind.example.com/mcp \
-H "Authorization: Bearer $MEMENTO_KEY" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0","id":3,"method":"tools/call",
"params":{
"name":"remember",
"arguments":{
"content":"Redis Sentinel 연결 실패 — REDIS_SENTINEL_ENABLED 미설정",
"topic":"redis",
"type":"error",
"dryRun":true
}
}
}'응답:
{
"dryRun": true,
"simulated": {
"fragment": { "content": "Redis Sentinel 연결 실패 — REDIS_SENTINEL_ENABLED 미설정", "type": "error", "topic": "redis" },
"conflicts": [],
"validation_warnings": [],
"quota": { "used": 120, "limit": 5000, "remaining": 4880 }
}
}# 응답 헤더 확인
curl -si -X POST https://anchormind.example.com/mcp \
-H "Authorization: Bearer $API_KEY" \
... | grep X-RateLimit
# X-RateLimit-Limit: 5000
# X-RateLimit-Remaining: 4879
# X-RateLimit-Resource: fragments- 세션 시작 —
context()로 핵심 기억을 로드한다. 선호, 에러 패턴, 절차가 복원된다. 미반영 세션이 있으면 힌트가 표시된다. - 작업 중 — 중요한 결정, 에러, 절차 발생 시
remember()로 저장한다. 저장 시 유사 파편과 자동으로 링크가 생성된다. 과거 경험이 필요하면recall()로 검색한다. 에러 해결 후forget()으로 에러 파편을 정리하고remember()로 해결 절차를 기록한다. - 세션 종료 —
reflect()로 세션 내용을 구조화된 파편으로 영속화한다. 수동 호출 없이도 세션 종료/만료 시 AutoReflect가 자동으로 실행된다.
| 변수 | 기본값 | 영향 범위 |
|---|---|---|
MEMENTO_REMEMBER_ATOMIC |
false |
true 시 remember 경로가 _rememberAtomic으로 전환. SELECT api_keys FOR UPDATE + 단일 BEGIN/COMMIT 트랜잭션으로 quota 재검증과 INSERT를 원자적으로 처리. _runPolicyGate는 양 경로 모두 동일하게 실행되므로 validation_warnings 포맷에 차이 없음. |
MEMENTO_CASE_BACKPROP_ENABLED |
false |
true 시 case_id를 가진 파편의 amend(resolutionStatus 변경) 시점에 동일 caseId 파편들의 importance를 역전파 조정. lib/config.js의 CASE_BACKPROP_ENABLED 상수로 export. case 해결 완료 시 관련 파편의 활성화 점수가 상향되어 이후 recall 정밀도를 높인다. |
MEMENTO_STORAGE |
pgvector |
스토리지 어댑터 선택. pgvector(기본, 프로덕션용 PgVectorStore) 또는 sqlite-vec(SqliteVecStore). 어댑터 교체 시 transaction(fn) 인터페이스가 유지되므로 write 경로 동시성 시맨틱은 동일하게 보존됨. |
MEMENTO_SYMBOLIC_POLICY_RULES |
false |
true 시 _runPolicyGate가 PolicyRules soft gate를 평가하여 위반 rule 이름을 validation_warnings에 누적. |
MEMENTO_FEEDBACK_SAMPLING |
true |
remember·amend·forget 성공 응답에 feedback_sampled 힌트를 확률적으로 동봉. false 시 힌트를 전혀 붙이지 않으며 응답 형태는 이전과 동일하다. |
- 로컬 임베딩 설정 —
EMBEDDING_PROVIDER=transformers전환 절차 상세 - 통합/E2E 테스트 — 테스트 환경 구성 및 실행 방법
- 아키텍처 — 컴포넌트 의존성 및 검색 파이프라인
- 설정 레퍼런스 — 전체 환경변수 목록 및 MEMORY_CONFIG