Skip to main content
Glama
sddiv
by sddiv
README.md
### Retired this implementation to generate a new one at NLSpec-Server

> Generated by [Claude Code](https://claude.ai/claude-code) using [NLSpec](https://github.com/sddiv/NLSpec-Specification)

# @nlspec/server

MCP server that parses natural language specification (nlspec) markdown files into structured, queryable elements and exposes CRUD + search operations as MCP tools.

An AI coding agent connects via MCP and can read, create, update, delete, and search spec elements without parsing raw markdown itself.

## Architecture

```
+-----------------------------------------------------------+
|                    MCP Clients                             |
|  (Claude Code, Cursor, Claude Desktop, any MCP client)    |
+---------------------------+-------------------------------+
                            | MCP Protocol (stdio)
                            v
+-----------------------------------------------------------+
|                   nlspec MCP Server                        |
|                                                            |
|  +-------------------+  +-------------------+             |
|  |  MCP Tool Layer   |  |  CLI Adapter      |             |
|  |  7 tools          |  |  (same functions) |             |
|  +---------+---------+  +---------+---------+             |
|            |                      |                        |
|            +----------+-----------+                        |
|                       |                                    |
|            +----------v-----------+                        |
|            |    Core Engine       |                        |
|            |                      |                        |
|            |  +----------------+  |                        |
|            |  | Spec Parser    |  | Markdown -> Elements   |
|            |  +----------------+  |                        |
|            |  +----------------+  |                        |
|            |  | Spec Store     |  | CRUD on Elements       |
|            |  +----------------+  |                        |
|            |  +----------------+  |                        |
|            |  | Query Engine   |  | Text + structural      |
|            |  +----------------+  | search                 |
|            |                      |                        |
|            +----------+-----------+                        |
|                       |                                    |
|            +----------v-----------+                        |
|            |  Persistence         |                        |
|            |  - .md files (truth) |                        |
|            |  - SQLite (index)    |                        |
|            +----------------------+                        |
+-----------------------------------------------------------+
```

Markdown files on disk are the **source of truth**. The SQLite index is a derived cache for fast queries and FTS5 full-text search. All mutations write back to markdown atomically (temp file + rename) and re-index.

## Prerequisites

- Node.js 20+
- npm

## Build

```bash
npm install
npm run build
```

## Test

```bash
npm test                # all tests (21 scenarios)
npm run test:smoke      # smoke only (scenarios 1, 2, 3)
```

## Usage

### As an MCP Server

Add to your MCP client configuration:

**Claude Code** (`.mcp.json` in project root):
```json
{
  "mcpServers": {
    "nlspec": {
      "command": "npx",
      "args": ["@nlspec/server"]
    }
  }
}
```

**Claude Desktop** (`claude_desktop_config.json`):
```json
{
  "mcpServers": {
    "nlspec": {
      "command": "npx",
      "args": ["@nlspec/server", "--project-dir", "/path/to/project"]
    }
  }
}
```

Or run directly:
```bash
npx @nlspec/server --project-dir /path/to/project
```

### As a CLI

```bash
npx nlspec init --name myservice
npx nlspec list --spec myservice --type FUNCTION
npx nlspec search "Entry" --type FUNCTION
npx nlspec get --spec myservice --section 5.1
```

## MCP Tools

| Tool | Description |
|---|---|
| `nlspec_init` | Initialize a new nlspec project or add a spec |
| `nlspec_get` | Read a specific element by ID or an entire section |
| `nlspec_list` | List elements with filters (type, section, tags) |
| `nlspec_search` | Full-text search + structural reference search |
| `nlspec_create` | Add a new element to a spec section |
| `nlspec_update` | Modify an existing element's content, tags, or name |
| `nlspec_delete` | Remove an element (with reference-safety check) |

### Examples

```
nlspec_get({spec_id: "kv-store", section: "5.1"})
  -> Returns Section 5.1 with all FUNCTIONs

nlspec_search({references: "Entry", element_type: "FUNCTION"})
  -> Returns all FUNCTIONs that USES Entry

nlspec_list({spec_id: "kv-store", element_type: "SCENARIO", tags: ["SMOKE"]})
  -> Returns SMOKE-tagged scenarios

nlspec_create({spec_id: "kv-store", section: "10", element_type: "SCENARIO", ...})
  -> Adds a new SCENARIO to the spec and markdown file
```

## Configuration

All settings can be set via environment variables:

| Variable | Default | Description |
|---|---|---|
| `NLSPEC_TRANSPORT` | `"stdio"` | MCP transport type |
| `NLSPEC_PROJECT_DIR` | `"."` | Root directory of the project |
| `NLSPEC_INDEX_PATH` | `".nlspec/index.sqlite"` | SQLite index path (relative to project_dir) |
| `NLSPEC_AUTO_REINDEX` | `true` | Re-parse when markdown files change |
| `NLSPEC_FTS` | `true` | Enable FTS5 full-text search |

## Element Types

The parser recognizes these element types inside code fence blocks in spec markdown:

`RECORD` `FUNCTION` `ENDPOINT` `SCENARIO` `ENUM` `ALIAS` `CONFIG` `IMAGE` `MANIFEST` `INFRA` `PIPELINE` `TOPOLOGY` `CONTRACT` `FAILURE_MODE` `IMPORT` `PROSE`

## How It Works

1. On startup, the server scans `specs/` for `*-spec.md` files
2. Each file is parsed into structured `SpecElement` objects — detecting types, extracting references (`USES`, `THROWS`, `USED BY`), tags (`[SEC:x.x]`), and preserving raw markdown
3. Elements are indexed in SQLite with FTS5 for full-text search
4. MCP tools expose CRUD + search over this index
5. Write operations (create/update/delete) modify both the SQLite index and the markdown file atomically
6. The markdown file is always the source of truth — the SQLite index is rebuilt from it on load

## Dependencies

| Package | Purpose |
|---|---|
| `@modelcontextprotocol/sdk` | MCP server SDK (tool registration, stdio transport) |
| `better-sqlite3` | SQLite for element index and FTS5 full-text search |

## License

MIT