Internal Data MCP Server

Internal Data MCP Server

Exposes internal employee directories and project management systems to AI models through standardized tools and resources. It enables AI assistants to search for team members, query project statuses, and explore organizational hierarchies with secure role-based access control.

Category
访问服务器

README

Internal Data MCP Server

A production-grade Model Context Protocol (MCP) server that exposes internal employee directory and project management systems to AI models.

Overview

This MCP server standardizes how AI assistants access your internal data. Instead of building custom integrations for each AI model, you define your data once, and any MCP-compatible client—Claude, ChatGPT, or your custom app—can use it without modification.

Key Capabilities

  • Employee Directory Search – Find team members by name, email, role, or department
  • Project Management – Query active, completed, and on-hold projects
  • Team Composition – Identify who's working on what projects
  • Organization Structure – Explore departments and team hierarchies
  • Secure Access Control – Role-based data filtering per user
  • Audit Logging – Complete audit trail of all data access
  • Production Ready – Health checks, error handling, Docker-ready

Architecture

┌─────────────────┐
│   AI Models     │
│  (Claude, etc)  │
└────────┬────────┘
         │
    HTTP/stdio
         │
┌────────▼──────────────────────┐
│    MCP Server (Node.js)        │
│  - Tools (Data Operations)     │
│  - Resources (Context Data)    │
│  - Authentication/Audit        │
└────────┬──────────────────────┘
         │
    ┌────┴──────┬──────────┐
    │            │          │
┌───▼──┐    ┌────▼───┐  ┌──▼────┐
│ DB   │    │ APIs   │  │ Docs   │
└──────┘    └────────┘  └────────┘

Quick Start

Prerequisites

  • Node.js 22+
  • npm or yarn
  • PostgreSQL (for production use; can be mocked in dev)

Installation

# Clone or download the repository
cd internal-data-mcp

# Install dependencies
npm install

# Build TypeScript
npm run build

Development

# Run the HTTP server (dev mode)
npm run dev

# Run with stdio transport (for Claude Desktop)
npm run stdio

# Type check
npm run type-check

The server will start on http://localhost:3100/mcp by default.

Production

# Build for production
npm run build

# Start the server
npm start

# Or use Docker
docker build -t internal-data-mcp .
docker run -p 3100:3100 -e INTERNAL_DB_URL="postgres://..." internal-data-mcp

Configuration

Environment Variables

# Database connection string
INTERNAL_DB_URL=postgres://user:password@localhost/internal_data

# Server port (default: 3100)
PORT=3100

# Node environment
NODE_ENV=production

Database Schema

The server expects the following PostgreSQL tables:

-- Employees table
CREATE TABLE employees (
  id UUID PRIMARY KEY,
  name TEXT NOT NULL,
  email TEXT UNIQUE NOT NULL,
  department TEXT NOT NULL,
  role TEXT NOT NULL,
  manager_id UUID,
  start_date DATE NOT NULL
);

-- Projects table
CREATE TABLE projects (
  id UUID PRIMARY KEY,
  name TEXT NOT NULL,
  status VARCHAR(20) NOT NULL CHECK (status IN ('active', 'completed', 'on_hold')),
  lead_id UUID NOT NULL REFERENCES employees(id),
  department TEXT NOT NULL,
  deadline DATE
);

-- Project members bridge table
CREATE TABLE project_members (
  project_id UUID NOT NULL REFERENCES projects(id),
  employee_id UUID NOT NULL REFERENCES employees(id),
  PRIMARY KEY (project_id, employee_id)
);

API Endpoints

Core MCP Endpoint

  • POST/GET /mcp – Main MCP protocol endpoint (requires authentication)

Health Checks

  • GET /health – Full health check with dependency status
  • GET /health/live – Liveness probe
  • GET /health/ready – Readiness probe

Information

  • GET /info – Server capabilities and available tools

Tools

search_employees

Search the employee directory by name, email, or role.

Parameters:

  • query (string, required) – Search term
  • department (string, optional) – Filter by department

Example:

{
  "name": "search_employees",
  "arguments": {
    "query": "engineer",
    "department": "Engineering"
  }
}

list_projects

List projects filtered by status.

Parameters:

  • status (enum["active", "completed", "on_hold"], required) – Project status

Example:

{
  "name": "list_projects",
  "arguments": {
    "status": "active"
  }
}

get_project_team

Get all team members for a specific project.

Parameters:

  • project_id (UUID, required) – Project identifier

Example:

{
  "name": "get_project_team",
  "arguments": {
    "project_id": "550e8400-e29b-41d4-a716-446655440000"
  }
}

Resources

org-structure

Organization structure overview with all departments.

URI: internal://org-structure

department-info

Detailed information about a specific department.

URI: internal://departments/{name}

Examples:

  • internal://departments/Engineering
  • internal://departments/Marketing

usage-guide

Guide on how to use the MCP server.

URI: internal://usage-guide

Authentication

The server supports multiple authentication methods:

Bearer Token (Recommended)

Include a Bearer token in the Authorization header:

curl -H "Authorization: Bearer your-token" http://localhost:3100/mcp

Token format (demo): Base64-encoded {userId}:{orgId}:{role}

Development Mode

Without an Authorization header, the server grants admin access (for development/demo only). In production, this should return 401.

Customizing Auth

Edit src/auth-middleware.ts to integrate with your authentication system:

  • JWT verification
  • API key validation
  • OAuth 2.0
  • Custom token validation

Access Control

User access is controlled through roles:

  • admin – Full access to all data
  • hr – Full employee data access, salary info allowed
  • manager – Restricted to their department
  • employee – Limited to public information

Edit src/auth-middleware.ts to customize access policies.

Logging & Audit Trail

All tool invocations are logged to the audit trail with:

  • User ID and organization
  • Tool name and parameters
  • Result size and execution time
  • Timestamp

This data is essential for compliance and security auditing. Configure your logging destination in src/audit.ts.

Connecting to Claude Desktop

Add to your ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "internal-data": {
      "command": "node",
      "args": ["path/to/internal-data-mcp/dist/index.js"],
      "env": {
        "INTERNAL_DB_URL": "postgres://...",
        "PORT": "3100"
      }
    }
  }
}

Or use the built-in Stdio transport:

{
  "mcpServers": {
    "internal-data": {
      "command": "tsx",
      "args": ["path/to/internal-data-mcp/src/stdio.ts"]
    }
  }
}

Connecting a Custom Client

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("http://localhost:3100/mcp"),
  {
    requestInit: {
      headers: {
        Authorization: `Bearer ${userToken}`,
      },
    },
  }
);

const client = new Client({
  name: "my-app",
  version: "1.0.0",
});

await client.connect(transport);
const { tools } = await client.listTools();

See src/client-example.ts for a full example.

Project Structure

internal-data-mcp/
├── src/
│   ├── index.ts                 # HTTP server entry point
│   ├── stdio.ts                 # Stdio transport entry point
│   ├── db.ts                    # Database access layer
│   ├── tools.ts                 # MCP tool definitions
│   ├── resources.ts             # MCP resource definitions
│   ├── auth-middleware.ts       # Authentication & access control
│   ├── audit.ts                 # Logging & audit trail
│   └── client-example.ts        # Example MCP client
├── Dockerfile                   # Multi-stage production build
├── claude_desktop_config.json   # Claude Desktop configuration
├── package.json                 # Dependencies
├── tsconfig.json                # TypeScript configuration
└── README.md                    # This file

Common Patterns

Adding a New Tool

  1. Add a function to src/db.ts to query your data
  2. Register the tool in src/tools.ts using server.tool()
  3. Define the Zod schema for parameters
  4. Return structured content
server.tool(
  "get_user_profile",
  "Get a user's profile information",
  {
    user_id: z.string().uuid().describe("User ID"),
  },
  async ({ user_id }) => {
    const user = await getUserProfile(user_id);
    return {
      content: [
        {
          type: "text",
          text: formatUserProfile(user),
        },
      ],
    };
  }
);

Adding a New Resource

Resources provide background context the AI can read:

server.resource(
  "api-docs",
  "internal://api/docs",
  {
    description: "API documentation",
    mimeType: "text/markdown",
  },
  async (uri) => ({
    contents: [
      {
        uri: uri.href,
        mimeType: "text/markdown",
        text: "# API Documentation\n...",
      },
    ],
  })
);

Integrating with an Internal API

server.tool(
  "get_ticket",
  "Look up a support ticket",
  {
    ticket_id: z.string().describe("Ticket ID"),
  },
  async ({ ticket_id }) => {
    const response = await fetch(
      `${process.env.TICKETING_API_URL}/tickets/${ticket_id}`,
      {
        headers: {
          Authorization: `Bearer ${process.env.TICKETING_API_TOKEN}`,
          "X-On-Behalf-Of": getUserContext().userId, // User identity
        },
      }
    );

    if (!response.ok) {
      return {
        content: [
          {
            type: "text",
            text: "Ticket not found or access denied",
          },
        ],
      };
    }

    const ticket = await response.json();
    return {
      content: [{ type: "text", text: formatTicket(ticket) }],
    };
  }
);

Best Practices

  1. Descriptive Tool Names & Descriptions – The AI decides when to call a tool based on its description. Be specific.

  2. Typed Parameters – Always use Zod and .describe() for each parameter so the AI understands what's expected.

  3. Structured Responses – Return formatted text or markdown, not raw JSON. The AI processes text better than deeply nested structures.

  4. Rate Limiting – Implement circuit breakers to prevent tool abuse:

function checkRateLimit(userId: string, limit = 30, windowMs = 60000) {
  // Implementation in audit.ts
}
  1. Error Handling – Always return user-friendly error messages, never stack traces.

  2. Access Control – Scope all queries to the authenticated user. Never leak data across organizational boundaries.

  3. Audit Everything – Log every tool call with user ID, parameters, timestamp, and result size.

Troubleshooting

Database Connection Issues

# Test database connectivity
psql $INTERNAL_DB_URL -c "SELECT 1"

# Check environment variable
echo $INTERNAL_DB_URL

# Review logs
npm run dev 2>&1 | grep -i error

Authentication Issues

  • For development, requests without a Bearer token use demo credentials
  • In production, remove this fallback in src/auth-middleware.ts
  • Check token format: base64(userId:orgId:role)

Tool Not Found

  • Make sure you registered the tool in src/tools.ts
  • Verify the tool name matches what the AI is calling
  • Check tool descriptions are clear and specific

Claude Desktop Integration

  • Copy claude_desktop_config.json to your Claude config directory
  • Restart Claude Desktop
  • Check that the MCP server is running on the specified port
  • Review logs: npm run dev

Production Deployment

Docker

Build and run in Docker:

docker build -t internal-data-mcp:latest .
docker run -d \
  -p 3100:3100 \
  -e INTERNAL_DB_URL="postgres://..." \
  -e NODE_ENV=production \
  --name internal-data-mcp \
  internal-data-mcp:latest

Kubernetes

Basic deployment example:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: internal-data-mcp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: internal-data-mcp
  template:
    metadata:
      labels:
        app: internal-data-mcp
    spec:
      containers:
      - name: mcp
        image: internal-data-mcp:latest
        ports:
        - containerPort: 3100
        env:
        - name: INTERNAL_DB_URL
          valueFrom:
            secretKeyRef:
              name: mcp-secrets
              key: db-url
        livenessProbe:
          httpGet:
            path: /health/live
            port: 3100
          initialDelaySeconds: 10
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 3100
          initialDelaySeconds: 5

Environment-Specific Configs

Create .env.production:

INTERNAL_DB_URL=postgres://prod-user:secure-pass@prod-db.internal:5432/internal_data
PORT=3100
NODE_ENV=production

Security Considerations

  1. Authentication – Always use HTTPS in production and validate tokens
  2. Authorization – Enforce role-based access control at the tool level
  3. Data Filtering – Filter sensitive fields based on user role
  4. Rate Limiting – Prevent abuse and brute-force attacks
  5. Logging – Maintain complete audit trails for compliance
  6. Network – Isolate the MCP server from the public internet if possible
  7. Secrets – Store credentials in environment variables or secure secret managers
  8. Dependencies – Keep npm packages updated for security patches

Contributing

To extend this server:

  1. Add database queries to src/db.ts
  2. Register tools in src/tools.ts
  3. Add resources in src/resources.ts
  4. Update access control in src/auth-middleware.ts
  5. Test with npm run dev
  6. Build and verify: npm run build && npm start

License

MIT

Resources

Support

For issues, questions, or contributions, refer to the project repository or contact the development team.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选