Skip to main content
Glama
scitara-cto

Dynamic MCP Server

by scitara-cto
README.md
# Dynamic MCP Server Framework

A flexible, extensible framework for building Model Context Protocol (MCP) servers with modern API key authentication, user management, and dynamic tool sharing.

---

## 🚀 Overview

Dynamic MCP Server enables secure, user-aware, and extensible AI tool servers. It supports:

- **API key-based authentication** (simple, compatible with all MCP clients)
- **User management and authorization** (MongoDB-backed)
- **Session-based, per-user tool loading**
- **Tool sharing and fine-grained access control**
- **Extensible HTTP and database layers for downstream projects**

---

## 🌟 Key Features

- **Dynamic Tool Management**: Create, delete, and authorize tools at runtime—tools are not limited to static definitions at startup or in code. This enables true runtime extensibility and is a primary differentiator from most other MCP servers.
- **User Management**: Add, update, delete, and list users; admin bootstrapping; role-based access.
- **Tool Sharing**: Share tools with other users, manage access levels, and receive real-time updates.
- **Modern Auth**: Simple API key authentication, MongoDB for authorization.
- **Extensibility**: Add custom HTTP routes and MongoDB collections in downstream projects.
- **Session-based Tool Loading**: Tools are loaded per user session, not globally.

---

## 🔑 Authentication (API Key)

- Each user is assigned a unique `apiKey` (generated automatically on user creation).
- To authenticate, clients must provide the `apiKey` via query parameter OR header:
  - **Query Parameter**: `?apiKey=your-key` or `?apikey=your-key`
  - **Header**: `x-apikey: your-key` or `apikey: your-key`
- **Streamable HTTP Transport (Modern)**: `/mcp?apiKey=...` or `/mcp` with header
- The server authenticates the user by looking up the `apiKey` in the database.

---

## 🚀 Transport Protocols

Dynamic MCP Server supports both legacy and modern MCP transport protocols:

### Streamable HTTP Transport
- **Protocol Version**: 2025-03-26
- **Endpoint**: `/mcp`
- **Features**: Modern, efficient, single-endpoint design
- **Authentication**: Query parameter `?apiKey=your-key` OR header `x-apikey: your-key`
- **Usage**: Recommended for new integrations

---

## � Documentation

- [Getting Started](./docs/getting-started.md)
- [Transport Protocols](./docs/transport-protocols.md)
- [User Management](./docs/user-management.md)
- [Tool Management & Sharing](./docs/tool-management.md)
- [Authentication & Authorization](./docs/authentication.md)
- [Extending the Server (HTTP & DB)](./docs/extending.md)
- [API Reference](./docs/api-reference.md)
- [Examples](./docs/examples.md)
- [Extending the Server: Creating Handler & Tool Packages](docs/tool_authoring.md)
- [Test Patterns & Mocking Strategies](docs/test_patterns.md)

> **Tool Visibility Model:**
> All tools are visible to users by default. Users can hide tools from their view using the `hide-tool` and `unhide-tool` actions. See [User Management](./docs/user-management.md) and [Tool Management & Sharing](./docs/tool-management.md) for details.

---

## 🛠️ Quick Start

See [Getting Started](./docs/getting-started.md) for installation and basic usage.

---

## 📝 Contributing

Contributions are welcome! See [the documentation](./docs/) for more details.

## 📄 License

MIT

---

## 🧩 Handler & Tool Registration (New Pattern)

Tools are now registered via **handler packages**. Each handler package groups related tools and provides a handler function for tool execution. This is the recommended pattern for extensibility and maintainability.

**Example:**

```js
const myHandlerPackage = {
  name: "my-domain",
  tools: [
    {
      name: "my-tool",
      description: "A custom tool",
      inputSchema: {
        /* ... */
      },
      handler: { type: "my-domain", config: {} },
      rolesPermitted: ["user", "admin"],
    },
    // ...more tools...
  ],
  handler: async (args, context, config, toolName) => {
    // Dispatch logic based on toolName, if needed
  },
};

const server = new DynamicMcpServer({ name: "my-mcp", version: "1.0.0" });
await server.start();
await server.registerHandler(myHandlerPackage);
```

See [Getting Started](./docs/getting-started.md) and [Examples](./docs/examples.md) for more details.

---

## 🧩 Tool Argument Mapping (config.args)

When defining a tool, you can use the `config.args` field to map user-supplied tool options (from inputSchema) to the arguments your action handler expects. This mapping supports:

- Literal values (e.g., `"country": "US"`)
- Template variables (e.g., `"city": "{{location}}"`)
- Nested objects and arrays (all templates are resolved recursively)

**Example:**

```js
handler: {
  type: "weather-tools",
  config: {
    url: "https://api.openweathermap.org/data/2.5/weather",
    args: {
      queryParams: {
        appid: "{{OPENWEATHER_API_KEY}}",
        q: "{{location}}",
        units: "{{units}}"
      }
    }
  }
}
```

When the tool is called, the system automatically resolves all `{{...}}` templates in config.args using the tool input and environment variables. The handler receives the merged and resolved arguments—no manual mapping is needed.

See [Tool Authoring](./docs/tool_authoring.md) for full details and examples.

---

```

```