Skip to main content
Glama
nonatin1000

@erickwendel/ew-customers-mcp

by nonatin1000

@erickwendel/ew-customers-mcp

An MCP (Model Context Protocol) server that exposes a legacy customer CRUD REST API as tools, a resource, and a prompt β€” all runnable directly inside VS Code Copilot Chat.

This server is a thin adapter: it wraps the legacy nodejs-fastify-mongodb-crud API (Node/Fastify + MongoDB) over HTTP and does not modify it. The legacy API stays exactly as it is; only the MCP wrapper was ported from TypeScript to Python.


What it does

Capability

Name

Description

πŸ”§ Tool

list_customers

Lists all customers

πŸ”§ Tool

get_customer

Finds a customer by id, name, or phone

πŸ”§ Tool

create_customer

Creates a customer

πŸ”§ Tool

update_customer

Updates a customer's name and/or phone by id

πŸ”§ Tool

delete_customer

Deletes a customer by id

πŸ“„ Resource

customers://api-info

Describes the legacy REST API this server wraps

πŸ’¬ Prompt

find_customer_prompt

Pre-built prompt that asks the agent to search a customer


Related MCP server: sap-mcp-server

Architecture

src/customers_mcp/
  domain/
    customer.py          # Pydantic models mirroring the legacy API's wire format
  infrastructure/
    customer_http_client.py  # HTTP client for the legacy REST API
  application/
    customer_service.py  # Business rules (find-by-any-field, delegates CRUD)
  mcp/
    server.py             # Wires tools/resource/prompt onto a FastMCP instance
    tools/                 # One module per tool (SRP)
    resources/
    prompts/
  __main__.py              # Entry point β€” connects the server to stdio transport
tests/
  conftest.py               # Shared MCP client helper (async context manager)
  test_customer_service.py  # Unit tests (fake HTTP client, no network)
  test_customer_tools.py    # Integration tests via a real MCP stdio client
  test_api_info_resource.py
  test_find_customer_prompt.py

CustomerService receives its CustomerHttpClient via constructor injection (composed in mcp/server.py), so it can be tested in isolation with a fake client β€” no legacy API or network needed for test_customer_service.py.


Prerequisites

  • Python 3.12+

  • uv (recommended) or pip

  • The legacy nodejs-fastify-mongodb-crud API running at http://localhost:9999 (only needed to actually call the tools or run the integration tests β€” see that project's docker-compose.yml: npm run docker:infra:up)


Installation

uv sync

Using in VS Code

1. Add the MCP server configuration

Create (or open) .vscode/mcp.json in your workspace:

{
  "servers": {
    "customers-mcp": {
      "command": "uv",
      "args": ["run", "python", "-m", "customers_mcp"]
    }
  }
}

2. Reload VS Code

Command Palette (Cmd+Shift+P) β†’ Developer: Reload Window.

3. Use it in Copilot Chat

List all customers
Create a customer named "Ana" with phone "999-000-111"
Find the customer named John

Running tests

uv run pytest

test_customer_service.py runs standalone (no dependencies). The other test files spawn the real MCP server and call the legacy API, so they require it running at http://localhost:9999 first.


Available commands

Command

Description

uv run python -m customers_mcp

Start the server (used by MCP clients)

uv run pytest

Run all tests

uv run ruff check .

Lint

uv run ruff format .

Format

Available Tools

5 tools
create_customerB

Create a customer

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesFull name of the customer
phoneYesPhone number of the customer

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNoMongoDB ObjectId of the customer
isErrorNoIndicates if an error occurred
messageNoConfirmation message
customerNoThe found customer
customersNoList of customers

TDQS

B3/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It only states the action and provides zero information about side effects, required permissions, error cases, or success behavior. There is no mention of what happens on duplicate names or how the response is structured (though output schema exists). 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler or redundant information. It is front-loaded with the core action. However, it is so minimal that it could be considered under-specified rather than concise, so it earns a 4 rather than a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter create operation with an output schema, the description is minimally sufficient for an agent to know the core purpose. However, it lacks usage context and behavioral details that would help the agent decide when to use it and what to expect. An agent might call it without knowing potential failure modes or preconditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% description coverage with clear parameter descriptions ('Full name of the customer' and 'Phone number of the customer'). The description does not add any meaning beyond the schema, but the baseline is 3 because schema already documents both parameters adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Create a customer' states a specific verb and resource. It distinguishes itself from sibling tools (list_customers, get_customer, delete_customer, update_customer) by indicating the create operation. However, it adds no nuance beyond the tool name, which slightly limits its clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the verb 'create' – it is for adding a new customer. But there is no explicit guidance on when to use it vs alternatives, no prerequisites, and no mention of conditions like uniqueness checks. The agent must infer the intended use case from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_customerB

Delete a customer by their id

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idYesMongoDB ObjectId of the customer to delete

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNoMongoDB ObjectId of the customer
isErrorNoIndicates if an error occurred
messageNoConfirmation message
customerNoThe found customer
customersNoList of customers

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It only says 'Delete a customer' without indicating whether this is a hard delete, whether it's irreversible, what happens on missing id, or any side effects. The lack of such disclosure is a significant gap for a destructive operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It is concise and to the point, though it could benefit from additional context without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema (not shown), the return value might be covered there, but the description does not explain error behavior, permanence, or prerequisites. For a delete operation, this is incompleteβ€”especially without annotations to carry the safety profile.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema fully describes customer_id with 100% coverage. The description adds no extra meaning beyond 'by their id', which is redundant. Since schema coverage is high, the baseline of 3 applies, but the description contributes nothing beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the verb 'Delete', the resource 'customer', and the method 'by their id'. It clearly distinguishes from sibling tools (list, get, create, update) by specifying the destructive action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage is implied by the verb 'Delete' but there is no explicit guidance on when to use it versus alternatives, nor any mention of prerequisites or consequences. For example, it doesn't say 'use this to permanently remove a customer' or 'this cannot be undone'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_customerA

Find a customer by id, name, or phone number

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoFull name of the customer
phoneNoPhone number of the customer
customer_idNoMongoDB ObjectId of the customer

Output Schema

ParametersJSON Schema
NameRequiredDescription
customerYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries the burden of behavioral disclosure. 'Find' reasonably implies a read-only operation with no modification side effects, which is helpful. However, it does not clarify behavior when no parameters are passed, when multiple parameters are passed, or when no matching customer exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The entire guidance is one efficient sentence with no filler. The action and the target identification method are immediately evident, making it easy to scan and parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple lookup tool, the description conveys the essence, and the output schema covers return structure. Yet all three input parameters are optional, and the description never states that at least one should be provided or how multiple identifiers interact, leaving an important call-time gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds marginal value by framing the three properties as alternative search identifiers, but it does not explain whether they are mutually exclusive, combinable, or required, so it does not substantially improve on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'find' and identifies the resource 'customer' plus the three lookup keys (id, name, phone). This clearly separates it from siblings like list_customers, create_customer, update_customer, and delete_customer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'by id, name, or phone number' implies when it should be used: when you have a customer identifier and need that customer's record. It gives clear context but stops short of explicitly contrasting with list_customers or noting exclusions, so it does not reach the top tier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_customersA

List all customers

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
customersYes

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states only the basic action and provides no information about pagination, ordering, response structure, or potential performance implications. While it clearly implies a read operation, it does not add any behavioral context beyond what the name suggests.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence with no redundant words. It is appropriately sized for a tool with no parameters and a straightforward purpose, 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.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the tool (no parameters, clear purpose, and an output schema exists), the description is nearly complete. It states the core function, and the output schema covers return values. However, it could mention that it returns a list of all customers without pagination or any limits, but this is largely implicit. It is adequate but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema is trivially 100% covered. Per the calibration baseline, a 0-parameter tool merits a 4. The description does not need to explain any parameters, and it does not add anything that conflicts with the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'List all customers' uses a specific verb (list) and resource (customers), clearly distinguishing it from sibling tools that get, delete, create, or update a customer. It leaves no ambiguity about what action is performed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The tool's usage is implied by the name and description: it lists all customers, while siblings handle individual customer operations. However, there is no explicit guidance on when to choose this over get_customer or when a filter would be needed. The context is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_customerA

Update an existing customer's name and/or phone number by their id

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoFull name of the customer
phoneNoPhone number of the customer
customer_idYesMongoDB ObjectId of the customer

Output Schema

ParametersJSON Schema
NameRequiredDescription
idNoMongoDB ObjectId of the customer
isErrorNoIndicates if an error occurred
messageNoConfirmation message
customerNoThe found customer
customersNoList of customers

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral burden. 'Update' signals mutation and 'and/or' hints at partial updates, but the description does not disclose what happens when only customer_id is provided, whether omitted fields preserve their values or are set to null, or how missing IDs are handled. These are significant behavioral gaps for an update operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence conveys the operation, target, and affected fields with no filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema fully documents parameters and an output schema exists, so return-value details are not the description's job. However, the description leaves omitted-parameter semantics ambiguous and gives no guidance on edge cases, making it minimally adequate rather than complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents customer_id, name, and phone meaningfully. The description adds only that the named fields are the update targets and that the ID identifies the customer, which is a slight reinforcement but not substantial added semantic value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Update'), a clear resource ('existing customer'), and the exact fields affected ('name and/or phone number') plus the identifying mechanism ('by their id'). This fully distinguishes it from the create, delete, list, and get siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Existing customer' clearly implies this tool is for customers that already exist, not for creation, and 'by their id' indicates the caller must know the target ID. It does not explicitly name alternatives or exclusions, but the context is strong enough for an agent to recognize when it applies.

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.

  1. 5 tool updatesv0.0.1
    • First observedcreate_customer
    • First observeddelete_customer
    • First observedget_customer
    • First observedlist_customers
    • First observedupdate_customer

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: list, get, create, update, and delete customers. No overlap or ambiguity between them.

Naming Consistency5/5

All tools follow the consistent verb_noun pattern: list_customers, get_customer, delete_customer, create_customer, update_customer. Perfectly consistent.

Tool Count5/5

With 5 tools, the set is well-scoped for a customers CRUD server. Each tool is necessary and none are redundant.

Completeness4/5

The tool set covers full CRUD operations (list, get, create, update, delete) for customers, missing only a bulk operation or search by multiple criteria, but agents can achieve most workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables natural language querying of SAP business partner data by exposing OData APIs as MCP tools for LLM agents.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables interaction with a REST API of customers through MCP tools, resources, and prompts, allowing listing, creating, retrieving, updating, and deleting customer records from MCP-compatible clients.
    5 npm
    ISC