员工数据管理服务

一个独立、生产就绪的MCP(模型上下文协议)服务器,用于通过Okta令牌验证安全访问员工数据,提供六种员工管理工具和三种传输选项(REST API、MCP HTTP、stdio)。

  • by indranilokg
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 indranilokg/okta-sample-employee-mcp-server

使用说明

Okta员工MCP服务器示例

一个独立的、生产就绪的MCP(模型上下文协议)服务器,用于员工数据访问,通过Okta令牌验证进行保护。

特征:

  • ✅ 对每个请求进行Okta令牌验证
  • ✅ 基于作用域的权限(mcp:读,mcp:写)
  • ✅ 6员工管理工具
  • ✅ 三种传输选项(REST API、MCP HTTP、stdio)
  • ✅ 通过Docker和Render部署为生产做好准备
  • ✅ 符合MCP规范

快速开始

先决条件

  • Python 3.9+
  • Okta租户与授权服务器
  • 有效的Okta令牌 mcp:read 或 mcp:write 范围

设置

# Install
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# Configure
cp env.template .env
# Edit .env with:
#   OKTA_DOMAIN=your-domain.okta.com
#   OKTA_AUTHORIZATION_SERVER_ID=your-auth-server-id

# Run
./start_server.sh
# Server runs on http://localhost:8001

可用工具

所有工具都需要 mcp:read 或 mcp:write 范围:

工具 描述 参数
list_employees 列出在职员工 status_filter (活动/非活动/全部)
get_employee_info 获取员工详细信息 employee_identifier (姓名或ID)
get_department_info 获取部门信息 department_name (可选)
get_benefits_info 获取福利信息 无
get_salary_info 获取工资级别 无
get_onboarding_info 获取入职流程 无

使用示例

1.REST API

列出工具:

curl -X GET http://localhost:8001/tools \
  -H "Authorization: Bearer $TOKEN"

呼叫工具:

curl -X POST http://localhost:8001/call_tool \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tool_name": "list_employees",
    "arguments": {"status_filter": "Active"}
  }'

答复:

{
  "result": {
    "employees": [
      {
        "employee_id": "EMP001",
        "name": "Jane Doe",
        "department": "Engineering",
        "title": "Senior Engineer",
        "manager": "John Smith",
        "status": "Active"
      }
    ],
    "total_count": 15,
    "status_filter": "Active"
  },
  "token_info": {
    "sub": "user@example.com",
    "scope": "mcp:read",
    "exp": 1704067200
  }
}

2.MCP流式HTTP(JSON-RPC)

初始化连接:

# Use -i to see response headers
curl -i -X POST http://localhost:8001/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "initialize",
    "params": {},
    "id": "1"
  }'

响应头 (保存Mcp会话Id):

HTTP/1.1 200 OK
mcp-session-id: 550e8400-e29b-41d4-a716-446655440000
content-type: application/json
...

提取会话ID(推荐):

# Extract and save session ID
SESSION_ID=$(curl -s -i -X POST http://localhost:8001/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":"1"}' \
  | grep -i "mcp-session-id" | awk '{print $2}' | tr -d '\r')

echo "Session ID: $SESSION_ID"

列出工具:

# Use the SESSION_ID from above
curl -X POST http://localhost:8001/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "id": "2"
  }'

呼叫工具:

curl -X POST http://localhost:8001/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "tool_name": "list_employees",
      "arguments": {"status_filter": "Active"}
    },
    "id": "3"
  }'

答复:

{
  "jsonrpc": "2.0",
  "result": {
    "employees": [
      {
        "employee_id": "EMP001",
        "name": "Jane Doe",
        "department": "Engineering",
        "title": "Senior Engineer",
        "manager": "John Smith",
        "status": "Active"
      }
    ],
    "total_count": 15,
    "status_filter": "Active"
  },
  "id": "3"
}

终止会话:

curl -X DELETE http://localhost:8001/mcp \
  -H "Mcp-Session-Id: $SESSION_ID"

3.标准运输(子流程)

启动服务器:

python -m mcp_server.stdio_transport

Python集成:

import subprocess
import json

# Start server
proc = subprocess.Popen(
    ["python", "-m", "mcp_server.stdio_transport"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True
)

def send_request(method, params=None):
    request = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params or {},
        "id": "1"
    }
    proc.stdin.write(json.dumps(request) + "\n")
    proc.stdin.flush()
    return json.loads(proc.stdout.readline())

# Initialize
response = send_request("initialize", {})
print(response)

# List tools
response = send_request("tools/list")
print(response)

# Call tool
response = send_request("tools/call", {
    "tool_name": "list_employees",
    "arguments": {"status_filter": "Active"}
})
print(response)

配置

.env 模板:

# REQUIRED: Your Okta domain
OKTA_DOMAIN=dev-12345.okta.com

# REQUIRED: Authorization Server ID
OKTA_AUTHORIZATION_SERVER_ID=employee-mcp-server

# OPTIONAL: Expected audience for token validation
# Leave empty to skip audience validation
OKTA_AUDIENCE=

# OPTIONAL: Server settings
PORT=8001
ENVIRONMENT=production
LOG_LEVEL=INFO

工作原理:

服务器自动从以下位置发现OAuth 2.0配置:

https://{OKTA_DOMAIN}/oauth2/{OKTA_AUTHORIZATION_SERVER_ID}/.well-known/oauth-authorization-server

这提供了:

  • JWKS URL(用于令牌签名验证)
  • 发卡机构(用于受众验证)
  • 所有OAuth 2.0端点

令牌要求

您的Okta代币必须具有:

  • 有效签名 (根据JWKS验证)
  • 未过期 (与exp索赔核对)
  • 范围正确 (mcp:读或mcp:在scp或范围声明中写)
  • 匹配观众 (如果设置了OKTA_AUDIENCE)

令牌示例:

{
  "scp": ["mcp:read"],
  "sub": "user@example.com",
  "aud": "https://mcp.streamward.com",
  "exp": 1704067200,
  "iss": "https://dev-12345.okta.com/oauth2/auss2..."
}

测试

健康检查

curl http://localhost:8001/health

REST API

export TOKEN="your_okta_token"

curl -X POST http://localhost:8001/call_tool \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tool_name": "list_employees", "arguments": {}}'

MCP HTTP

# Initialize (no auth)
curl -X POST http://localhost:8001/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "initialize", "params": {}, "id": "1"}'

# Get SESSION_ID from response header and use in next requests

标准

echo '{"jsonrpc":"2.0","method":"initialize","params":{},"id":"1"}' | \
python -m mcp_server.stdio_transport

故障排除

“MCP请求的令牌无效”

  • 令牌过期或签名无效
  • 检查令牌 jwt.io (不要在那里提交秘密)

“权限被拒绝”

  • 令牌没有 mcp:read 或 mcp:write 范围
  • 检查令牌 scp 索赔(Okta)或 scope 声明(OAuth)

“发现失败”

  • 检查OKTA_DOMAIN和OKTA_AUTHORIZION_SERVER_ID
  • 验证值是否与Okta设置匹配

服务器无法启动

  • 确保安装了依赖项: pip install -r requirements.txt
  • 检查端口8001是否尚未使用: lsof -i :8001

部署

码头工人

docker build -t okta-mcp .
docker run -p 8001:8001 \
  -e OKTA_DOMAIN=your-domain \
  -e OKTA_AUTHORIZATION_SERVER_ID=your-auth-server \
  okta-mcp

渲染

看 deployment/render.yaml 一键部署

手册

python -m uvicorn mcp_server.main:app --host 0.0.0.0 --port 8001

API文件

交互式API文档可在以下网址获取: http://localhost:8001/docs

运输比较

功能 REST API MCP HTTP stdio
符合标准 ❌ ✅ ✅
令牌验证 ✅ ✅ ⚠️
会话管理 ❌ ✅ ❌
网络就绪 ✅ ✅ ❌
IDE集成 ❌ ✅ ✅
克劳德桌面 ❌ ✅ ✅

根据您的用例进行选择:

  • REST API -定制集成、测试
  • MCP HTTP -标准MCP客户,生产
  • 标准 -Claude桌面,集成开发环境

MCP兼容性

此服务器与标准MCP客户端完全兼容:

  • ✅ langchain mcp适配器
  • ✅ 克劳德桌面版
  • ✅ Cline/Cursor集成
  • ✅ continue.dev
  • ✅ 所有符合规范的MCP客户端

工具定义遵循MCP规范,并具有适当的 inputSchema 参数验证字段。

许可证

请参阅许可证文件

支持

有关问题或疑问,请参阅: