Skip to main content

Interface Guide

EchOS supports four interfaces for interacting with your personal knowledge base. You can enable/disable each interface in your .env file.

Configuration

Edit .env to control which interfaces are active:
The Web UI is experimental. The CLI (pnpm echos) is stable and requires no daemon. Telegram is the recommended interface for daily use. The setup wizard (pnpm wizard) generates a WEB_API_KEY automatically when you enable the web interface.
Start the application:
The application will start all enabled interfaces simultaneously.

1. Telegram Bot Interface

Default: Enabled

Setup

  1. Create a bot with @BotFather on Telegram
  2. Get your bot token
  3. Get your Telegram user ID from @userinfobot
  4. Configure in .env:

Usage

  1. Start EchOS: pnpm start
  2. Open Telegram and message your bot
  3. Send natural language commands:
    • "Save this article: https://example.com/post"
    • "What notes do I have about TypeScript?"
    • "Create a note called 'Project Ideas'"
    • "Remind me to review the proposal tomorrow"

Commands

Steering (mid-run interruption)

If the agent is currently processing a task and you send a new text message, EchOS steers the agent rather than queuing a second turn:
  1. The agent finishes its current tool call
  2. Remaining tool calls in the turn are skipped
  3. The new message is injected and the agent responds to it
The agent replies “↩️ Redirecting…” immediately to acknowledge receipt. The final response (for the original turn, now steered) is updated in the original message thread. Use /followup instead when you want to chain work after the current task — e.g. “save this article” then /followup summarise the key points.

Exporting Notes

Ask the agent to export notes and it will send the file as a document attachment:
Supported formats: markdown, text, json, zip. All exports are sent as document attachments. Single-note markdown/text exports are delivered directly as small document files; multi-note exports or explicit zip/json format requests write a temporary file to data/exports/ before sending. The temporary file is deleted automatically after the bot sends it.

Inline Keyboards

Certain tool results include inline keyboard buttons for quick actions without typing:
  • Reading queue — “Mark Read” buttons per item, plus link buttons for items with URLs
  • List notes — “Mark Read” and “Archive” buttons for non-archived items
  • Reminders — “Complete” buttons for pending reminders
When you press a button, the action executes immediately (no AI round-trip) and the button is removed from the keyboard. These actions work the same as asking the agent to mark content as read, archive notes, or complete reminders.

Features

  • ✅ Streaming responses (live updates as AI thinks)
  • ✅ Multi-user support (each user has isolated sessions)
  • ✅ Rate limiting per user
  • ✅ Authentication via ALLOWED_USER_IDS
  • ✅ Voice message support (with Whisper transcription)
  • ✅ Photo/document support
  • ✅ Mid-run steering and follow-up queuing
  • ✅ File exports delivered as document attachments
  • ✅ Inline keyboards for quick actions on list results
  • ✅ Configurable emoji reactions (can be disabled)

Configuration

Security

Only users listed in ALLOWED_USER_IDS can interact with the bot. All requests are validated and sanitized.

2. Web API Interface

Default: Disabled — experimental

Setup

Configure in .env:
Generate a key:
Or run pnpm wizard — it generates and stores the key automatically.
If ENABLE_WEB=true and WEB_API_KEY is not set, the web server throws at startup and the process exits. There is no unauthenticated fallback.

Usage

Start EchOS and access the API at http://localhost:3000

Endpoints

Health Check

Response:
All API routes except /health require an Authorization header:
The userId in every request must be one of the values in ALLOWED_USER_IDS — requests with unknown user IDs are rejected with 403.

Send Chat Message

Response:

Steer Running Agent

Interrupt the agent mid-turn. Only valid while a /api/chat request is in flight for the same userId. Skips remaining tool calls and injects the new message.
Returns 409 if the agent is not currently running.

Switch Model Preset

Valid presets: fast | balanced | deep. Returns { ok: true, model: "<model-id>" }.

Queue Follow-up

Queue a message to run after the current agent turn completes. Safe to call at any time — the message is held until the agent is idle.

Reset Chat Session

Response:

Examples

Create a note:
Search knowledge:
Save an article:
Health check (no auth required):

Exporting Notes

Ask the agent to export notes. The agent’s response will include a download link:
The export file endpoint GET /api/export/:fileName requires Bearer auth and validates the filename against ^[\w-]+\.(zip|json|md|txt)$ to prevent path traversal. Files are automatically cleaned up after 1 hour by the scheduler. Example URL: /api/export/export-1234567890.zip.

Features

  • ✅ RESTful JSON API
  • ✅ Bearer token authentication (WEB_API_KEY)
  • userId validated against ALLOWED_USER_IDS
  • ✅ CORS restricted to localhost origins
  • ✅ Server binds to 127.0.0.1 (not externally reachable)
  • ✅ Session management per user
  • ✅ Tool execution tracking
  • ✅ Non-streaming responses (full response after completion)
  • ✅ Export file download via GET /api/export/:fileName

Integration

Build a frontend application that calls this API:

3. CLI / Terminal Interface

The CLI is a standalone binary that runs directly against your data — no daemon required. It auto-detects how it’s being used and switches modes accordingly.

Three Modes

One-shot — pass a query as an argument, get an answer, exit:
Pipe — pipe text in, get plain text out, exit:
Interactive REPL — no args, TTY detected, persistent session:

No Daemon Needed

pnpm echos boots its own agent in-process and connects directly to the same ./data/ directory the daemon uses. SQLite WAL mode makes concurrent access safe — run the CLI over SSH while the daemon is serving Telegram and Web without conflicts.

Interactive REPL Features

  • Persistent readline history at ~/.echos_history (survives between sessions, max 500 lines)
  • Streaming responses with tool call indicators dimmed in grey
  • Ctrl+C cancels the in-flight response and re-prompts (does not exit)
  • Ctrl+D or typing exit / quit exits cleanly

Example Session

Output

  • TTY: colored tool indicators, separator line after each response
  • Non-TTY (pipe/redirect): plain text only, no ANSI codes — safe to pipe into other tools

Logging

Startup logs are suppressed by default (log level warn). To see initialization details:

VPS / SSH Workflow

Exporting Notes

Use the --output / -o flag to save an exported file, or pipe single-note exports directly:
For inline (single-note markdown/text) exports, content is written to stdout or --output if specified. For file exports (zip/json), the file is moved to the --output path or saved to the current directory. The export destination path is printed to stderr so stdout remains clean for piping.

Features

  • ✅ Standalone — no daemon or Redis required
  • ✅ Three auto-detected modes (one-shot, pipe, interactive)
  • ✅ Streaming responses
  • ✅ Persistent readline history
  • ✅ Ctrl+C cancels mid-response without killing the process
  • ✅ Plain output in pipe mode (scriptable)
  • ✅ Safe concurrent access alongside running daemon (SQLite WAL)
  • --output / -o flag for saving exported files

Limitations

  • Single user session (no multi-user support)
  • No authentication (runs with local user permissions)
  • Text-only (no images, voice)

Choosing the Right Interface

Recommendations:
  • Primary use: Telegram (most features, best UX, stable)
  • Local automation/integration: Web API (requires WEB_API_KEY)
  • Terminal / SSH / scripting: CLI (pnpm echos)

Multiple Interfaces

You can run Telegram and Web simultaneously:
The CLI (pnpm echos) is always available independently — no .env flag needed, just run it. Note: Each interface maintains its own session state, so conversations don’t carry across interfaces.

Security Considerations

Telegram

  • ✅ Built-in authentication via ALLOWED_USER_IDS
  • ✅ Rate limiting per user
  • ✅ Input validation and sanitization
  • ⚠️ Only one instance can run per bot token

Web API

  • ✅ Bearer token auth via WEB_API_KEY (set in .env)
  • userId validated against ALLOWED_USER_IDS on every request
  • ✅ Binds to 127.0.0.1 — not reachable from the network
  • ✅ CORS restricted to localhost / 127.0.0.1 origins
  • ⚠️ Experimental — not recommended as the primary interface
  • ⚠️ If WEB_API_KEY is missing, the server refuses to start (exits with an error)

CLI (pnpm echos)

  • ⚠️ No authentication — runs with local user permissions
  • ✅ No network exposure (stdin/stdout only)
  • ✅ Safe for local/SSH use

Quick Start Examples

Test Web API

Use the CLI

Test Telegram + Web


4. MCP Server

Default: Disabled (ENABLE_MCP=false) The MCP (Model Context Protocol) server exposes your EchOS knowledge base to any MCP-compatible AI client — Claude Code, Cursor, Windsurf, and others. It runs as part of the daemon (not a separate process) and listens on a configurable port.

Setup

Add to your .env:
Restart the daemon (pnpm start). You should see:

Exposed Tools

Exposed Resources

MCP resources let clients browse and read notes, tags, and categories without calling a tool. Each resource type uses a URI template: Listing resources (e.g. resources/list) returns all notes, tags, or categories. Reading a resource (e.g. resources/read with notes://abc-123) returns the full content as text/markdown.

Connect from Claude Code

Add to your Claude Code configuration (~/.claude.json or project .claude.json):
If MCP_API_KEY is not set, omit the headers block.

Security

  • The MCP server only binds to 127.0.0.1 (localhost) — not accessible from other machines by default
  • Set MCP_API_KEY to require bearer token authentication on all requests
  • If MCP_API_KEY is unset, the server accepts all requests (convenient for localhost-only use)

Troubleshooting

Telegram: 409 Conflict Error

See Troubleshooting — Telegram bot conflicts

Web API: Port Already in Use

CLI: No output / empty response

  • The model may have changed. Check DEFAULT_MODEL in .env — ensure it’s not a deprecated model
  • Run with LOG_LEVEL=info pnpm echos "query" to see startup and agent creation logs
  • Ensure at least one LLM API key is set: ANTHROPIC_API_KEY (Anthropic) or LLM_API_KEY (other providers)

CLI: Startup logs cluttering output

  • By default the CLI runs at log level warn — you should only see agent responses
  • If you’re seeing logs, check if LOG_LEVEL is set in your shell environment

Interface Not Starting

Check the startup logs:
Look for messages like:
  • Telegram bot started
  • Web server started (with port number)

Next Steps

  • Telegram: See examples in the main README
  • Web API: Build a frontend with React/Vue/etc.
  • CLI: Terminal queries, SSH access, scripting
  • MCP Server: Connect Claude Code, Cursor, and other AI agents to your knowledge base
  • Deploy: See Deployment for production setup