# L-Dopa > **An MCP server for helping AI agents recover, refocus, and get shit done.** > > *L-Dopa fixed me, alright??* L-Dopa is a small, production-minded [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that helps an agent recover when an approach is failing, context is scattered, or retries are turning into a loop. It **does not execute commands, mutate external systems, or replace an agent's judgment**. It analyzes the evidence supplied to it, retains bounded recovery state, and proposes a safer next move. The name is a joke. The recovery loop is not. ## What it does L-Dopa v0.1 provides six MCP tools that let an agent diagnose failures, reduce scope, restore relevant context, and manage retries deliberately. | Tool | Use it when | It returns | | --- | --- | --- | | `diagnose` | An operation failed and the agent has an error or log excerpt. | Likely cause, calibrated confidence, redacted evidence, next actions, and retry guidance. | | `stimulate` | The agent is circling without making a useful observation. | A concise reset that focuses on an assumption and a minimal safe check. | | `focus` | A task is too broad or tangled. | A prioritized list of one to five concrete next actions; three is the default. | | `reuptake` | The agent needs relevant recovery context from its L-Dopa session. | A compact summary of recent failures, attempts, successes, facts, and unresolved issues. | | `retry` | The agent is considering or reporting a retry. | A recorded, bounded retry or a block with an alternative-strategy recommendation. | | `fix_me` | The agent is stuck and wants one concise recovery sequence. | Diagnosis, focused actions, a recovery nudge, and retry guidance. | ## Design principles | Principle | Implementation in v0.1 | | --- | --- | | **No magical certainty** | Diagnostic confidence is `low`, `medium`, or `high`; weak evidence remains weak. | | **No blind loops** | Repeated materially similar failures, unchanged retry proposals, and per-operation retry limits block further retries. | | **Bounded memory** | JSON-backed state retains only the configured number of records per category for each session. | | **Safe by default** | L-Dopa offers diagnosis and planning only. It never executes shell commands or external actions. | | **Credential-aware output** | Common token, authorization header, password, API-key, JWT, AWS-key, and GitHub-token patterns are redacted before state, logs, and tool output. | | **Simple deployment** | The server uses standard MCP stdio transport and requires Node.js 18 or newer. | ## Installation Clone the repository and install the dependencies: ```bash git clone https://github.com/mshanghai570/L-Dopa.git cd L-Dopa npm install npm run build ``` Start the stdio server manually with: ```bash npm start ``` `npm start` intentionally appears to wait for input. MCP servers speak JSON-RPC over standard input and output, so normally an MCP client launches it for you. ## Connect an MCP client Build L-Dopa first, then use its executable entry point. The following generic MCP configuration is compatible with clients that support local stdio servers: ```json { "mcpServers": { "l-dopa": { "command": "node", "args": ["/absolute/path/to/L-Dopa/dist/index.js"], "env": { "LDOPA_STATE_FILE": "/absolute/path/to/l-dopa-state.json", "LDOPA_MAX_HISTORY": "50", "LDOPA_RETRY_LIMIT": "3", "LDOPA_LOG_LEVEL": "info" } } } } ``` For an installed package, the command may instead be `l-dopa`, depending on the client environment. Keep standard output reserved for MCP protocol messages. L-Dopa writes its own concise structured operational logs to standard error. ## Configuration L-Dopa runs with safe defaults and can be configured through a JSON file and/or environment variables. Copy the provided example to get started: ```bash cp l-dopa.config.example.json l-dopa.config.json LDOPA_CONFIG=./l-dopa.config.json npm start ``` Environment variables override file values. | Setting | JSON property | Environment variable | Default | Meaning | | --- | --- | --- | --- | --- | | State path | `stateFile` | `LDOPA_STATE_FILE` | `~/.l-dopa/state.json` | Location of the bounded JSON session store. | | History limit | `maxHistory` | `LDOPA_MAX_HISTORY` | `50` | Positive maximum records retained for each category in a session. | | Retry limit | `retryLimit` | `LDOPA_RETRY_LIMIT` | `3` | Positive maximum planned/reported retries retained for an operation before new retries are blocked. | | Logging level | `logLevel` | `LDOPA_LOG_LEVEL` | `info` | One of `debug`, `info`, `warn`, or `error`. | | Config file | — | `LDOPA_CONFIG` | — | Optional path to a JSON configuration file. | Configuration contains **no provider credential settings** because this version makes no model or provider calls. If a future extension requires credentials, pass them through environment variables; do not add them to a repository, configuration file, or recovery prompt. ## Tool reference All text arguments are bounded and credential-redacted before L-Dopa persists or returns them. `sessionId` defaults to `"default"`, but agents should use a stable ID per task or conversation to prevent unrelated recovery histories from mixing. ### `diagnose` Use `diagnose` after a failure with as much useful context as is available. `errorMessage`, `recentOperation`, `logs`, `attemptedSolution`, `expectedResult`, and `actualResult` are optional, but a precise error or actual result makes the response more useful. ```json { "sessionId": "deploy-2026-08-27", "recentOperation": "Deploy version 0.1.0", "errorMessage": "429 Too Many Requests", "attemptedSolution": "Immediately retried the deployment", "expectedResult": "Deployment accepted", "actualResult": "The API rejected the request" } ``` The response includes `likelyCause`, `confidence`, `evidence`, `recommendedNextActions`, `retryAppropriate`, `tryDifferentStrategy`, and a `redacted` indicator. Detection is deliberately heuristic rather than falsely authoritative. ### `stimulate` Use `stimulate` when an agent needs to stop narrating and start learning. Supply a required `task` and optional high-signal `context`. ```json { "sessionId": "deploy-2026-08-27", "task": "Repair the deployment", "context": "The health check timed out twice after a successful build" } ``` The recovery strategy emphasizes a minimal, verifiable action and warns against unchanged loops. ### `focus` Use `focus` to turn a broad task into a deliberately short sequence. `maxSteps` is optional and ranges from one to five; it defaults to three. ```json { "sessionId": "deploy-2026-08-27", "task": "Repair the deployment and verify availability", "context": "Health checks time out", "maxSteps": 3 } ``` ### `reuptake` Use `reuptake` when the agent needs relevant session context without dumping a transcript. `limit` defaults to five and is capped at twenty. ```json { "sessionId": "deploy-2026-08-27", "limit": 5 } ``` It returns the current task, recovery status, recent failures, attempted solutions, successful approaches, discovered facts, unresolved issues, and retry count. The v0.1 tools do not yet expose a dedicated fact-recording tool; `discoveredFacts` is reserved for extensions and remains present in the compact schema. ### `retry` Use `retry` to create an explicit retry record or report its outcome. A `proposedChange` should name what is different. L-Dopa permits planned, successful, and failed records, but it never performs the retry itself. ```json { "sessionId": "deploy-2026-08-27", "operation": "Deploy version 0.1.0", "previousFailure": "429 Too Many Requests", "proposedChange": "Wait for Retry-After and submit only one request", "result": "planned" } ``` L-Dopa blocks a retry if the configured operation limit is exhausted, the same failure has recurred, or an existing retry is repeated without a changed proposal. Its block response recommends a bounded alternative path, which may include handing a well-scoped subtask and gathered evidence to another capable agent. ### `fix_me` Use `fix_me` for the short version of `diagnose → focus → stimulate → retry guidance`. It records a supplied failure, when present, then returns a plan; it does not execute it. ```json { "sessionId": "publish-0.1.0", "task": "Publish the package safely", "recentOperation": "npm publish", "errorMessage": "401 Unauthorized", "attemptedSolution": "Re-ran the same command" } ``` ## State and privacy The state store is a plain JSON file written atomically with mode `0600`. It has a versioned shape and stores separate sessions keyed by `sessionId`. Within each session, failure records, retry records, attempted solutions, successful approaches, and discovered facts are trimmed to `maxHistory`. State is intentionally lightweight, not a long-term memory system. It is local to the running user's machine and is not transmitted by L-Dopa. Review or delete the configured state file whenever you need to clear recovery history. > **Important:** Redaction covers several common credential patterns but is a defensive convenience, not a license to submit secrets. Do not intentionally place passwords, tokens, private keys, or full authorization headers in diagnostic input. ## Development ```bash npm install npm run build npm test ``` The project is deliberately modular: ```text src/ config.ts Configuration loading and validation index.ts Executable stdio MCP entry point logger.ts Structured, redacted standard-error logging redaction.ts Credential-detection and output redaction recovery.ts Diagnostic, focus, stimulation, and plan logic server.ts MCP server and tool registrations state.ts Bounded, atomic JSON session storage types.ts Shared contracts tests/ l-dopa.test.ts End-to-end MCP and state behavior tests ``` ## Test coverage The automated suite connects a real MCP client and server through the SDK's in-memory transport. It covers server initialization, MCP tool discovery, every tool, state persistence, bounded retention, retry limits, unchanged retries, repeated-failure detection, and credential redaction. Run it with: ```bash npm test ``` ## Limitations and roadmap L-Dopa v0.1 uses deterministic heuristics, so it recognizes common failure classes but is not an omniscient debugger. It has no vector store, remote persistence, model-provider integration, or command-execution capability by design. It does not inspect an agent's hidden chain of thought; it only works with supplied operational context. Future additions should preserve these boundaries: add a tool only when it provides a clear recovery benefit, keep command execution in a separate permission-controlled component, and keep state bounded and inspectable. ## License [MIT](LICENSE)