Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.hitheo.ai/llms.txt

Use this file to discover all available pages before exploring further.

When @hitheo/mcp starts, it looks for a theo.config.json in the working directory (the IDE workspace root). If it finds one, every relevant tool call is enriched with the values you defined — your IDE agent doesn’t have to remember to pass them. This is how you give a repo its own persona (“you are a backend engineer for this Express API”), pre-activate the skills that matter for the project, and expose custom tools that only make sense in this codebase.
Most people generate this file with theo init, then tune persona and skills by hand. You rarely need to write it from scratch.

Quick example

{
  "persona": "You are a backend engineer assistant for this Express API.",
  "skills": ["deep-research", "content-writer"],
  "defaultMode": "code",
  "temperature": 0.3,
  "tools": [
    {
      "name": "check_stock",
      "description": "Look up current stock levels for a SKU",
      "input_schema": {
        "type": "object",
        "properties": { "sku": { "type": "string" } },
        "required": ["sku"]
      }
    }
  ],
  "metadata": { "team": "warehouse-ops" }
}
Drop that at the repo root. The next time any MCP tool fires, those fields are merged into the request.

Schema

FieldTypeUsed byDescription
personastringtheo_completeCustom system prompt injected as persona.system_prompt.
skillsstring[]theo_completeSkill slugs to activate on every completion.
defaultModeChatModetheo_completeFallback mode when the caller didn’t pass one.
toolsToolDef[]theo_completeInline tool definitions Theo can call during the agent loop.
temperaturenumberreservedDefault temperature. (Plumbed in the config loader but not yet forwarded by theo_complete.)
metadataRecord<string, unknown>reservedMetadata attached to every request for tracking. (Loaded today; passthrough planned.)
ToolDef shape (used in tools):
interface ToolDef {
  name: string;
  description: string;
  input_schema?: Record<string, unknown>;  // JSON-Schema
}

File precedence and sandbox

@hitheo/mcp loads config in this order, by design:
  1. theo.config.json — always loaded if present. Parsed with JSON.parse; no code runs.
  2. theo.config.js / theo.config.tsignored unless you opt in. Loading them would import() arbitrary code from the workspace root, which is unsafe when an IDE spawns the MCP server inside a project you haven’t audited.
To opt back in:
export THEO_ALLOW_JS_CONFIG=1
With that flag set, the loader tries theo.config.js first, then theo.config.ts, before falling back to JSON. If a JS/TS config is present without the flag, the server logs a warning to stderr and skips it.
Only set THEO_ALLOW_JS_CONFIG=1 in directories you authored or trust. A malicious theo.config.js in any repo you open will execute as your user the moment the IDE launches the MCP server.
Even with the flag set, theo.config.json remains the recommended format. The TypeScript helper defineConfig from @hitheo/sdk can emit a typed object you then JSON.stringify into the JSON file if you want autocompletion in your editor.

Merge semantics

When the MCP server handles a tool call, the project config is merged with the arguments the IDE agent passes in. The rules:
FieldMerge rule
personaIf config has persona, it becomes persona.system_prompt. Caller arg overrides if present.
skillsConcatenated: [...config.skills, ...args.skills]. Empty result → field omitted.
defaultModeOnly used if the caller didn’t pass mode. Caller args win.
toolsForwarded as-is when no caller args; not currently overridden by per-call tool lists.
temperature, metadataLoaded by the config parser; not yet forwarded by theo_complete.
In practice this means:
  • A repo persona is always applied.
  • Skills are additive — the agent can request more skills on top of the repo’s defaults, but cannot subtract from them in a single call.
  • Modes follow “explicit wins”: if the agent passes mode: "research", that beats defaultMode: "code".

Where theo init puts it

When you run theo init, the CLI writes a starter config based on your folder name:
{
  "persona": "You are an AI assistant for the <project-name> project.",
  "skills": [],
  "defaultMode": "auto"
}
You can edit it freely afterward; the MCP server will pick up changes the next time it starts (i.e. the next IDE restart).

Updating without restarts

The config is read once at server startup, so changes take effect on the next MCP server boot (which usually means the next time your IDE reopens the workspace). If you need to iterate on a persona quickly, edit .theo/RULES.md instead — it influences how the IDE’s agent thinks about the tools, and most agents reload it automatically.
  • Install — how theo init writes the config file in the first place.
  • SDK defineConfig — typed helper for projects that prefer TS authoring.
  • Skills overview — what to put in skills.
  • Security — full rationale for the JSON-only default.