CustomerIQ-Agent
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CustomerIQ-AgentWhat's the churn risk for CUST-000042, and what does our retention policy say?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
CustomerIQ-Agent — MCP Server Tying Projects 1-3 Together
Project 4 of the CustomerIQ portfolio — an MCP (Model Context Protocol) server that exposes Project 1's churn risk model, Project 2's ticket classifier, and Project 3's RAG document Q&A as callable tools, so any MCP-aware AI client (Claude Desktop, Claude Code, or a custom agent) can orchestrate all three in one conversation.
What is MCP, in one paragraph
MCP is an open protocol (originally introduced by Anthropic) that standardizes how an LLM client connects to external tools and data sources — instead of every AI application writing custom, one-off integrations for every tool, an MCP server exposes a set of tools with typed schemas over a standard protocol, and any MCP-compatible client can discover and call them the same way. This project is an MCP server: it doesn't call an LLM itself (except indirectly, inside Project 3's RAG pipeline) — it exposes capabilities for an LLM client to call.
Related MCP server: Works With Agents MCP Server
Why this project depends on Projects 1-3 (not duplicates them)
This is the concrete implementation of "make each project depend on the other" from the original
plan. Project 4 contains no model training or document ingestion code of its own — it loads
the already-trained artifacts Projects 1-3 produce (churn_model.joblib,
tfidf_baseline.joblib, rag_index.joblib) directly from their sibling folders, assuming the
standard layout:
AI-ML-CAREER/projects/
project-01-tabular-ml/
project-02-nlp-text-classification/
project-03-rag-document-qa/
project-04-mcp-agent/ <- this projectIf you run Project 4 before building Projects 1-3's artifacts, each tool raises a clear
FileNotFoundError naming exactly which command to run first — see tools.py's
_require_artifact().
The three tools
Tool | Backed by | Input | Output |
| Project 1 (XGBoost) |
| churn probability + risk tier |
| Project 2 (TF-IDF + LogReg) |
| category + confidence |
| Project 3 (RAG) |
| grounded answer + sources, or a refusal |
Project structure
project-04-mcp-agent/
├── src/project_04_agent/
│ ├── config.py # resolves sibling-project artifact paths (env-var overridable)
│ ├── tools.py # framework-independent tool logic (unit-testable directly)
│ └── server.py # MCP wiring: @mcp.tool() decorators around tools.py
├── scripts/
│ └── demo_client.py # a real MCP client that launches the server and calls its tools
└── tests/
└── test_tools.py # tests the tool logic directly (skipped if artifacts are missing)Setup & usage (Windows / PowerShell, using uv)
Prerequisite: Projects 1, 2, and 3 must already be built (their models/index exist on disk). If you haven't run them recently:
cd ..\project-01-tabular-ml; uv run python scripts/run_pipeline.py; cd ..\project-04-mcp-agent
cd ..\project-02-nlp-text-classification; uv run python scripts/run_baseline.py; cd ..\project-04-mcp-agent
cd ..\project-03-rag-document-qa; uv run python scripts/run_ingest.py; cd ..\project-04-mcp-agentThen set up Project 4 itself:
cd project-04-mcp-agent
uv init
uv add "mcp>=2" joblib pandas scikit-learn xgboost
uv run pytest tests/ -q # unit tests against the real cross-project artifacts
uv run python scripts/demo_client.py # real MCP client<->server demo, no external app neededA version note worth knowing (I hit this myself)
The mcp package went through a breaking API change: in mcp 1.x, the server class was called
FastMCP (from mcp.server.fastmcp import FastMCP). As of mcp 2.x, it's renamed to
MCPServer (from mcp.server.mcpserver import MCPServer) with some parameter changes. This
project targets mcp>=2. If uv add mcp gives you a 1.x version for some reason, either
uv add "mcp>=2" explicitly, or swap the import in server.py back to the 1.x form — I'd
recommend actually hitting this error once yourself and fixing it, rather than just reading this
note, since "a dependency's API changed between versions" is an extremely common real-world
debugging scenario worth having practiced.
Connecting to Claude Desktop / Claude Code
Add this to your MCP client's config (e.g. Claude Desktop's claude_desktop_config.json):
{
"mcpServers": {
"customeriq-agent": {
"command": "uv",
"args": ["run", "--directory", "C:\\Users\\Dell\\AI-ML-CAREER\\projects\\project-04-mcp-agent", "python", "src/project_04_agent/server.py"]
}
}
}After restarting the client, you should be able to ask things like "What's the churn risk for CUST-000042, and if it's high, what does our retention policy say we can offer them?" — a question that genuinely requires two of the three tools.
Verified results (Phase 1)
Tested through the real MCP protocol (tool discovery + tool calls via mcp.client.stdio, the
same mechanism Claude Desktop uses), not mocked:
churn_risk_score("CUST-000000")→{"found": true, "churn_probability": 0.1886, "risk_tier": "low"}support_ticket_category("My internet keeps disconnecting...")→{"category": "technical_issue", "confidence": 0.87}policy_question("What happens if I miss a payment?")→ grounded answer citing the Billing Policypolicy_question("What's the weather today?")→ correctly refused (Project 3's hallucination mitigation carries through end-to-end via MCP)
5/5 unit tests pass against the real cross-project artifacts.
Design decisions worth mentioning in an interview
Why separate
tools.pyfromserver.py? The MCP framework wrapping is a thin decorator layer; the actual logic is plain, framework-independent Python that's unit-testable with ordinary pytest and reusable behind a REST API or CLI if MCP weren't the chosen integration layer — the same "business logic separate from framework" principle assklearn.Pipelineobjects intools.py(Project 1) orRAGPipelinein Project 3.Why load artifacts via
sys.pathinsertion instead of pip-installing each project as a package? Simplicity for a portfolio project — each project stays independently runnable and clonable without a shared packaging/publishing step. In a real production system you'd likely package Projects 1-3 as proper installable libraries (or serve them behind their own APIs) and have Project 4 depend on them as normal dependencies rather than reaching into sibling folders.Why
lru_cacheon the model/pipeline loaders? Loading a joblib model or rebuilding the RAG pipeline is relatively expensive; an MCP server handles many tool calls over its lifetime, so loading once and reusing avoids redundant disk I/O and deserialization on every call.Why does the RAG tool default to
MockLLMClient? Consistent with Project 3: the whole platform should be runnable and testable with zero API keys configured. Swapping toAnthropicLLMClientfor real answer synthesis is a one-line change intools.py.
What's next (Phase 2 — complexity increase, on request)
A fourth tool that combines all three: given a
customer_id, look up risk score, find their most recent support ticket's category, and retrieve the relevant retention policy — a genuine multi-tool agentic workflow in one call.Real LLM backend for the RAG tool (swap
MockLLMClient→AnthropicLLMClient)Streamable-HTTP transport (instead of stdio) so the server could run remotely, not just locally spawned by the client
Input validation / guardrails on tool arguments (e.g. reject a
customer_idthat doesn't match the expected format before ever touching the model)Structured logging of every tool call (what was asked, what was returned, latency) for basic observability — the kind of thing a real deployed agent needs
The complete CustomerIQ portfolio
# | Project | Concepts |
1 | CustomerIQ-Risk | Tabular ML: EDA, leakage-safe pipelines, XGBoost, SHAP |
2 | CustomerIQ-Voice | NLP: TF-IDF, PyTorch embeddings, overfitting |
3 | CustomerIQ-Docs | GenAI: RAG, vector search, hallucination mitigation |
4 | CustomerIQ-Agent | Modern AI tooling: MCP, cross-project orchestration |
Four repos, one coherent narrative, each depending on the last — built and verified end-to-end, not just scaffolded.
Available Tools
3 toolschurn_risk_scoreB
Look up a customer's churn risk score (Project 1: tabular ML model).
Args:
customer_id: Customer id in "CUST-XXXXXX" format, e.g. "CUST-000042".
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'Look up' implies a read-only operation, and naming the model type adds slight context, but it says nothing about what the score means, its range, whether it is cached/stale, latency, or error behavior. For a scoring tool with zero annotation coverage, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then the single argument with its format and example. No filler sentences. The 'Args:' block is a reasonable structure for a one-parameter tool, though slightly formal for such a short description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description is the only place to explain the return value, and it never says what the churn risk score looks like (range, units, interpretation). For a minimal single-parameter lookup it is mostly sufficient to call correctly, but the result is unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema only labels the field 'Customer Id', so the description must compensate. It does: it specifies the required format 'CUST-XXXXXX' and supplies a concrete example 'CUST-000042', which is exactly the information needed to form a valid call.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Look up a customer's churn risk score'. It further identifies the underlying model ('Project 1: tabular ML model'). It does not position itself against siblings, but the siblings (support_ticket_category, policy_question) are unrelated lookups so differentiation is not really needed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus the other lookups or any alternative. There are no prerequisites, no exclusions, and no indication of the context in which churn scoring is appropriate (e.g., during retention workflows).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
policy_questionB
Answer a question grounded in company policy documents (Project 3: RAG).
Args:
question: A natural-language question about billing, cancellation,
technical support, or account security policy.
| Name | Required | Description | Default |
|---|---|---|---|
| question | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does not disclose whether answers are cached, whether the policy corpus is fixed or updated, whether the call has latency/cost implications from RAG retrieval, or what happens with out-of-domain questions. '(Project 3: RAG)' names a mechanism but conveys nothing actionable about behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core sentence is front-loaded and efficient, but the 'Args:' block reads like a docstring leaking into the description and the '(Project 3: RAG)' parenthetical adds internal-context noise without agent value. Roughly half the content earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-annotation tool with a 0%-coverage schema and no output schema, the description should explain the return shape (text answer? citations? confidence?) and domain boundaries. It instead borrows structure from a Python docstring, leaving the agent guessing about output and failure modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does list acceptable question domains (billing, cancellation, technical support, account security). That is useful scoping for the single 'question' param, but it stops short of syntax, format, or length guidance. Marginal but real value over the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: answering a question grounded in company policy documents. The parenthetical '(Project 3: RAG)' hints at the retrieval mechanism but is cryptic internal scaffolding rather than useful differentiation. It does distinguish the tool from siblings churn_risk_score and support_ticket_category, which are classification/scoring tools rather than Q&A.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly scopes usage by naming policy domains (billing, cancellation, technical support, account security), which tells the agent what kinds of questions belong here. However, it offers no explicit when-to-use vs alternatives guidance, no exclusion of churn_risk_score or support_ticket_category, and no prerequisites. Implied usage only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
support_ticket_categoryB
Classify a support ticket's category (Project 2: NLP text classifier).
Args:
ticket_text: The raw customer support ticket text.
| Name | Required | Description | Default |
|---|---|---|---|
| ticket_text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It says this is an NLP text classifier, but does not describe output format, returned categories, confidence, permissions, rate limits, or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the core action. The parenthetical project identifier adds little, and the Args block is functional but slightly noisy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a classifier with one input, no output schema, and no annotations, the description is thin. It does not explain what categories are returned, what the output looks like, or when the tool should be used.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the single parameter. It does so by explaining that ticket_text is the raw customer support ticket text, which is more meaningful than the schema's bare 'Ticket Text' title.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: classify a support ticket's category. It also identifies the tool as an NLP text classifier. It does not explicitly distinguish itself from siblings churn_risk_score or policy_question, but the purpose is still clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives. It does not mention the sibling tools, prerequisites, or conditions that select this classifier over churn risk scoring or policy question answering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
churn_risk_score - First observed
policy_question - First observed
support_ticket_category
TDQS
Scored across 3 tools
Each tool targets a clearly distinct task: churn risk scoring, support ticket classification, and policy Q&A. There is no overlap in purpose or inputs, so an agent can easily select the correct tool.
All names use consistent snake_case and are descriptive noun phrases, which is readable and predictable. However, they do not follow the common verb_noun action pattern, so the convention is consistent but not action-oriented.
Three tools map cleanly to three distinct underlying capabilities (tabular ML, NLP classifier, RAG). The count is well-scoped and each tool earns its place without redundancy.
The surface covers the three stated project functions, but lacks supporting operations like customer lookup, ticket history, or score explanation. These are minor gaps that an agent could work around for the core tasks.
Maintenance
Related MCP Connectors
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
One MCP endpoint for Claude, GPT & Gemini: 100+ tools + no-code connectors + agent workers.
Let AI agents query data and act across all your business apps via MCP.
Operator-as-agent MCP hub. 6 tools. First $5 free, then $0.001/call.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceExposes RAG and document intelligence pipelines as 8 composable tools for MCP-compatible clients, enabling querying, indexing, classifying, extracting, and assessing documents.1MIT
- AlicenseAqualityFmaintenanceProvides 14 MCP tools for AI agent infrastructure, enabling knowledge base queries, skill search, handoffs, blueprint validation, trust scoring, identity verification, SLA validation, and compliance checks.22MIT
- AlicenseNot gradedqualityBmaintenanceExposes order status lookup and knowledge base search tools from the Support Agent AI over MCP, enabling MCP clients to handle customer support queries with grounded, citation-backed answers.MIT
- AlicenseNot gradedqualityCmaintenanceEnables an AI to perform customer support workflows by looking up customers, retrieving orders, and creating support tickets through MCP tools.4 npmX11 no permit persons clause