customer-data-mcp
mcp-oracle 桌面版
一个本地 MCP(Model Context Protocol)服务器,将客户数据以可查询工具的形式暴露出来,让 Claude 可以通过直接调用此服务器来回答关于客户的自然语言问题。
目前数据在本机模拟(data/customers.json,28 条含订单历史的伪客户记录)。之后,可以把模拟数据层换成对 Oracle AI Agent Studio 的真实访问,而完全不用动 MCP 工具代码——见下文
替换接入 Oracle AI Agent Studio。
Project purpose
这是一个基于 stdio 的 MCP server,提供五个工具:
工具 | 作用 |
| 按姓名、电子邮件或公司搜索(部分匹配) |
| 按精确 ID 获取某位客户的完整档案 |
| 获取某位客户的订单历史 |
| 按状态筛选客户:active / inactive / churned |
筛选客户:active / inactive / churned | filter 状态客户 的 active / inactive / churned |
| 单个客户的消费总额、订单数量、平均订单价值 |
一旦在 Claude Desktop 中注册为自定义连接器,Claude 就可以自己调用这些工具,回答诸如“哪些客户已流失?”或“John Smith 订单?”之类的问题。
Related MCP server: CRM MCP Server
项目结构
/mcp-oracle-demo
/data
customers.json # mock customer + order data
/src
data_source.ts # ONLY file that touches raw data — the Oracle swap point
server.ts # MCP server entry point, registers all tools
tools/
search_customers.ts
get_customer_details.ts
get_customer_orders.ts
list_customers_by_status.ts
get_customer_stats.ts
/test
test_data_source.ts # manual test walkthrough (npm test)
package.json
tsconfig.json
README.md安装与本地运行
Requires Node.js 18 或更高版本。
cd mcp-oracle-demo
npm install
npm run build # compiles src/ -> dist/
npm start # runs the compiled server over stdioFor 没有 build 步骤的本地开发:
npm run dev # runs src/server.ts directly via tsx在接入 Claude Desktop 之前,运行验证流程,其中综合测试数据访问层和每个“工具”的处理器,同时应为每项检查打印 PASS/FAIL:
npm testA stdio MCP 服务器本身不会向 stdout 打印任何内容(stdout 是为协议 stream 保留的)——启动后你会看到 stderr 上打印的一行“customer-data-mcp server running on stdio”,然后它会等待客户端(如 Claude Desktop)来连接。
在 Claude Desktop 中注册
在你的 claude_desktop_config.json 中新增一项(Claude Desktop 菜单 → Settings → Developer → Edit Config),指向该已编译的服务器:
{
"mcpServers": {
"customer-data": {
"command": "node",
"args": ["/absolute/path/to/mcp-oracle-demo/dist/server.js"]
}
}
}请使用绝对路径——Claude Desktop 是从自己的当前目录启动进程,而不是此项目的目录。保存配置后重启 Claude Desktop,你应该在“已连接”的 tool source 列表中看到 “customer-data”(新聊天中的 🔌 / “tools” 图标)。
连接后可尝试的问题
“显示所有 active 客户。”
“[customer name] 订购了什么?”
“哪些客户已流失?”
“客户 CUST-0012 在我们这里总共消费了多少,平均订单金额是多少?”
“找到 Acme Co. 的所有客户。”
Swapping in Oracle AI Agent Studio
src/data_source.ts 是唯一与原始客户数据接触的文件。每个 MCP 工具都调用其导出的( getCustomerById, searchCustomers, getCustomerOrders, getCustomersByStatus, getCustomerStats)函数,而不是直接读取该 JSON 文件——因此以后切换到实际“后端时,只需修改这一个文件,而不需要改工具定义或服务器本身。
在 data_source.ts 中需要做哪些改动:
认证处理 — 给 Oracle AI Agent Studio 的 API 增加 token 流程(例如 OAuth 客户端凭据或 API key)。最好从环境变量读取凭据,不要硬编码,再配一个短期的 token 缓存,免得每次调用都要重新认证。
替换本地的 JSON read (
loadCustomers()) 为对 Oracle 端点的已认证里 REST 调用——如GET /customers/{id}、GET /customers/search?q=...、GET /customers?status=...——并把 Oracle 的返回结构映射到文件内已经定义的类型Customer/OrderTS 接口上(如果 Oracle schema 不同也可以调整)。错误处理 —— 真实 API 会 timeout、rate-limit 或以本地文件读取不会出现的方式失败,因此增加 try/catch 和清晰的错误消息,让工具可以反馈给后端给 Claude。
缓存 —— 当前的内存缓存假设数据是静态的;连上真实后端后,要么移除这个缓存,要么设置短 TTL 。
上面每点的详细说明也直接注释在 src/data_source.ts 的文件底部。
测试
npm test 运行 test/test_data_source.ts,它会:
直接调用
data_source.ts中每个函数,并对照 已知的 mock 数据特征来检查返回值(例如已知 customer IDing can resolve,未知 ID 返回null,搜索不区分大小写)。直接调用 每个工具的 handler 函数(绕过 MCP transport层),并检查返回的 JSON 是否是格式正确 且 与底层数据一致。
这是一个纯脚本(不依赖测试框架),因此在屏实际演示中很容易逐行阅读、讲解。
Available Tools
5 toolsget_customer_detailsA
Get the full profile for a single customer by their exact customer ID (e.g. 'CUST-0007'). Returns name, contact info, company, signup date, status, and order summary. If you only have a name or email, use search_customers first to find the customer ID.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes | The exact customer ID, e.g. 'CUST-0007'. |
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 states that it returns a profile with specific fields, implying a read-only operation, but it doesn't explicitly confirm read-only behavior, error handling (e.g., not found), or any side effects. While adequate for a simple get, it could be more explicit about the safety and failure modes.
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 two sentences with no filler. The core purpose is front-loaded, and the alternative usage is stated concisely. Every sentence contributes information, and there is no redundancy.
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 single-parameter tool with no output schema and no annotations, the description covers the essential context: what it does, what it accepts, what it returns, and how to route when the ID is unavailable. It does not detail return structure or error cases, but given the tool's simplicity, this is reasonably complete.
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 100% for the single parameter, so baseline is 3. The description adds value by giving an example format ('CUST-0007') and emphasizing 'exact customer ID', which clarifies that the value must match precisely. This goes beyond the schema's description to reduce ambiguity.
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 uses a specific verb 'Get' and a specific resource 'full profile for a single customer', and identifies the key identifier (customer ID). It distinguishes from the sibling search_customers by explicitly stating when to use that alternative, and it lists the returned fields, making the tool's purpose unambiguous.
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 explicitly says 'If you only have a name or email, use search_customers first', giving clear guidance on when to prefer an alternative. However, it does not address other siblings like get_customer_orders or list_customers_by_status, though the mention of 'order summary' hinted at potential overlap. The guidance is helpful but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_customer_ordersA
Get the full order history for a single customer by their exact customer ID (e.g. 'CUST-0007'). Returns a list of orders, each with an order ID, date, product, amount, and order status. If you only have a name or email, use search_customers first to find the customer ID.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes | The exact customer ID, e.g. 'CUST-0007'. |
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 implies read-only behavior via 'Get' but does not explicitly state non-mutating or any error/edge-case behavior. It does describe the return structure (list with fields), which adds some value, but lacks disclosure on empty results, pagination, or access requirements. For a simple read operation this is adequate but not rich.
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?
Two sentences, front-loaded with the primary action and example. The second sentence adds return details and a redirect to search_customers. Zero waste, every clause 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 single-parameter read tool with no output schema, the description fully explains what it returns (list with order fields) and provides an alternative when prerequisites are unmet. There is no missing information an agent needs to invoke it correctly.
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 100% and the schema itself documents customer_id with the same example and description. The description adds the qualifier 'exact' and repeats the example, but this is marginal beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.
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 clearly states the tool gets the full order history for a single customer by exact customer ID, with the example 'CUST-0007'. It also specifies return fields, making the purpose unambiguous. It does not explicitly contrast with every sibling, but it does name search_customers as an alternative, which helps differentiation.
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 provides clear usage context: use when you have the exact customer ID, and if you only have a name/email, use search_customers first. This explicitly sets a condition for when not to use this tool. However, it does not mention other siblings like get_customer_details or get_customer_stats, so coverage of alternatives is incomplete but sufficient for basic routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_customer_statsA
Get summary spend statistics for a single customer by their exact customer ID (e.g. 'CUST-0007'): total order count, total spend (excluding cancelled/refunded orders), average order value, and lifetime value. Use this for questions about how much a specific customer has spent, rather than their raw order list.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes | The exact customer ID, e.g. 'CUST-0007'. |
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 discloses a key behavioral detail—total spend excludes cancelled/refunded orders—which is essential to interpret the output. However, it does not cover edge cases like nonexistent customer IDs or permission requirements, but for a read-only summary tool this is acceptable.
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?
Two concise sentences: the first lists the purpose and metrics, the second gives usage guidance. The phrase 'e.g. CUST-0007' repeats the schema example, but the description is otherwise efficient and front-loaded.
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 single-parameter read tool with no output schema, the description adequately covers the return values (metrics listed), a hidden behavioral detail (exclusion of cancelled/refunded), and clear usage context. No critical information is missing for correct invocation.
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 100%; the schema already describes customer_id with an example. The description reinforces 'exact' and repeats the same example, adding no new semantic information. It meets the baseline for high schema coverage.
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 clearly states the verb ('Get'), the resource ('summary spend statistics for a single customer'), and specifies the exact metrics returned (total order count, total spend, average order value, lifetime value). It also explicitly differentiates from raw order lists via the phrase 'rather than their raw order list,' distinguishing it from the sibling get_customer_orders.
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 provides an explicit when: 'Use this for questions about how much a specific customer has spent,' and a when-not with an alternative: 'rather than their raw order list.' This gives clear guidance without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_customers_by_statusA
List all customers with a given status. Valid statuses are 'active', 'inactive', or 'churned'. Returns each matching customer's basic profile info. Use this for questions like 'show me all active customers' or 'which customers have churned?'
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | The customer status to filter by. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description bears full responsibility for behavioral disclosure. It states that the tool returns 'basic profile info', implying a read-only operation and summarizing the output. It does not mention pagination, ordering, or potential limitations, but for a simple list-by-status tool this is sufficient. The description is honest and does not contradict any annotations (there are none).
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 two concise sentences: the first delivers the core action and valid values, the second states the return type and provides query examples. It is front-loaded with the essential purpose and contains zero filler, making it easy for an agent to parse quickly.
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 single-parameter tool with no output schema and no annotations, the description covers the essential context: what it does, valid inputs, return nature, and usage examples. It does not mention pagination or any edge cases, but given the simplicity of the operation, this is adequate. A 5 would require addressing potential limitations or more specific return details, which are not critical here.
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 100% — the single 'status' parameter already has an enum and a clear description. The description repeats the valid statuses and gives usage examples, which adds a little context but does not provide new semantic meaning beyond what the schema declares. This matches the baseline of 3 for full schema coverage.
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 clearly states the action ('List'), the resource ('all customers'), and the specific filter ('with a given status'). It also gives concrete example queries, which makes the purpose unambiguous. The verb 'list' distinguishes it from sibling tools like search_customers (search) and get_customer_details (single customer), so an agent can easily tell them apart.
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 provides explicit usage context with example questions ('show me all active customers', 'which customers have churned?'), telling the agent when to invoke this tool. However, it does not mention when not to use it or explicitly contrast with alternatives like search_customers or get_customer_details, so it stops short of the full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_customersA
Search for customers by name, email, or company name. Performs a case-insensitive partial match, so 'smith' will match 'John Smith' and 'jane.smith@...'. Returns a list of matching customers with their basic profile info (does not include full order history — use get_customer_details or get_customer_orders for that). Use this when the user gives a name, email, or company rather than an exact customer ID.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search text to match against customer name, email, or company (partial match, case-insensitive). Example: 'smith', 'acme', 'john@example.com'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses case-insensitive partial matching, indicates the return content ('basic profile info'), and explicitly excludes full order history, directing to other tools. It does not mention pagination or error behavior, but for a read-only search these are minor gaps.
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?
Three sentences, front-loaded with the core purpose, each earning its place. No redundancy, and the secondary alternatives are mentioned succinctly without digressing.
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 simple one-parameter search tool, it covers the essential context: what it matches, what it returns (basic profile), what it excludes (order history), and when to use it. It could elaborate on what 'basic profile info' includes, but given the single parameter and no output schema, this is adequate.
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 already fully documents the query parameter with description and example, covering the matching behavior (partial, case-insensitive). The tool description restates the same info but adds no new semantic detail beyond the schema, so baseline 3 is appropriate.
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?
Description states a specific verb ('Search for customers'), identifies the resource ('customers'), and enumerates searchable fields (name, email, company). It also distinguishes from siblings by noting it's for partial text matches rather than exact IDs and mentions get_customer_details/get_customer_orders for order history, making it clear what this tool is for.
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?
Explicitly states when to use: 'Use this when the user gives a name, email, or company rather than an exact customer ID.' It also guides toward alternatives for order history, providing clear when-to-use and when-not-to-use guidance.
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.
5 tool updates
v1.0.0- First observed
get_customer_details - First observed
get_customer_orders - First observed
get_customer_stats - First observed
list_customers_by_status - First observed
search_customers
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: search by name/email/company, get details by ID, get orders by ID, list by status, and get stats by ID. There is no overlap; the descriptions explicitly clarify when to use each (e.g., search_customers vs. get_customer_details).
All tool names follow a consistent verb_noun pattern using snake_case: search_customers, get_customer_details, get_customer_orders, list_customers_by_status, get_customer_stats. The verbs (search, get, list, get) and nouns are uniform and predictable.
5 tools is well-scoped for a customer data server, sitting comfortably within the ideal 3-15 range. Each tool addresses a distinct query type without redundancy, making the surface concise and maintainable.
The tool set covers the core read-oriented workflows: search, details, orders, status-based listing, and stats. The only minor gap is a lack of a way to list all customers regardless of status (e.g., a list_customers tool), but list_customers_by_status can approximate this with a single status, and the domain appears read-only by design.
Maintenance
Related MCP Connectors
Agent personas for Claude. 16 tools, 13 personas, 3 workflows. Zero extra API cost. Free.
Marketo MCP server for AI. 130 tools to operate Marketo from Claude, Cursor, or ChatGPT.
Build and manage AI-native customer support agents from Claude or any MCP client.
Your Aurentia workspace — projects, CRM, tasks, deliverables — in Claude, Cursor or any MCP client.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables querying a synthetic patient dataset with tools to look up patients by ID, age, disease, name, and get statistics, connecting Claude Desktop to local data.6-
- FlicenseNot gradedqualityDmaintenanceEnables querying and managing a CRM database through natural language conversations with Claude Desktop.-
- FlicenseAqualityDmaintenanceEnables Claude to query a local DuckDB warehouse containing mock motorcycle-loan data, with tools for customer search, insights, and read-only SQL queries.5-
- FlicenseNot gradedqualityDmaintenanceProvides Claude agents with CRM contact lookup, action logging, and prompt cost auditing tools. Includes a Streamlit UI to demo the same tools without an MCP client.-