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
| |-- 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
| `-- 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 four tools.
Input:
{
"client_id": "123"
}
Output:
{
"client_id": "123",
"status": "Completed",
"message": "Client onboarding completed successfully"
}
Input:
{
"client_id": "123",
"field": "name"
}
Allowed field values:
namefamilyOutput:
{
"client_id": "123",
"field": "name",
"value": "John"
}
{
"client_id": "123",
"field": "family",
"value": "Doe"
}
Input:
{
"client_id": "123"
}
Output:
{
"client_id": "123",
"client_name": "John Doe",
"facility_limit_eur": 75000000,
"currency": "EUR",
"formatted_limit": "EUR 75,000,000"
}
Input:
{
"client_id": "123"
}
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 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" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}"
Call tool:
curl -X POST http://localhost:8000/mcp ^
-H "Content-Type: application/json" ^
-d "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"get_client_onboarding_status\",\"arguments\":{\"client_id\":\"123\"}}}"
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
Authentication is intentionally disabled for local development.
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 real Microsoft Entra app and bot registration IDs.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 includes bot manifest placeholders but does not implement a Bot Framework message handler. Copilot calls the MCP server/plugin action; the bot block is present for Teams app packaging and future Teams conversational extensions.
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": {
"client_id": "123",
"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.27.Run in your terminal:
claude mcp add client-onboarding-mcp -- npx