ReMe/reme/config/default.yaml
jinliyl 3d2ecc60d2
feat(service): expose MCP through HTTP backend (#498)
* feat(service): expose MCP through HTTP backend

Serve JSON/SSE job endpoints and streamable HTTP MCP from one FastAPI application, sharing the same jobs and application lifecycle. Preserve the standalone MCP backend, add configurable MCP HTTP settings, update startup metadata and integration docs, and cover routing, lifecycle, configuration, and compatibility behavior with unit tests.

* fix(service): preserve MCP request protections

Route the exact MCP path through the complete FastMCP ASGI application so its middleware and state remain active. Reject non-literal MCP paths and validate reserved Job conflicts before tolerant service registration. Add regression coverage for middleware preservation, route syntax, and startup failure.

* fix(service): reject encoded MCP paths

Reject percent signs in mcp_path so ASGI path decoding cannot turn an accepted configuration into an unreachable route. Cover encoded slash, space, and double-encoded slash inputs.
2026-08-27 17:23:11 +08:00

840 lines
22 KiB
YAML

service:
backend: http
web_enabled: true
mcp_enabled: true
mcp_path: /mcp
jobs:
index_update_loop:
backend: background
watch_dirs: [daily_dir, digest_dir]
watch_suffixes: [md]
steps:
- backend: init_changes_step
monitor_type: file_store
monitor_name: default
dispatch_steps: [update_index_step]
- backend: watch_changes_step
dispatch_steps:
- backend: update_index_step
persist: False
resource_watch_loop:
backend: background
watch_dirs: [resource_dir]
watch_suffixes: [md, txt, json, jsonl, csv, yaml, html]
steps:
- backend: init_changes_step
monitor_type: file_catalog
monitor_name: resource
dispatch_steps:
- backend: update_catalog_step
file_catalog: resource
- backend: auto_resource_step
- backend: watch_changes_step
dispatch_steps:
- backend: update_catalog_step
file_catalog: resource
- backend: auto_resource_step
digest_watch_loop:
backend: background
watch_dirs: [daily_dir, digest_dir]
watch_suffixes: [md]
steps:
- backend: init_changes_step
monitor_type: file_catalog
monitor_name: digest
dispatch_steps:
- backend: update_catalog_step
file_catalog: digest
- backend: log_changes_step
- backend: watch_changes_step
dispatch_steps:
- backend: update_catalog_step
file_catalog: digest
- backend: log_changes_step
dream_cron:
backend: cron
cron: "0 23 * * *"
steps:
- backend: dream_extract_step
file_catalog: dream
topic_session_id: interests
scan_days: 2
max_units: 5
- backend: dream_integrate_step
- backend: dream_topics_step
topic_count: 3
topic_diversity_days: 7
- backend: dream_finish_step
file_catalog: dream
optimize_index_cron:
backend: cron
cron: "0 2 * * *"
steps:
- backend: optimize_index_step
auto_dream:
backend: base
description: "Auto-dream: scan today's day-index and daily notes, globally extract merged units/topics, integrate digest units, write interests.yaml, and persist the dream catalog."
parameters:
type: object
properties:
date:
type: string
description: "YYYY-MM-DD to scan; defaults to today in the dreamer's timezone"
default: ""
hint:
type: string
description: "caller guidance passed through to dream extract/integrate"
default: ""
scan_days:
type: integer
description: "number of recent daily directories to scan, ending at date"
default: 2
max_units:
type: integer
description: "maximum number of extracted memory units"
default: 5
topic_count:
type: integer
description: "maximum number of final daily interest topics"
default: 3
topic_diversity_days:
type: integer
description: "number of previous interests.yaml days to avoid repeating"
default: 7
steps:
- backend: dream_extract_step
file_catalog: dream
topic_session_id: interests
scan_days: 2
max_units: 5
- backend: dream_integrate_step
- backend: dream_topics_step
topic_count: 3
topic_diversity_days: 7
- backend: dream_finish_step
file_catalog: dream
auto_memory:
backend: base
description: "Auto-memory: record conversation facts into a daily note"
parameters:
type: object
properties:
messages:
type: array
description: "messages"
items:
type: object
session_id:
type: string
description: "source conversation session identifier"
default: ""
memory_hint:
type: string
description: "optional hint"
date:
type: string
description: "YYYY-MM-DD daily note date; empty = infer from message timestamps or today"
default: ""
required:
- messages
steps:
- backend: auto_memory_step
auto_memory_cc:
backend: base
description: "Auto-memory (Claude Code): record a Claude Code session into a daily note, resolved from its session_id"
parameters:
type: object
properties:
session_id:
type: string
description: "Claude Code session id; its transcript is resolved from disk"
memory_hint:
type: string
description: "optional hint"
required:
- session_id
steps:
- backend: auto_memory_cc_step
auto_resource:
backend: base
description: "Auto-resource: interpret resource files into daily notes"
parameters:
type: object
properties:
changes:
type: array
description: "resource change batch, each item has path/file_path and change"
items:
type: object
properties:
path:
type: string
file_path:
type: string
change:
type: string
description: "added/modified/deleted"
required:
- changes
steps:
- backend: auto_resource_step
proactive:
backend: base
description: "Proactive: read daily/<date>/interests.yaml and expose the latest user-interest topics."
parameters:
type: object
properties:
date:
type: string
description: "YYYY-MM-DD to read; defaults to today in the dreamer's timezone"
default: ""
include_content:
type: boolean
description: "whether to include the raw YAML content in the response answer and metadata"
default: true
steps:
- backend: proactive_step
version:
backend: base
description: "return reme package version"
parameters:
type: object
properties: { }
steps:
- backend: version_step
app_config:
backend: base
description: "return the effective application config with secrets redacted"
parameters:
type: object
properties: { }
steps:
- backend: app_config_step
chat:
backend: stream
description: "Stream a read-only agent conversation over the ReMe workspace."
parameters:
type: object
properties:
query:
type: string
description: "user message"
session_id:
type: string
description: "agent session to resume"
system_prompt:
type: string
description: "optional system prompt override"
required:
- query
steps:
- backend: chat_step
agent_wrapper: default
health_check:
backend: base
description: "return a concise health-check snapshot of reme components"
parameters:
type: object
properties: { }
steps:
- backend: health_check_step
status:
backend: base
description: "report memory estimates for stateful data components and process RSS"
parameters:
type: object
properties: { }
steps:
- backend: status_step
help:
backend: base
description: "list all registered jobs with their metadata"
parameters:
type: object
properties: { }
steps:
- backend: help_step
# shell:
# backend: base
# description: "execute a shell command asynchronously in the workspace"
# parameters:
# type: object
# properties:
# cmd:
# type: string
# description: "shell command to execute"
# shell_timeout:
# type: number
# description: "maximum execution time in seconds"
# default: 86400
# required:
# - cmd
# steps:
# - backend: shell_step
traverse:
backend: base
description: >-
Return a bounded wikilink graph with frontend-ready nodes and directed edges.
parameters:
type: object
properties:
path:
oneOf:
- type: string
- type: array
items:
type: string
minItems: 1
description: "workspace-relative path or paths used as graph seeds"
depth:
type: integer
minimum: 0
description: "maximum number of wikilink hops"
default: 1
direction:
type: string
description: >-
traversal direction; returned edges always preserve the original
wikilink source-to-target direction
enum:
- forward
- backward
- both
default: both
required:
- path
steps:
- backend: traverse_step
graph_snapshot:
backend: base
description: "Return the category-rooted digest wikilink graph with daily-note leaves."
parameters:
type: object
properties: { }
steps:
- backend: graph_snapshot_step
reindex:
backend: base
description: "wipe the file store and rebuild it from the existing files"
watch_dirs: [daily_dir, digest_dir, resource_dir]
watch_suffixes: [md, jsonl]
parameters:
type: object
properties: { }
steps:
- backend: clear_store_step
- backend: init_changes_step
monitor_type: file_store
monitor_name: default
dispatch_steps: [update_index_step]
search:
backend: base
description: "Hybrid workspace search (vector + BM25, RRF-fused)."
parameters:
type: object
properties:
query:
type: string
description: "search query"
limit:
type: integer
description: "max results"
default: 5
min_score:
type: number
description: "min fused score"
default: 0.0
start_date:
type: string
description: "optional inclusive start date filter (YYYY-MM-DD); results earlier than this date are excluded"
end_date:
type: string
description: "optional inclusive end date filter (YYYY-MM-DD); results later than this date are excluded"
required:
- query
steps:
- backend: search_step
vector_weight: 0.7
candidate_multiplier: 5.0
expand_links: true
max_links_per_direction: 10
node_search:
backend: base
description: "Digest node recall — given a candidate abstraction's name+description, surface existing digest nodes similar enough to either dedup against or link to as related."
parameters:
type: object
properties:
query:
type: string
description: "search query"
limit:
type: integer
description: "max digest nodes to return"
default: 20
required:
- query
steps:
- backend: node_search_step
vector_weight: 0.7
candidate_multiplier: 5.0
daily_list:
backend: base
description: "List notes under a single day."
parameters:
type: object
properties:
date:
type: string
description: "YYYY-MM-DD; empty = today"
default: ""
steps:
- backend: daily_list_step
daily_reindex:
backend: base
description: "Rebuild the day-index page daily/<date>.md."
parameters:
type: object
properties:
date:
type: string
description: "YYYY-MM-DD; empty = today"
default: ""
steps:
- backend: daily_reindex_step
frontmatter_delete:
backend: base
description: "Drop keys from a file's frontmatter."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
keys:
type: array
description: "keys to remove"
items:
type: string
required:
- path
- keys
steps:
- backend: frontmatter_delete_step
frontmatter_read:
backend: base
description: "Read a file's frontmatter as a dict."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
required:
- path
steps:
- backend: frontmatter_read_step
frontmatter_update:
backend: base
description: "Merge key-values into a file's frontmatter."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
metadata:
type: object
description: "key-values to merge"
required:
- path
- metadata
steps:
- backend: frontmatter_update_step
stat:
backend: base
description: "Stat path (size, mtime, exists, is_dir, is_file)."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
required:
- path
steps:
- backend: stat_step
list:
backend: base
description: "List files under a workspace path."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative dir; empty = root"
default: ""
recursive:
type: boolean
description: "recurse"
default: false
sort_by:
type: string
enum:
- mtime
description: "optional ordering; mtime returns most recently modified files first"
extensions:
type: array
items:
type: string
description: "optional extension allowlist applied before sorting and limiting"
limit:
type: integer
description: "max results"
default: 100
steps:
- backend: list_step
move:
backend: base
description: "Move / rename a workspace file; rewrites inbound wikilinks by default."
parameters:
type: object
properties:
src_path:
type: string
description: "workspace-relative source"
dst_path:
type: string
description: "workspace-relative destination"
overwrite:
type: boolean
description: "overwrite if dst exists"
default: false
retarget:
type: boolean
description: "rewrite [[src]] → [[dst]] across the workspace"
default: true
required:
- src_path
- dst_path
steps:
- backend: move_step
delete:
backend: base
description: "Delete a workspace file or folder; returns surviving inbound wikilinks."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
required:
- path
steps:
- backend: delete_step
read:
backend: base
description: "Read a markdown file under the workspace."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path; markdown only"
start_line:
type: integer
description: "first line (1-based, inclusive)"
end_line:
type: integer
description: "last line (1-based, inclusive)"
required:
- path
steps:
- backend: read_step
with_neighbors: false
max_neighbors_per_direction: 10
load:
backend: base
description: "Load a complete text file for the local editor without agent-output truncation."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
required:
- path
steps:
- backend: load_step
max_bytes: 5242880
read_image:
backend: base
description: "Read an image file as base64 (workspace-relative path)."
parameters:
type: object
properties:
path:
type: string
description: >-
workspace-relative path; common image formats supported
(png/jpg/jpeg/webp/gif/bmp/tiff/heic)
required:
- path
steps:
- backend: read_image_step
max_bytes: 5242880
write:
backend: base
description: "Write a markdown file (create or overwrite) with name/description frontmatter."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path; markdown only"
name:
type: string
description: "frontmatter name"
description:
type: string
description: "frontmatter description"
content:
type: string
description: "body"
metadata:
type: object
description: "Optional extra frontmatter fields (md only)."
required:
- path
- name
- description
- content
steps:
- backend: write_step
save:
backend: base
description: "Save text verbatim, optionally rejecting external changes since the file was opened."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
content:
type: string
description: "complete file content, including frontmatter"
expected_mtime:
type: string
description: "optional ISO mtime returned by stat"
required:
- path
- content
steps:
- backend: save_step
daily_write:
backend: base
description: "Write a daily markdown note with conversation source frontmatter."
parameters:
type: object
properties:
name:
type: string
description: "daily note filename stem and frontmatter name"
description:
type: string
description: "frontmatter description"
session_id:
type: string
description: "source conversation session identifier"
content:
type: string
description: "body"
date:
type: string
description: "YYYY-MM-DD daily note date; empty = today"
default: ""
metadata:
type: object
description: "Optional extra frontmatter fields."
required:
- name
- description
- session_id
- content
steps:
- backend: daily_write_step
edit:
backend: base
description: "Find-and-replace in a markdown file (all occurrences)."
parameters:
type: object
properties:
path:
type: string
description: "workspace-relative path"
old:
type: string
description: "text to find"
new:
type: string
description: "replacement"
default: ""
required:
- path
- old
- new
steps:
- backend: edit_step
components:
tokenizer:
default:
backend: regex
# as_embedding:
# default:
# backend: ${EMBEDDING_BACKEND:-openai}
# model: ${EMBEDDING_MODEL_NAME:-text-embedding-v4}
# dimensions: 1024
# credential:
# api_key: ${EMBEDDING_API_KEY:-}
# base_url: ${EMBEDDING_BASE_URL:-https://dashscope.aliyuncs.com/compatible-mode/v1}
# parameters: { }
#
# embedding_store:
# default:
# backend: local
# as_embedding: default
as_llm:
default:
backend: ${LLM_BACKEND:-openai}
model: ${LLM_MODEL_NAME:-qwen3.7-plus}
stream: true
context_size: 200000
max_retries: 3
credential:
api_key: ${LLM_API_KEY:-}
base_url: ${LLM_BASE_URL:-}
parameters:
max_tokens: 65536
thinking_enable: false
agent_wrapper:
default:
backend: agentscope
as_llm: default
permission_mode: bypass
react_config:
max_iters: 30
context_config:
trigger_ratio: 0.8
reserve_ratio: 0.1
tool_result_limit: 50000
model_config:
max_retries: 1
claude_code:
backend: claude_code
model: ${CLAUDE_CODE_MODEL_NAME:-glm-5.1}
api_key: ${CLAUDE_CODE_API_KEY:-}
base_url: ${CLAUDE_CODE_BASE_URL:-https://dashscope.aliyuncs.com/apps/anthropic}
permission_mode: bypassPermissions
codex:
backend: codex
auth_mode: api_key
model: ${CODEX_MODEL_NAME:-}
api_key: ${CODEX_API_KEY:-}
base_url: ${CODEX_BASE_URL:-}
approval_mode: auto_review
sandbox: full-access
codex_oauth:
backend: codex
auth_mode: oauth
model: ${CODEX_MODEL_NAME:-}
codex_home: ${CODEX_HOME:-~/.codex}
approval_mode: auto_review
sandbox: full-access
file_graph:
default:
backend: local
file_catalog:
default:
backend: local
resource:
backend: local
digest:
backend: local
dream:
backend: local
file_chunker:
markdown:
backend: markdown
supported_extensions: [ "md" ]
embed_toc: true
max_ast_sections: 100
include_frontmatter_in_metadata: false
include_frontmatter_keys_in_metadata: [] # empty = all non-empty frontmatter keys
json:
backend: json
supported_extensions: [ "json" ]
jsonl:
backend: jsonl
supported_extensions: [ "jsonl" ] # noqa: keep #314 chunker scope intact after #325
default:
backend: default
supported_extensions: ["txt","log"]
keyword_index:
default:
backend: bm25
tokenizer: default
file_store:
default:
backend: local
# backend: faiss
store_name: local
# embedding_store: default
embedding_store: ""
keyword_index: default
file_graph: default