alcove-mcp
by KoroKira
README.md
# alcove-mcp
`alcove-mcp` is a small, read-only MCP adapter that lets MCP hosts and agents
such as Hermes access Alcove through its public `/api/v1` HTTP API.
The adapter never imports Alcove code and never accesses Alcove's PostgreSQL,
Redis, filesystem, or internal services. Its only data path is:
```text
MCP host -> alcove-mcp -> HTTP /api/v1 -> Alcove authorization and API
```
## V0 surface
The server exposes exactly four tools:
| MCP tool | Alcove endpoint | Required scope |
| ----------------- | ------------------------------------ | -------------- |
| `list_pads` | `GET /api/v1/pads` | `pads:read` |
| `search_pads` | `GET /api/v1/search?q=...&limit=...` | `search:read` |
| `get_pad` | `GET /api/v1/pads/{pad_id}` | `pads:read` |
| `get_pad_content` | `GET /api/v1/pads/{pad_id}/content` | `pads:read` |
At startup, the client performs an internal `GET /api/v1/me` identity/readiness
check. It is deliberately not exposed as an MCP tool.
V0 has no writing, deleting, sharing, shell, terminal, filesystem,
administration, token-management, or implicit fallback capabilities.
## Architecture
```text
src/config/ environment validation and URL/token configuration
src/alcove/ HTTP client, DTO schemas, and safe upstream errors
src/mcp/ MCP server factory and four tool registrations
src/main.ts stdio entrypoint
tests/ config, HTTP mapping, MCP validation, and security tests
```
The MCP SDK validates tool arguments from Zod schemas before handlers run.
The Alcove client validates successful HTTP responses against Zod DTOs. The
adapter does not reproduce Alcove authorization or membership rules: 401,
403, and inaccessible-pad behavior are returned by Alcove and mapped to safe
MCP errors.
## Requirements
- Node.js 24 LTS (the reference runtime and CI version)
- npm
- An Alcove deployment exposing `/api/v1`
- An Alcove API token with only `me:read`, `pads:read`, and `search:read`
Node.js `>=24` is declared in `package.json`.
## Installation
```sh
npm ci
npm run build
```
For local development without building:
```sh
npm run dev
```
## Configuration
Copy `.env.example` to a local environment file or export the variables in
the process environment:
```sh
export ALCOVE_URL=http://127.0.0.1:8000
export ALCOVE_API_TOKEN='your-read-only-token'
```
`ALCOVE_URL` is the Alcove base URL. The adapter appends `/api/v1`.
Credentials, query strings, fragments, unsupported protocols, empty tokens,
and tokens containing whitespace are rejected.
The token is a secret. Do not commit it, put it in a URL, include it in a
fixture, or paste it into logs or MCP configuration checked into source
control.
## Creating a read-only Alcove token
Create an Alcove API token through the authenticated Alcove web interface or
the API-token management flow in Alcove. Configure only these scopes:
```text
me:read
pads:read
search:read
```
The corresponding Alcove API operation is `POST /api/v1/tokens` and requires
an interactive browser session. Its request can contain a name, the three
scopes above, and an expiry such as `90` days. The creation response contains
the raw token once; never print that response in a shell transcript or CI log.
Do not grant `pads:write`, `pads:share`, or any administrative scope. Store
the raw token only in the secret environment of the MCP host. Alcove returns
the raw token only when it is created; if it is lost, revoke it and create a
new one.
## Running over stdio
The built server is launched with:
```sh
ALCOVE_URL=http://127.0.0.1:8000 \
ALCOVE_API_TOKEN='your-read-only-token' \
node dist/main.js
```
During development, MCP hosts can launch:
```sh
npx tsx src/main.ts
```
stdout is exclusively the MCP JSON-RPC protocol channel. The server does not
write banners or diagnostics to stdout. Transport errors, when any, go to
stderr.
## MCP host configuration
An MCP host should launch the server as a child process and pass the secrets
through its environment. For example, a generic stdio configuration is:
```json
{
"command": "node",
"args": ["/absolute/path/to/alcove-mcp/dist/main.js"],
"env": {
"ALCOVE_URL": "http://127.0.0.1:8000",
"ALCOVE_API_TOKEN": "${ALCOVE_API_TOKEN}"
}
}
```
The exact wrapper key differs between MCP hosts. The important properties are
the command, arguments, and environment variables; no custom MCP protocol
implementation is required.
## Security model
- Alcove remains the source of truth for authentication, scopes, memberships,
and pad authorization.
- The Bearer token is sent only in the HTTP `Authorization` header.
- HTTP redirects are disabled so a token cannot be forwarded to another host.
- Response bodies are validated and upstream bodies are not copied into error
messages.
- Invalid-token and revoked-token responses share the same safe authentication
error.
- Inaccessible pads are handled through Alcove's 404 response and are not
distinguished locally.
- No data is persisted or cached by this adapter.
- Only the four explicit read-only tools are registered.
## Verification
```sh
npm run build
npm run typecheck
npm run lint
npm run test
npm run test:stdio
```
`test:stdio` starts the real server entrypoint as a child process and uses the
official MCP client SDK to perform the stdio handshake, `tools/list`, and a
`tools/call`. This also proves that stray stdout output would break the MCP
conversation. It verifies that the configured test token does not appear on
stderr.
The MCP Inspector can be used manually after building:
```sh
npx @modelcontextprotocol/inspector \
env ALCOVE_URL=http://127.0.0.1:8000 \
ALCOVE_API_TOKEN="$ALCOVE_API_TOKEN" \
node dist/main.js
```
## V0 limitations
- stdio is the only transport currently wired.
- There are no write, sharing, deletion, administration, shell, filesystem,
terminal, or resource/prompt surfaces.
- The adapter does not implement authorization or membership logic.
- The adapter does not refresh, create, revoke, or persist Alcove tokens.
- A remote deployment can be added later using the same server factory and an
official Streamable HTTP transport.
## License
MIT. See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues