Metadata-Version: 2.4
Name: mcp-vos-auth
Version: 0.1.0
Summary: Token validation middleware for FastMCP tools
Project-URL: Repository, https://github.com/vinehoo/mcp-vos-auth
Author: vber
License: MIT
License-File: LICENSE
Keywords: authentication,fastmcp,mcp,middleware
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: fastmcp<4,>=2.11
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pip>=26.1.2
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.24; extra == 'test'
Requires-Dist: pytest>=8; extra == 'test'
Description-Content-Type: text/markdown

# mcp-vos-auth

用于 FastMCP 的工具调用 token 校验 middleware。它在工具执行前读取工具名、参数和
`token` 参数，通过 Vinehoo `check_token` 接口验证 token；验证失败时工具返回“无权限”。

## 安装

### 通过 PyPI 安装

```bash
pip install mcp-vos-auth
```

### 不通过 pip 使用

无论采用下面哪种方式，目标项目都必须提供本包的运行依赖：

```bash
pip install fastmcp httpx
```

#### 方式一：设置 `PYTHONPATH`（本地多项目开发推荐）

将本项目的 `src` 目录加入 Python 模块搜索路径：

```bash
export PYTHONPATH="/path/to/mcp-vos-auth/src:$PYTHONPATH"
python your_server.py
```

例如本仓库位于 `/Users/vber/Documents/codes/mcp-vos-auth` 时：

```bash
export PYTHONPATH="/Users/vber/Documents/codes/mcp-vos-auth/src:$PYTHONPATH"
python your_server.py
```

目标项目不需要修改导入语句：

```python
from mcp_vos_auth import register_token_auth
```

`PYTHONPATH` 只对当前终端会话有效。需要长期使用时，可将 `export` 命令加入 shell 配置，
或写入项目的启动脚本。

#### 方式二：在程序入口添加源码路径（仅建议临时调试）

```python
import sys

sys.path.insert(0, "/path/to/mcp-vos-auth/src")

from mcp_vos_auth import register_token_auth
```

这种方式会把本机绝对路径写入业务代码，不适合多人协作或生产部署。

#### 方式三：将包源码复制到目标项目

把本仓库的 `src/mcp_vos_auth` 目录完整复制到目标项目根目录：

```text
your-project/
├── your_server.py
└── mcp_vos_auth/
    ├── __init__.py
    └── middleware.py
```

然后正常导入：

```python
from mcp_vos_auth import register_token_auth
```

该方式部署简单，但复制后的源码不会自动同步本仓库后续的修复和升级，需要自行维护版本。

以上三种方式都不需要安装 `mcp-vos-auth` 本身。对于本地联调，优先使用 `PYTHONPATH`；
对于需要固定源码且不使用包管理的部署，可复制 `mcp_vos_auth` 目录。

## 使用

```python
from fastmcp import FastMCP
from mcp_vos_auth import register_token_auth

mcp = FastMCP("protected-server")

# 自动创建 middleware 并注册到当前 FastMCP 实例。
register_token_auth(mcp, platform="app")

@mcp.tool
def get_order(order_id: int, token: str) -> dict:
    return {"order_id": order_id}

if __name__ == "__main__":
    mcp.run()
```

不传 `platform` 时校验中台用户：

```python
register_token_auth(mcp)
```

默认保护所有工具。可排除公开工具，或只保护指定工具：

```python
register_token_auth(mcp, excluded_tools={"health", "version"})
# 或
register_token_auth(mcp, protected_tools={"get_order", "delete_order"})
```

其他配置：

```python
register_token_auth(
    mcp,
    token_parameter="access_token",
    timeout=3.0,
    unauthorized_message="无权限",
)
```

如果工具使用 Pydantic 模型等嵌套参数，可以用点路径指定 token 的位置：

```python
@mcp.tool
async def submit_feedback(params: SubmitFeedbackInput) -> str:
    ...

register_token_auth(mcp, token_parameter="params.token")
```

`on_validation` 回调可获取工具名、完整工具参数和标准化校验结果。请勿在日志中记录完整
token：

```python
async def audit(tool_name, arguments, result):
    print(tool_name, result.valid, result.data)

register_token_auth(mcp, on_validation=audit)
```

安全策略为 fail-closed：缺少 token、HTTP 401、`error_code != 0`、响应格式异常、网络错误
或超时都会阻止工具执行。token 参数仍会传给工具函数；如工具不需要使用它，可以保留该
参数但不要记录或返回它。

## 构建和发布

```bash
python -m pip install build twine
python -m build
twine check dist/*
twine upload dist/*
```

发布前请在 `pyproject.toml` 中确认包名、作者、Repository URL 和版本号。

## 测试

```bash
python -m pip install -e '.[test]'
pytest
```
