Skip to main content
Glama

nable-passportal-mcp

A stateless HTTP MCP service for the N-able Passportal Documents API. It exposes Passportal API v2 operations as Model Context Protocol (MCP) tools consumable by Claude and other MCP clients.

服务介绍

  • Stateless — 不保存任何用户状态或会话数据,请求之间完全隔离;仅在进程内缓存派生出的短期 access token(见下文"认证")。

  • Concurrent-safe — 每请求的凭据与实例 base URL 通过 Python contextvars 隔离,并发请求之间绝不串号。

  • 多租户 — 每个请求自带 Passportal Access Key / Secret Access Key 与客户实例 base URL(gateway 模式),单个服务实例即可服务多个 Passportal 客户。

  • 认证 — Passportal 用的是 OAuth2 client-credentials、HMAC 签名的授权方式:本服务用长期的 Access Key / Secret Access Key 对,自己向 Passportal 换取短期(约 55 分钟)access token 并按租户缓存,调用方无需关心 HMAC 计算或 token 续期。凭据通过 x-passportal-access-key / x-passportal-secret-key 两个 Header 传入,x-passportal-base-url 传入客户实例地址。

上游 API 参考:

Related MCP server: Paperless MCP

Endpoints

Method

Path

Description

POST

/mcp

MCP protocol entry point

GET

/health

Health check

默认端口:8080(通过 MCP_HTTP_PORT 配置)。

HEADER 授权参数说明

Gateway 模式(默认、生产、SOP 合规)下,每个 /mcp 请求必须携带以下 Header:

x-passportal-access-key

项目

说明

类型

string

是否必填

必填

默认值

枚举值

字段描述

Passportal Access Key(对应授权请求里的 x-key),在 Passportal 门户生成。

Example

x-passportal-access-key: 11111111111111111111111111111111

x-passportal-secret-key

项目

说明

类型

string

是否必填

必填

默认值

枚举值

字段描述

Passportal Secret Access Key。本服务在进程内用它对每次 token 交换请求做 HMAC-SHA256 签名(x-hash),从不持久化、不转发给 Passportal 之外的任何地方。

Example

x-passportal-secret-key: 22222222222222222222222222222222

x-passportal-base-url

项目

说明

类型

string

是否必填

必填

默认值

枚举值

字段描述

客户 Passportal 实例的 Base URL(dashboard 地址的根,不含尾部 /)。例如 dashboard 为 https://instance.passportalmsp.com//dashboard#/default,则此处填 https://instance.passportalmsp.com

Example

x-passportal-base-url: https://instance.passportalmsp.com

缺少任一 Header 时,/mcp 请求返回 401,响应体的 required_headers 会列出所需的三个 Header 名。

内部授权流程(自动完成,调用方无需关心)

本服务收到上述三个 Header 后,在真正调用 Documents API 之前,会自动:

  1. 生成一段随机明文 content,用 Secret Access Key 对其计算 HMAC-SHA256 签名得到 x-hash(hex 编码)。

  2. POST {base_url}/api/v2/auth/client_token,Header 带 x-key(=Access Key)、x-hash,body 带 { "scope": "docs_api", "content": "<同一段明文>" },换回 access_token 与过期时间 expiry_time

  3. 用换到的 access_token 作为 x-access-token Header 调用真正的 Documents API(如 GET /api/v2/documents)。

  4. (base_url, access_key, secret_key) 的指纹在进程内缓存该 access_token,直到临近 expiry_time(默认无返回时按 55 分钟兜底)才重新走一次上述交换——避免每次工具调用都重新签名换 token。

调用方全程只需要提供 Access Key / Secret Access Key / base URL 这三项静态凭据,HMAC 计算、token 交换与续期均由本服务完成。

Tool List

passportal_list_documents

List documents from N-able Passportal —GET <base_url>/api/v2/documents。全部参数均为可选。

参数

类型

必填

枚举值

说明

resultsPerPage

integer

每页返回的结果数(正整数)。

pageNum

integer

页码 / 索引(正整数)。

orderBy

string

label, id

排序字段。

orderDir

string

asc, desc

排序方向。

type

string

asset, active_directory, application, backup, email, file_sharing, contact, location, internet, lan, printing, remote_access, vendor, virtualization, voice, wireless, licencing, custom, ssl

模板类型过滤。

templateUid

string

按具体模板过滤,接受 UID 或 ID(如 tpl-101101)。

clientId

integer

客户标识过滤。

searchTxt

string

基于文档属性的全文搜索。

响应为 Passportal 原始 JSON,结构大致为:

{
  "success": true,
  "apiRequestUid": "string",
  "results": [
    {
      "id": 0,
      "organization_id": 0,
      "label": "string",
      "description": "string",
      "client_id": 0,
      "customId": "string",
      "templateId": 0,
      "templateName": "string",
      "type": "string"
    }
  ],
  "description": "string"
}

Configuration

Variable

Required

Default

Description

AUTH_MODE

No

gateway

gateway(每请求 Header,SOP 合规)或 env(共享凭据,仅本地开发)。

PASSPORTAL_ACCESS_KEY_HEADER

No

x-passportal-access-key

gateway 模式下携带 Access Key 的 Header 名。

PASSPORTAL_SECRET_KEY_HEADER

No

x-passportal-secret-key

gateway 模式下携带 Secret Access Key 的 Header 名。

PASSPORTAL_BASE_URL_HEADER

No

x-passportal-base-url

gateway 模式下携带实例 base URL 的 Header 名。

PASSPORTAL_TOKEN_SCOPE

No

docs_api

token 交换请求的 scope,由 Passportal Documents API 固定,一般无需修改。

PASSPORTAL_ACCESS_KEY

env mode only

env 模式下使用的 Passportal Access Key。

PASSPORTAL_SECRET_KEY

env mode only

env 模式下使用的 Passportal Secret Access Key。

PASSPORTAL_BASE_URL

env mode only

env 模式下的客户实例 base URL,如 https://instance.passportalmsp.com

MCP_TRANSPORT

No

http

传输方式:httpstdio

MCP_HTTP_PORT

No

8080

HTTP 监听端口。

MCP_HTTP_HOST

No

0.0.0.0

HTTP 监听地址。

env 模式(仅本地开发,非生产 SOP 合规):设置 AUTH_MODE=envPASSPORTAL_ACCESS_KEYPASSPORTAL_SECRET_KEYPASSPORTAL_BASE_URL,所有请求共享同一凭据,切勿用于生产 / 多租户。

Quick Start

HTTP server (gateway mode — 默认,SOP 合规)

uv sync
uv run nable-passportal-mcp
# 每请求通过 x-passportal-access-key + x-passportal-secret-key + x-passportal-base-url
# Header 传入凭据与实例地址;本服务内部自动完成 HMAC 签名与 token 交换/续期

HTTP server (env mode — 仅本地开发)

cp .env.example .env
# 编辑 .env:AUTH_MODE=env、PASSPORTAL_ACCESS_KEY=...、PASSPORTAL_SECRET_KEY=...、
#           PASSPORTAL_BASE_URL=https://<instance>.passportalmsp.com
uv sync
uv run nable-passportal-mcp
# 服务启动于 http://0.0.0.0:8080

Docker

docker compose up --build

Test Examples

Health check

curl http://localhost:8080/health

预期响应:

{"status": "ok", "transport": "http", "auth_mode": "gateway"}

Initialize(MCP 握手)

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "x-passportal-access-key: your_access_key" \
  -H "x-passportal-secret-key: your_secret_access_key" \
  -H "x-passportal-base-url: https://instance.passportalmsp.com" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {"name": "curl", "version": "1.0"}
    }
  }'

List tools

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "x-passportal-access-key: your_access_key" \
  -H "x-passportal-secret-key: your_secret_access_key" \
  -H "x-passportal-base-url: https://instance.passportalmsp.com" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}'

Call passportal_list_documents

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "x-passportal-access-key: your_access_key" \
  -H "x-passportal-secret-key: your_secret_access_key" \
  -H "x-passportal-base-url: https://instance.passportalmsp.com" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "passportal_list_documents",
      "arguments": {
        "resultsPerPage": 20,
        "pageNum": 1,
        "orderBy": "label",
        "orderDir": "asc",
        "type": "asset"
      }
    }
  }'

第一次调用会先触发一次内部 HMAC token 交换(略增延迟),后续约 55 分钟内的调用复用缓存的 access token。

Security

  • 每请求的 Access Key / Secret Access Key / base URL 存放于 contextvars.ContextVar,请求结束后立即 reset,绝不跨租户串号。

  • 换来的短期 access token(约 55 分钟有效期)按 (base_url, access_key, secret_key) 指纹在进程内缓存,纯为避免每次工具调用都重新做一次 HMAC 签名 + 网络往返;缓存只存派生出的短期 token,不存 Secret Access Key 本身,也不落盘、不跨进程持久化。

  • Secret Access Key 只在进程内用于计算 x-hashauth.py::compute_x_hash),从不被记录到日志,也不会转发给 Passportal 之外的任何地方。

  • 容器以非 root 用户运行。

  • 切勿提交真实 Access Key / Secret Access Key —— .gitignore 已排除 .env

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MSPbotsAI/nable-passportal-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server