AI agents become useful when they can access the right business context and take approved actions. A generic chatbot can answer broad questions, but it cannot inspect your SaaS database, read your internal docs, search your support tickets, create a task, or summarize a customer account unless you connect it to those systems. That is the real reason developers are learning how to build a custom MCP server.
The Model Context Protocol, or MCP, is an open protocol that helps LLM applications connect to external data sources and tools in a standardized way. Anthropic introduced MCP as an open standard for secure, two-way connections between AI-powered tools and data sources, while the official MCP specification describes servers exposing capabilities such as tools, resources, and prompts to clients. Anthropic MCP announcement MCP specification
This guide explains how to build a custom MCP server for a SaaS app, database, API, documentation system, or internal business workflow. It covers what your server should expose, how to design tools and resources, when to use TypeScript or Python, how to test with MCP clients, and how to deploy MCP safely in production.
What Is a Custom MCP Server?
A custom MCP server is a connector between an AI client and a specific data source or capability that your business owns. Instead of giving an agent direct, uncontrolled access to your database or internal API, the MCP server exposes a controlled set of actions and context.
For example, a custom MCP server for a project management SaaS might expose:
- A resource for reading the current user's assigned projects.
- A tool for creating a task after validating required fields.
- A prompt for generating a weekly project summary from selected records.
- A read-only database schema resource for helping a coding agent understand the data model.
- A support-ticket search tool for retrieving relevant customer history.
The goal is not to expose everything. The goal is to expose the smallest useful set of capabilities that an AI agent needs to complete a workflow safely.
MCP Tools, Resources, and Prompts
Before writing code, understand MCP's core server primitives.
| Primitive | Purpose | Example | Risk Level |
|---|---|---|---|
| Resources | Expose readable context to the client. | A database schema, project file, customer profile, or runbook. | Low to medium, depending on data sensitivity. |
| Tools | Let the model invoke actions. | Search records, create task, call API, query database. | Medium to high, especially for write actions. |
| Prompts | Define reusable workflows or templates. | Summarize incident, draft release notes, generate customer brief. | Low, but output should still be reviewed. |
MCP's tools documentation says tools let servers expose executable capabilities that language models can invoke, such as querying databases, calling APIs, or performing computations. MCP tools documentation That is why tool design is the most important part of custom MCP development.
Step 1: Choose the Use Case
Do not start by building a general MCP server for your entire company. Start with one workflow that is valuable and safe.
Good first use cases include:
- Read-only search over internal documentation.
- Read-only database schema inspection for developers.
- Support ticket lookup for customer success teams.
- Project summary generation from task records.
- GitHub issue and pull request summaries.
- Safe CRM lead lookup for sales research.
- Incident runbook retrieval for DevOps teams.
Avoid starting with destructive tools such as deleting records, sending emails, issuing refunds, changing permissions, or deploying infrastructure. Prove read-only value first.
Step 2: Pick TypeScript or Python
MCP has official SDKs for multiple languages. The official SDK page says developers can build MCP servers and clients using SDKs classified by feature completeness, protocol support, and maintenance commitment. MCP official SDKs
For most teams, the choice comes down to TypeScript or Python.
| Language | Use It When | Common MCP Use Cases |
|---|---|---|
| TypeScript | Your app stack is Node.js, Next.js, Express, NestJS, or full-stack TypeScript. | SaaS APIs, GitHub workflows, developer tools, CRM integrations, web app backends. |
| Python | Your data stack, AI pipeline, analytics workflow, or backend is Python-based. | Data tools, knowledge bases, notebooks, ML workflows, internal automation, database helpers. |
The TypeScript SDK repository says it implements the MCP specification and runs on Node.js, Bun, and Deno. MCP TypeScript SDK The Python SDK repository says MCP lets developers build servers that expose data and functionality to LLM applications in a secure, standardized way. MCP Python SDK
Step 3: Define the Server Contract
Before writing the server, define what it will expose. A good MCP server contract should answer:
- Who is allowed to use this server?
- What resources can the agent read?
- What tools can the agent call?
- Which tools are read-only?
- Which tools write data or trigger external actions?
- Which arguments are required?
- What should the output schema look like?
- What errors should be returned?
- Which actions require human approval?
For example, a customer lookup server should not expose a broad run_sql tool to an agent. A safer design is a narrow search_customers tool with validated fields such as email, account ID, or company name, and a limited result schema.
Step 4: Build a Simple Python MCP Server
The official MCP server build guide uses Python's FastMCP class, which uses type hints and docstrings to generate tool definitions. Build an MCP server guide
A simple server pattern looks like this:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("customer-support")
@mcp.tool()
def search_help_docs(query: str) -> list[dict]:
"""Search approved support documentation."""
# Replace this with your real search logic.
return [
{
"title": "Password reset guide",
"url": "https://example.com/docs/password-reset",
"snippet": "Steps for resetting a customer password."
}
]
@mcp.tool()
def get_ticket_summary(ticket_id: str) -> dict:
"""Return a read-only ticket summary by ticket ID."""
# Validate ticket_id and enforce permissions before querying.
return {
"ticket_id": ticket_id,
"status": "open",
"priority": "medium",
"summary": "Customer cannot access billing settings."
}
if __name__ == "__main__":
mcp.run()
This example is intentionally read-only. It gives an agent useful context without allowing it to modify customer data. After the workflow is proven, you can add write tools behind stronger validation and approvals.
Step 5: Build a TypeScript MCP Server
For SaaS teams using Node.js, a TypeScript MCP server is often easier to integrate with existing code. The TypeScript SDK can be used to expose tools and connect to Node-based APIs, databases, and services.
A typical TypeScript server design includes:
- A server instance with a clear name and version.
- Tool definitions with explicit input schemas.
- Handlers that validate arguments before calling business logic.
- Structured return values.
- Error handling for missing records, unauthorized requests, and API failures.
- Logging around each tool call.
For example, a SaaS admin MCP server might expose get_account_summary, search_invoices, and create_support_task. The first two can be read-only, while create_support_task should require stronger validation and audit logging.
Step 6: Connect to Real Data Safely
The biggest mistake in MCP development is connecting an agent directly to powerful systems without enough control. A custom MCP server should act as a safety layer, not a shortcut around safety.
Safe data integration patterns include:
- Use read-only database users for schema inspection and reporting tools.
- Use allowlisted queries instead of arbitrary SQL execution.
- Limit result size so agents cannot dump entire tables.
- Mask sensitive fields such as tokens, passwords, card data, and private notes.
- Validate tool inputs before calling internal APIs.
- Log every tool call with timestamp, user, arguments, and result metadata.
- Require approval for tools that write, send, delete, deploy, or modify permissions.
A custom MCP server should narrow the agent's access to exactly what the workflow needs. If the agent needs to summarize support tickets, it probably does not need payment records, admin credentials, or full database write access.
Step 7: Test with an MCP Client
After building the server, connect it to an MCP-compatible client or inspector tool and test each capability. Your test plan should include happy paths and failure cases.
Test for:
- Tool discovery.
- Correct input schema display.
- Valid tool calls.
- Invalid arguments.
- Empty results.
- Permission failures.
- API timeout behavior.
- Large result truncation.
- Prompt injection attempts inside returned data.
- Logging and audit output.
OpenAI's MCP server guide explains that remote MCP servers can connect models over the internet to new data sources and capabilities for ChatGPT Apps, deep research, or API integrations. OpenAI MCP server guide If you plan to expose a remote MCP server, test authentication, transport, and network behavior carefully before production.
Step 8: Deploy Local vs Remote MCP Servers
There are two common deployment styles:
| Deployment Type | Best For | Security Notes |
|---|---|---|
| Local MCP server | Developer tools, local files, local Git repos, personal automation. | Restrict file access and avoid exposing secrets. |
| Remote MCP server | Team tools, SaaS integrations, web apps, shared business workflows. | Require authentication, transport security, rate limits, and audit logs. |
For internal company workflows, a remote MCP server is often more maintainable because permissions, updates, and logs can be centrally managed. For developer productivity tools, local MCP servers can be simpler and safer when they only access a specific project folder.
Step 9: Add Observability
A production MCP server should be observable like any backend service. You should know who used it, what tools were called, which calls failed, and whether the agent's output was useful.
Track these metrics:
- Tool call count by user and tool.
- Tool latency and timeout rate.
- API error rate.
- Permission-denied events.
- Large result truncation events.
- Human approval rate.
- Rejected action rate.
- Cost per workflow if model usage is tied to tool usage.
- Security events such as unusual access patterns.
Without observability, teams cannot tell whether an MCP server is helping, failing, leaking context, or being overused.
Step 10: Add Security Controls
Treat MCP as privileged integration infrastructure. A server that can access internal files, databases, ticketing systems, or customer records needs the same seriousness as any production API.
- Least privilege: give the server only the credentials it needs.
- Read-only first: prove value before adding write actions.
- Input validation: validate every tool argument.
- Output filtering: remove secrets and sensitive fields before returning results.
- Rate limiting: prevent expensive or abusive repeated tool calls.
- Human approval: require review for destructive or external actions.
- Audit logs: record tool calls and results.
- Environment separation: use separate dev, staging, and production servers.
- Dependency review: keep SDKs and packages updated.
Security should be part of the first design, not something added after the server becomes popular.
Example: MCP Server for a SaaS Support Dashboard
Imagine a SaaS company wants support agents to ask an AI assistant, “What is going on with this customer?” A custom MCP server can expose only the safe, useful context.
Resources:
- Customer account summary.
- Plan and billing status without sensitive payment data.
- Open support tickets.
- Recent incidents affecting the customer.
- Product documentation links.
Tools:
- lookup_customer: read-only customer lookup by email or account ID.
- search_tickets: returns relevant support ticket summaries.
- create_internal_note: writes a note only after approval.
- draft_reply: creates a suggested response without sending it.
This workflow helps agents answer faster while keeping sensitive actions controlled.
Common Mistakes to Avoid
Mistake 1: Exposing generic database access
A broad SQL execution tool is risky. Prefer narrow tools with explicit schemas, read-only credentials, and result limits.
Mistake 2: Returning too much context
More context is not always better. Return only what the workflow needs. Large results increase cost, latency, and privacy risk.
Mistake 3: No human approval for write actions
Creating tasks may be low risk, but deleting records, sending emails, issuing refunds, or changing permissions should require explicit approval.
Mistake 4: Ignoring prompt injection in data
Returned documents, tickets, and web pages can contain malicious instructions. Treat retrieved content as data, not as a trusted system instruction.
Mistake 5: Building one giant MCP server
Create focused servers by domain: GitHub, support, billing, documentation, CRM, or analytics. Smaller servers are easier to secure and maintain.
Production Checklist
- Use a clear server name, version, and owner.
- Document every exposed tool, resource, and prompt.
- Start with read-only tools where possible.
- Validate all tool inputs.
- Use least-privilege credentials.
- Limit returned result size.
- Mask sensitive fields.
- Log every tool call.
- Add rate limits and timeouts.
- Require human approval for high-risk actions.
- Test with valid, invalid, empty, and malicious inputs.
- Separate dev, staging, and production configurations.
- Review dependencies and SDK updates.
Final Takeaway
A custom MCP server is not just another API wrapper. It is a controlled integration layer between AI agents and real business systems. The best servers are focused, safe, observable, and designed around actual workflows.
Start small. Expose one read-only workflow, test it with real users, measure its usefulness, then add more tools gradually. If the agent needs to take actions, add validation, logging, and human approval before production.
MCP is powerful because it standardizes how AI clients connect to tools and context. Your responsibility as a builder is to decide what context is safe, what actions are allowed, and how every call can be monitored.
Build Custom MCP Servers with Gadzooks Solutions
Gadzooks Solutions helps teams design and build custom MCP servers for SaaS apps, internal tools, documentation systems, databases, CRMs, support platforms, and developer workflows. We define tool schemas, connect APIs, secure credentials, add observability, test with MCP clients, and deploy production-ready servers.
If your AI agent needs real business context instead of generic answers, a custom MCP server can become the integration layer that makes it useful.
FAQ: Building a Custom MCP Server
What is the first MCP server I should build?
Start with a read-only documentation, support-ticket, or database-schema server. These give agents useful context without allowing them to modify production systems.
Do I need a custom MCP server if my app already has APIs?
Possibly. Your existing APIs are still useful, but an MCP server can expose them in an AI-friendly way through tools, resources, and prompts with clear schemas and guardrails.
Can an MCP server write to a database?
Yes, but write actions should be narrow, validated, logged, and protected by permission checks. For high-risk actions, require human approval before writing.
Should MCP tools return raw database rows?
Usually no. Return structured, filtered, task-specific results. Remove secrets, internal-only fields, and unnecessary personal data before returning output to the client.
Can Gadzooks build MCP servers for private SaaS data?
Yes. Gadzooks Solutions can build MCP servers for private SaaS databases, CRMs, internal APIs, support tools, documentation, analytics systems, and developer workflows with security and observability built in.
Sources
- Anthropic: Introducing the Model Context Protocol
- Model Context Protocol specification
- MCP architecture documentation
- MCP official SDKs
- Build an MCP server guide
- MCP tools documentation
- MCP resources documentation
- MCP prompts documentation
- MCP TypeScript SDK
- MCP Python SDK
- OpenAI MCP server guide
- OpenAI Agents SDK MCP documentation