MCP (Model Context Protocol) server for Hudu IT documentation platform. Provides 39 tools and 6 resources for managing companies, assets, articles, passwords, websites, and more through any MCP-compatible client.
- 39 MCP tools covering all major Hudu resources
- 6 MCP resources for direct data access
- Dual auth mode: classic
HUDU_API_KEYREST access, oroauth— a thin, authenticated proxy to a newer Hudu instance's own native MCP server - Dual transport support: stdio (default) and HTTP Streamable
- Lazy initialization - SDK client created on first tool call
- Connection testing built-in
- All logging to stderr to avoid polluting MCP stdio transport
Important
Before you click: this server depends on @wyre-technology/node-hudu,
which is hosted on the GitHub Packages npm registry. GitHub Packages has no
anonymous access — even though the package is public, every npm install needs a
token. The cloud builder runs npm install for you, so you must give it one, or
the build fails with npm error 401 Unauthorized ... npm.pkg.github.com.
- Create a GitHub Personal Access Token with the
read:packagesscope (classic token). Any GitHub account works — you do not need to be a member of thewyre-technologyorg to read its public packages. - Add it as a build variable when prompted by the deploy flow:
- DigitalOcean App Platform → set an encrypted env var named
NODE_AUTH_TOKENwith scope Build Time to your PAT (theDockerfilereads it viaARG NODE_AUTH_TOKENto authenticatenpm ci). - Cloudflare Workers → set a build variable named
NODE_AUTH_TOKENto your PAT (Workers → Settings → Build → Variables and Secrets).
- DigitalOcean App Platform → set an encrypted env var named
Note
The DigitalOcean target builds the full Docker image and runs the complete MCP
server over HTTP — this is the recommended path for operators. This repo does not
ship a wrangler.json/Workers entrypoint, so for a self-hosted server prefer
DigitalOcean or the prebuilt container image (ghcr.io/wyre-ai/hudu-mcp).
This project depends on @wyre-technology/node-hudu, published to the GitHub
Packages npm registry, which requires a token even for public packages.
Authenticate npm once before installing:
git clone https://github.com/WYRE-AI/hudu-mcp.git
cd hudu-mcp
# Authenticate npm to GitHub Packages (token needs the read:packages scope)
export NODE_AUTH_TOKEN=$(gh auth token) # or a PAT with read:packages
npm install
npm run buildThe repo's .npmrc already points the @wyre-technology scope at GitHub Packages and
reads the token from NODE_AUTH_TOKEN, so no further config is needed.
| Variable | Required | Default | Description |
|---|---|---|---|
HUDU_BASE_URL |
Yes | - | Your Hudu instance URL (e.g., https://docs.example.com) |
HUDU_API_KEY |
No | - | Your Hudu API key. Setting this selects api_key auth mode (see below); omitting it defaults to oauth mode. |
HUDU_AUTH_MODE |
No | auto-detected | Explicitly force api_key or oauth. Overrides the auto-detection below. |
MCP_TRANSPORT |
No | stdio |
Transport type: stdio or http |
MCP_HTTP_PORT |
No | 8080 |
HTTP server port (when using http transport) |
MCP_HTTP_HOST |
No | 0.0.0.0 |
HTTP server host |
MCP_SERVER_NAME |
No | hudu-mcp |
Server name reported to MCP clients |
MCP_SERVER_VERSION |
No | 1.0.0 |
Server version reported to MCP clients |
LOG_LEVEL |
No | info |
Log level: error, warn, info, debug |
LOG_FORMAT |
No | simple |
Log format: json or simple |
This server talks to Hudu in one of two ways. HUDU_AUTH_MODE picks between
them; if it's unset, the mode is auto-detected from whether HUDU_API_KEY
is set:
-
api_key(auto-selected whenHUDU_API_KEYis set) — the classic mode. This server calls Hudu's REST API directly via@wyre-technology/node-huduand implements all 39 tools itself, exactly as before. This is the mode every existing deployment already uses, and it is 100% unchanged and unaffected by everything below. -
oauth(auto-selected whenHUDU_API_KEYis not set) — for newer Hudu instances that expose their own native MCP server (Hudu Admin -> External Apps -> MCP), protected by interactive OAuth rather than a static API key. In this modehudu-mcpdoes not reimplement any tools; it acts as a thin, authenticated proxy that forwards MCP requests straight through to{HUDU_BASE_URL}/mcpand relays the responses back, so you automatically get whatever tool surface that Hudu instance exposes.The OAuth flow (RFC 9728/8414 discovery, RFC 7591 Dynamic Client Registration, PKCE
authorization_code, no client secret — this is a public client) runs the first time a request needs a token:hudu-mcpdiscovers the instance's OAuth metadata from{HUDU_BASE_URL}/.well-known/oauth-protected-resource/mcpand{HUDU_BASE_URL}/.well-known/oauth-authorization-server.- It registers itself as a public OAuth client via Dynamic Client
Registration (once per Hudu instance — the issued
client_idis cached). - It prints an authorization URL to stderr. Open it in a browser and approve access.
- A short-lived local server on
http://127.0.0.1:<ephemeral-port>/callbackcatches the redirect and exchanges the code for tokens. - Tokens are cached at
~/.hudu-mcp/credentials-<hash-of-base-url>.json(file mode0600), and transparently refreshed on later runs — you should only see the browser prompt again if the refresh token itself expires or is revoked.
Because this flow needs a browser that can reach a callback server bound to
127.0.0.1on the machine runninghudu-mcp, it works forstdio(always local to the calling MCP client) and for a self-hostedhttptransport running on the same machine you're browsing from — e.g. local testing onlocalhost:8080. It does not work for anhttptransport deployed to a remote host you don't have browser-level access to (a cloud VM, a container, etc.): your browser can't reach that machine's own loopback interface to complete the redirect, so the first-run authorization would hang. This is unrelated to gateway mode (AUTH_MODE=gateway), which is a stateless multi-tenant proxy with credentials injected per request via headers and has no single user to run a browser flow for at all — settingHUDU_AUTH_MODE=oauthtogether withAUTH_MODE=gatewayis a startup error.
Add to your claude_desktop_config.json:
{
"mcpServers": {
"hudu": {
"command": "node",
"args": ["/path/to/hudu-mcp/dist/entry.js"],
"env": {
"HUDU_BASE_URL": "https://docs.example.com",
"HUDU_API_KEY": "your-api-key"
}
}
}
}For a newer Hudu instance with its own native MCP server (see
Authentication modes), omit HUDU_API_KEY and only set
HUDU_BASE_URL — hudu-mcp will print an authorization URL to the terminal the
first time it's launched:
{
"mcpServers": {
"hudu": {
"command": "node",
"args": ["/path/to/hudu-mcp/dist/entry.js"],
"env": {
"HUDU_BASE_URL": "https://docs.example.com"
}
}
}
}HUDU_BASE_URL=https://docs.example.com \
HUDU_API_KEY=your-api-key \
MCP_TRANSPORT=http \
MCP_HTTP_PORT=8080 \
npm start| Tool | Description |
|---|---|
hudu_list_companies |
List companies with optional filters |
hudu_get_company |
Get a company by ID |
hudu_create_company |
Create a new company |
hudu_update_company |
Update an existing company |
hudu_delete_company |
Delete a company |
hudu_archive_company |
Archive a company |
hudu_unarchive_company |
Unarchive a company |
hudu_test_connection |
Test the connection to Hudu API |
| Tool | Description |
|---|---|
hudu_list_assets |
List assets with optional filters |
hudu_get_asset |
Get an asset by ID |
hudu_create_asset |
Create a new asset |
hudu_update_asset |
Update an existing asset |
hudu_delete_asset |
Delete an asset |
hudu_archive_asset |
Archive an asset |
| Tool | Description |
|---|---|
hudu_list_asset_layouts |
List asset layouts |
hudu_get_asset_layout |
Get an asset layout by ID |
hudu_create_asset_layout |
Create a new asset layout |
hudu_update_asset_layout |
Update an existing asset layout |
| Tool | Description |
|---|---|
hudu_list_asset_passwords |
List asset passwords |
hudu_get_asset_password |
Get an asset password by ID |
hudu_create_asset_password |
Create a new asset password |
hudu_update_asset_password |
Update an existing asset password |
hudu_delete_asset_password |
Delete an asset password |
| Tool | Description |
|---|---|
hudu_list_articles |
List knowledge base articles |
hudu_get_article |
Get an article by ID |
hudu_create_article |
Create a new article |
hudu_update_article |
Update an existing article |
hudu_delete_article |
Delete an article |
hudu_archive_article |
Archive an article |
| Tool | Description |
|---|---|
hudu_list_websites |
List monitored websites |
hudu_get_website |
Get a website by ID |
hudu_create_website |
Create a new website |
hudu_update_website |
Update an existing website |
hudu_delete_website |
Delete a website |
| Tool | Description |
|---|---|
hudu_list_folders |
List folders |
hudu_list_procedures |
List procedures |
hudu_list_activity_logs |
List activity logs |
hudu_list_relations |
List relations |
hudu_list_magic_dash |
List Magic Dash items |
| URI | Description |
|---|---|
hudu://companies |
List of all companies |
hudu://companies/{id} |
Company details by ID |
hudu://assets |
List of all assets |
hudu://assets/{id} |
Asset details by ID |
hudu://articles |
List of all articles |
hudu://articles/{id} |
Article details by ID |
# Install dependencies
npm install
# Build
npm run build
# Run in development mode
npm run dev
# Clean build output
npm run clean