Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/readme-refresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@unclecat/mcp-multi-db": patch
"@unclecat/mcp-obsidian": patch
"@unclecat/mcp-odoo": patch
---

docs: rewrite the README (English + Vietnamese) with a consistent structure: quick start for Claude Code, Claude Desktop/Cursor and VS Code, configuration and tool reference, safety notes, troubleshooting. `@unclecat/mcp-obsidian` now ships `README.vi.md`. db docs now cover `defaultAlias` (optional `databaseAlias`), `defaultSchema` and `db_list_tables` pagination.
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,13 @@ jobs:
fi

# Detect changed workspace packages between this commit and its first parent
# Package dirs come from pnpm-workspace.yaml (root excluded), so new packages are picked up automatically
base=$(git rev-parse HEAD^1)
pkgs=$(pnpm -r exec pwd | xargs -n1 basename)
changed_dirs=$(git diff --name-only "$base" HEAD \
| awk -F/ '$1=="db" || $1=="odoo" {print $1}' \
| sort -u)
| cut -d/ -f1 \
| grep -Fx "$pkgs" \
| sort -u || true)

if [ -z "$changed_dirs" ]; then
echo "No workspace package files changed — no release this run"
Expand Down
14 changes: 10 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ Node ≥ 20 required.

This is a pnpm monorepo. Each MCP server is its own package directory at the repo root and is published independently to npm.

- [`db/`](./db) — `@unclecat/mcp-multi-db`
- [`odoo/`](./odoo) — `@unclecat/mcp-odoo`
- [`db/`](./db): `@unclecat/mcp-multi-db`
- [`obsidian/`](./obsidian): `@unclecat/mcp-obsidian`
- [`odoo/`](./odoo): `@unclecat/mcp-odoo`

To add a new MCP package see [`docs/ADDING_A_NEW_MCP.md`](./docs/ADDING_A_NEW_MCP.md).
### Adding a new package

1. Create `<dir>/` with `package.json` (scoped `@unclecat/mcp-<name>`, `"publishConfig": { "access": "public" }`, `lint` / `format` / `test` / `test:coverage` scripts), `README.md`, `README.vi.md` and `LICENSE`.
2. Add `<dir>` to `pnpm-workspace.yaml` and to the npm `directories` list in `.github/dependabot.yml`. CI and the release workflow pick packages up from the workspace file.
3. Add a changeset. The first version of a new package has to be published manually once (`npm publish --access public`), because npm Trusted Publishing can only be configured for a package that already exists.
4. On npmjs.com, open the package's **Settings → Trusted publishing** and add GitHub Actions with `unclecatvn` / `mcp` / `release.yml`, ticking `npm publish`.

## Branches

Expand Down Expand Up @@ -74,7 +80,7 @@ git push --follow-tags

- **Branch protection on `master`:** require PR + ≥ 1 approval, require status check **`ci-success`** to pass, no force push.
- **Allow GitHub Actions to create PRs:** Settings → Actions → General → Workflow permissions.
- **Secrets:** `NPM_TOKEN` (granular access token for `@unclecat/*`, type "automation").
- **npm Trusted Publishing:** every package on npmjs.com trusts `unclecatvn/mcp` and the workflow `release.yml`. There is no `NPM_TOKEN` secret, because publishing authenticates through OIDC and attaches provenance.

## Tests

Expand Down
98 changes: 76 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,89 @@
# unclecat MCP servers

A monorepo of MCP (Model Context Protocol) servers by [@unclecatvn](https://github.com/unclecatvn).
[Model Context Protocol](https://modelcontextprotocol.io) servers that give AI assistants such as Claude, Cursor and VS Code safe access to SQL databases, Odoo ERP and Obsidian vaults.

[![CI](https://github.com/unclecatvn/mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/unclecatvn/mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Node](https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org)

## Packages

| Package | Description |
|---------|-------------|
| [`@unclecat/mcp-multi-db`](./db) | MCP server for MySQL/MariaDB, PostgreSQL, and SQL Server with parameterized queries and per-alias safety modes. |
| [`@unclecat/mcp-obsidian`](./obsidian) | MCP server for Obsidian vaults via the filesystem. Works without Obsidian running, multi-vault, per-vault readonly/readwrite. |
| [`@unclecat/mcp-odoo`](./odoo) | MCP server for Odoo v18+ via JSON-RPC. Multi-instance support, API key or password auth, generic CRUD tools. |
| Package | Connects to | Highlights |
|---|---|---|
| [**@unclecat/mcp-multi-db**](./db)<br>[![npm](https://img.shields.io/npm/v/@unclecat/mcp-multi-db.svg)](https://www.npmjs.com/package/@unclecat/mcp-multi-db) | MySQL, MariaDB, PostgreSQL, SQL Server | Parameterized queries only, read-only by default, row caps and timeouts, several databases in one server |
| [**@unclecat/mcp-odoo**](./odoo)<br>[![npm](https://img.shields.io/npm/v/@unclecat/mcp-odoo.svg)](https://www.npmjs.com/package/@unclecat/mcp-odoo) | Odoo 18+ over JSON-RPC | Several instances, API-key auth, generic CRUD on any model, business actions through `call_method` |
| [**@unclecat/mcp-obsidian**](./obsidian)<br>[![npm](https://img.shields.io/npm/v/@unclecat/mcp-obsidian.svg)](https://www.npmjs.com/package/@unclecat/mcp-obsidian) | Obsidian vaults on disk | No plugin and no running app needed, backlinks, section-level patching, daily notes |

Each package has its own README with full configuration, a tool reference and troubleshooting. Vietnamese docs are linked from each one.

## Quick start

Every server runs through `npx`, so there is nothing to install or build. With [Claude Code](https://docs.anthropic.com/en/docs/claude-code):

```bash
claude mcp add odoo -e ODOO_PROD_URL=https://erp.example.com -e ODOO_PROD_DB=production -e ODOO_PROD_USERNAME=admin -e ODOO_PROD_API_KEY=your-api-key -- npx -y @unclecat/mcp-odoo
```

```bash
claude mcp add obsidian -e OBSIDIAN_MAIN_PATH=/absolute/path/to/Vault -- npx -y @unclecat/mcp-obsidian
```

```bash
claude mcp add multi-db -e MCP_DB_CONFIG=/absolute/path/to/mcp-db.config.json -- npx -y @unclecat/mcp-multi-db
```

For Claude Desktop, Cursor and VS Code, see the configuration section of each package README.

## Design principles

## Repository
All servers in this repository follow the same rules:

- Releases: [Releases](https://github.com/unclecatvn/mcp/releases)
- Security policy: [`SECURITY.md`](./SECURITY.md)
- Contributing: [`CONTRIBUTING.md`](./CONTRIBUTING.md)
- Adding a new MCP package: [`docs/ADDING_A_NEW_MCP.md`](./docs/ADDING_A_NEW_MCP.md)
- License: [MIT](./LICENSE)
- **Safe by default.** Every server starts read-only, and you opt in to writes per database, instance or vault. Destructive tools are annotated so hosts can ask before running them, and secrets are never echoed back to the model.
- **Multi-target.** One server process handles any number of databases, Odoo instances or vaults, and the model picks one per call.
- **Model-friendly.** Tool descriptions include examples, errors carry stable codes, and each server sends short instructions on `initialize` so the model composes correct calls on the first try.
- **Zero install.** Plain ESM JavaScript on Node 20+, with no build step and no native dependencies.
- **Supply-chain hygiene.** Packages are published from GitHub Actions through [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers) with provenance. Dependabot proposes updates weekly and skips releases younger than 14 days.

## Workspace layout
## Repository layout

```
.
├── db/ # @unclecat/mcp-multi-db
├── obsidian/ # @unclecat/mcp-obsidian
├── odoo/ # @unclecat/mcp-odoo
├── .changeset/ # release-flow state (Changesets)
├── .github/workflows/ # ci.yml, release.yml
├── docs/ # repo-level docs
├── pnpm-workspace.yaml # workspace package list
└── package.json # private root, scripts only
├── db/ @unclecat/mcp-multi-db
├── obsidian/ @unclecat/mcp-obsidian
├── odoo/ @unclecat/mcp-odoo
├── .changeset/ pending release notes (Changesets)
├── .github/ CI, release workflow, Dependabot
├── pnpm-workspace.yaml workspace package list
└── package.json private root: shared scripts and dev tooling
```

Each package is independently versioned and published to npm.
## Development

Requires Node 20+ and pnpm 9+.

```bash
git clone https://github.com/unclecatvn/mcp.git
cd mcp
pnpm install
pnpm -r test # unit tests in every package
pnpm -r lint # ESLint
pnpm -r format # Prettier check
```

Work on one package with `pnpm --filter <package-name> <script>`, for example `pnpm --filter @unclecat/mcp-obsidian test:watch`.

## Releasing

1. Open a feature branch, add a changeset (`pnpm changeset`) and open a PR into `staging`.
2. Promote `staging` to `master` with a PR.
3. The release workflow opens a **version packages** PR. Merging it publishes every bumped package to npm.

Details are in [CONTRIBUTING.md](./CONTRIBUTING.md).

## Security

Please report vulnerabilities privately as described in [SECURITY.md](./SECURITY.md). Do not open public issues for them.

## License

[MIT](./LICENSE) © UncleCat
4 changes: 3 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This policy applies to **all packages** in this monorepo:

- [`@unclecat/mcp-multi-db`](./db)
- [`@unclecat/mcp-obsidian`](./obsidian)
- [`@unclecat/mcp-odoo`](./odoo)

## Reporting a vulnerability
Expand All @@ -23,13 +24,14 @@ Only the **latest released minor** of each package receives security fixes.
| Package | Supported |
| -------------------------- | --------- |
| `@unclecat/mcp-multi-db` | latest minor |
| `@unclecat/mcp-obsidian` | latest minor |
| `@unclecat/mcp-odoo` | latest minor |

Older versions can be patched on a best-effort basis if the vulnerability is severe and the consumer cannot upgrade.

## Threat model

All packages run as **trusted processes** with access to external systems (databases, ERP APIs). They are designed to be invoked by a **single MCP host process** (Claude Desktop, Claude Code, etc.) — not exposed as a network service.
All packages run as **trusted processes** with access to external systems (databases, ERP APIs) or local files (Obsidian vaults). They are designed to be invoked by a **single MCP host process** (Claude Desktop, Claude Code, etc.) — not exposed as a network service.

Shared mitigations:

Expand Down
Loading
Loading