Skip to main content
Glama
README.md
# 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)

TDQS

A3.6/5.0

Scored across 6 tools

Disambiguation2/5

Several tools have unclear boundaries: diagnose, focus, and fix_me all produce recommended next actions or plans, while stimulate and focus both generate recovery-oriented output. Only reuptake and retry are clearly distinct, making tool selection genuinely ambiguous.

Naming Consistency4/5

The tools mostly follow a consistent lowercase imperative-verb style: diagnose, stimulate, focus, retry. The main deviation is fix_me, which introduces an underscore and an object pronoun, but the overall naming pattern is still recognizable.

Tool Count4/5

Six tools is a reasonable size for a session-recovery-focused server. However, fix_me is an aggregate of other tools and adds some redundancy, so the set is slightly less lean than it could be.

Completeness4/5

The tool surface covers the core recovery loop well: diagnose failures, focus on next actions, retry with bounded state, and retrieve session context. Minor gaps exist around explicit session reset or state-clearing operations, but agents can generally work around them.

Maintenance

ActivityMaintained
ResponsivenessNo issues