loading…
Search for a command to run...
loading…
Enables querying client onboarding status and basic client info (name, family) via two tools, designed for integration with Microsoft Copilot and Teams.
Enables querying client onboarding status and basic client info (name, family) via two tools, designed for integration with Microsoft Copilot and Teams.
Minimal Python 3.12 project with:
Architecture:
[Microsoft Teams]
|
v
[Microsoft Copilot]
|
v
[MCP Server]
|
v
[Mock Backend Server]
.
|-- appPackage/
| |-- adaptive-cards/
| | `-- client-result.json
| |-- color.png
| |-- declarativeAgent.json
| |-- manifest.json
| |-- mcp-tools.json
| |-- openapi.yaml
| |-- outline.png
| |-- plugin.json
| `-- plugin.openapi.json
|-- examples/
| |-- curl.md
| |-- json-rpc.md
| |-- requests.http
| `-- responses/
| |-- basic_info_family.json
| |-- basic_info_name.json
| |-- auth_failed.json
| |-- auth_required.json
| |-- auth_success.json
| |-- error_invalid_field.json
| |-- facility_limit.json
| |-- onboarding_status.json
| `-- outreach_summary.json
|-- mcp_server/
| |-- __init__.py
| |-- __main__.py
| |-- app.py
| |-- auth.py
| |-- backend_client.py
| |-- config.py
| |-- errors.py
| |-- jsonrpc.py
| |-- logging_config.py
| |-- mcp_app.py
| |-- models.py
| |-- routes.py
| |-- session.py
| `-- tool_registry.py
|-- mock_backend/
| |-- __init__.py
| |-- __main__.py
| |-- app.py
| |-- config.py
| |-- logging_config.py
| |-- models.py
| `-- routes.py
|-- tests/
| |-- conftest.py
| |-- test_backend.py
| |-- test_mcp_http.py
| `-- test_tool_registry.py
|-- .env.example
|-- .vscode/launch.json
|-- Dockerfile
|-- docker-compose.yml
|-- main.py
|-- openapi.yaml
|-- pytest.ini
|-- requirements.txt
`-- tools.json
The MCP exposes these five tools.
Input:
{
"client_id": "123",
"otp": "9632"
}
Successful output:
{
"authenticated": true,
"client_id": "123",
"message": "Authentication successful"
}
Failed output:
{
"authenticated": false,
"message": "Invalid OTP"
}
Business tools use the authenticated client_id stored in the MCP session. For local HTTP tests, keep the same x-mcp-session-id header across calls.
Input:
{}
Output:
{
"client_id": "123",
"status": "Completed",
"message": "Client onboarding completed successfully"
}
Input:
{
"field": "name"
}
Allowed field values:
namefamilyOutput:
{
"client_id": "123",
"field": "name",
"value": "John"
}
{
"client_id": "123",
"field": "family",
"value": "Doe"
}
Input:
{}
Output:
{
"client_id": "123",
"client_name": "John Doe",
"facility_limit_eur": 75000000,
"currency": "EUR",
"formatted_limit": "EUR 75,000,000"
}
Input:
{}
Output includes the outreach reasons, highlights, and total questions to answer:
{
"client_id": "123",
"client_name": "John Doe",
"outreach_count": 2,
"questions_to_answer_count": 5,
"reasons": ["Annual facility review", "Updated cash-flow forecast"],
"summary": "John Doe has 2 outreach items. Reasons: Annual facility review, Updated cash-flow forecast. You should answer 5 questions in total."
}
Use Python 3.12.
python -m venv .venv312
.venv312\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
Terminal 1:
uvicorn mock_backend.app:app --host 0.0.0.0 --port 8001 --reload
Terminal 2:
uvicorn mcp_server.app:app --host 0.0.0.0 --port 8000 --reload
Health checks:
curl http://localhost:8001/health
curl http://localhost:8000/health
OpenAPI 3.1 schema:
openapi.yamlhttp://localhost:8000/openapi.jsonhttp://localhost:8000/openapi.yamlEndpoints:
curl -X POST http://localhost:8000/api/v1/authenticate \
-H "Content-Type: application/json" \
-H "x-mcp-session-id: demo-session" \
-d '{"client_id":"123","otp":"9632"}'
curl http://localhost:8000/api/v1/client/onboarding-status -H "x-mcp-session-id: demo-session"
curl http://localhost:8000/api/v1/client/basic-info/name -H "x-mcp-session-id: demo-session"
curl http://localhost:8000/api/v1/client/facility -H "x-mcp-session-id: demo-session"
curl http://localhost:8000/api/v1/client/outreach-summary -H "x-mcp-session-id: demo-session"
curl http://localhost:8000/api/v1/clients/123/onboarding-status
curl http://localhost:8000/api/v1/clients/123/basic-info/name
curl http://localhost:8000/api/v1/clients/123/basic-info/family
curl http://localhost:8000/api/v1/clients/123/facility
curl http://localhost:8000/api/v1/clients/123/outreach-summary
List tools:
curl -X POST http://localhost:8000/mcp ^
-H "Content-Type: application/json" ^
-H "x-mcp-session-id: demo-session" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}"
Authenticate first:
curl -X POST http://localhost:8000/mcp ^
-H "Content-Type: application/json" ^
-H "x-mcp-session-id: demo-session" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"authenticate_client\",\"arguments\":{\"client_id\":\"123\",\"otp\":\"9632\"}}}"
Then call business tools with the same session ID and no client_id argument:
curl -X POST http://localhost:8000/mcp ^
-H "Content-Type: application/json" ^
-H "x-mcp-session-id: demo-session" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"get_client_onboarding_status\",\"arguments\":{}}}"
The MCP Python SDK registration is in mcp_server/mcp_app.py. For stdio-style MCP testing:
python -m mcp_server.mcp_app
The mock backend is a separate FastAPI service and returns hardcoded data only.
curl http://localhost:8001/status/123
curl http://localhost:8001/info/123/name
curl http://localhost:8001/info/123/family
curl http://localhost:8001/facility/123
curl http://localhost:8001/outreach/123/summary
MCP client-session authentication is enabled in the tool flow:
authenticate_clientclient_id, otp9632x-mcp-session-id or mcp-session-id header for HTTP testsIf a business tool is called before authentication, the MCP tool returns:
{
"error": "AUTH_REQUIRED",
"message": "Please authenticate first using client_id and OTP"
}
Production replacement points are marked in session.py:
API key validation is intentionally disabled for local development. This is separate from the MCP client-session authentication tool.
Enable API key validation:
MCP_AUTH_REQUIRED=true
MCP_API_KEY_HEADER=x-api-key
MCP_API_KEY=local-dev-key
Then call:
curl http://localhost:8000/api/v1/clients/123/onboarding-status -H "x-api-key: local-dev-key"
Production replacement points:
APIKeyAuthMiddleware with Microsoft Entra ID JWT validation.docker compose up --build
Services:
http://localhost:8000http://localhost:8001Package files are in appPackage/.
manifest.json: Microsoft 365/Teams app manifestdeclarativeAgent.json: declarative agent manifestplugin.json: Microsoft 365 Copilot plugin manifest using RemoteMCPServerplugin.openapi.json: OpenAPI fallback plugin manifestmcp-tools.json: MCP tool discovery metadata mirror of the inline plugin metadataopenapi.yaml: OpenAPI schema for the REST facadecolor.png and outline.png: Teams package iconsBefore packaging:
appPackage/plugin.json, appPackage/openapi.yaml, and appPackage/manifest.json if you move away from the current Railway URL.appPackage/manifest.json with a real package ID before production publishing.appPackage/, not the folder itself.Example Copilot prompts:
ngrok http 8000
https://abc123.ngrok-free.app.appPackage/manifest.json, appPackage/plugin.json, and appPackage/openapi.yaml.This project is packaged as a Copilot declarative agent. It does not implement a Bot Framework message handler.
Invalid basic info field through REST:
curl http://localhost:8000/api/v1/clients/123/basic-info/age
Response shape:
{
"error": {
"code": "validation_error",
"message": "Request validation failed.",
"details": []
}
}
Invalid MCP tool call:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_client_basic_info",
"arguments": {
"field": "age"
}
}
}
Response shape:
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32602,
"message": "Tool arguments failed validation.",
"data": {
"code": "invalid_arguments",
"details": []
}
}
}
Both services log requests with method, path, status code, and elapsed time.
Log levels:
MCP_LOG_LEVEL=INFO
BACKEND_LOG_LEVEL=INFO
pytest -q
Tests cover:
tools/listtools/callREST endpoints are versioned under /api/v1.
Recommended evolution:
/api/v1 stable for existing Copilot plugins./api/v2 for breaking response or parameter changes.operationId values aligned with Copilot plugin function names.v2.4.v1.22.Выполни в терминале:
claude mcp add client-onboarding-mcp -- npx Да, Client Onboarding MCP бесплатный — установка в один клик через Unyly без оплаты.
Нет, Client Onboarding работает без API-ключей и переменных окружения.
Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.
Открой Client Onboarding на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
CSA PROJECT - FZCO © 2026 IFZA Business Park, DDP, Premises Number 31174 - 001
Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.