files-mcp-ts
by LiviuBirjega
README.md
# files-mcp-ts
A lightweight [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server implemented in TypeScript for performing basic file operations. This server provides secure file system access through the MCP interface, allowing AI assistants and other MCP clients to read, write, and list files in a controlled manner.
## Overview
This MCP server implements the Model Context Protocol specification to provide file system operations. The main `FilesMcpTs` class in `src/index.ts` creates an MCP server that:
- **Tools**: Exposes three file operation tools (`read_file`, `list_files`, `write_file`)
- **Resources**: Provides a `file://current-directory` resource for directory listings
- **Transport**: Uses stdio transport for communication with MCP clients
- **Architecture**: Clean TypeScript implementation with proper error handling and type safety
The server is designed to be spawned by MCP clients and communicates via standard input/output streams.
## Project Structure
```
files-mcp-ts/
├── src/
│ └── index.ts # Main MCP server implementation
├── dist/ # Compiled JavaScript output (generated)
├── node_modules/ # Dependencies (generated)
├── .gitignore # Git ignore rules
├── package.json # Package configuration and dependencies
├── pnpm-lock.yaml # Dependency lock file
├── tsconfig.json # TypeScript compiler configuration
└── README.md # This documentation
```
## Features
### Tools
- **`read_file`** – Read the contents of any text file by providing its path
- **`list_files`** – List all files and directories within a specified directory
- **`write_file`** – Write or overwrite text content to a file (creates directories if needed)
### Resources
- **`file://current-directory`** – Provides a real-time listing of files in the server's working directory
### Technical Features
- **Type Safety** – Full TypeScript implementation with strict type checking
- **Error Handling** – Comprehensive error handling with proper MCP error codes
- **Async Operations** – Non-blocking file operations using Node.js fs/promises
- **Input Validation** – Parameter validation for all tool calls
## Prerequisites
- **Node.js 18.x or newer** – Required for ES2022 features and MCP SDK compatibility
- **pnpm** – Recommended package manager (or npm/yarn as alternatives)
- **TypeScript knowledge** – For development and customization
## Installation & Setup
1. **Install dependencies:**
```bash
pnpm install
```
2. **Build the project:**
```bash
pnpm build
```
This compiles TypeScript sources from `src/` to JavaScript in `dist/`.
3. **Verify installation:**
```bash
pnpm start
```
You should see: `Simple Files MCP Server running on stdio`
## Usage
### Development Mode
```bash
pnpm dev
```
Runs the server directly from TypeScript source with hot reloading via `tsx`.
### Production Mode
```bash
pnpm start
# or
npx files-mcp-ts
```
Runs the compiled JavaScript version from `dist/`.
### Integration with MCP Clients
The server communicates via stdio and is designed to be spawned by MCP clients. It's not meant to be run interactively but rather integrated into MCP-compatible applications.
## MCP Client Integration
### Claude Desktop Configuration
Add this server to your Claude Desktop configuration file:
**Location:** `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)
```json
{
"mcpServers": {
"files-mcp-ts": {
"command": "node",
"args": ["/path/to/files-mcp-ts/dist/index.js"],
"workingDirectory": "/desired/working/directory"
}
}
}
```
### Alternative: Using pnpm
```json
{
"mcpServers": {
"files-mcp-ts": {
"command": "pnpm",
"args": ["exec", "files-mcp-ts"],
"workingDirectory": "/path/to/files-mcp-ts"
}
}
}
```
### Configuration Notes
- The `workingDirectory` determines where the `file://current-directory` resource points
- Ensure the path to the compiled `dist/index.js` is correct
- Restart Claude Desktop after configuration changes
### Windsurf IDE Configuration
Add this server to your Windsurf MCP configuration file:
**Location:** `%APPDATA%\Codeium\Windsurf\mcp_config.json` (Windows) or `~/.codeium/windsurf/mcp_config.json` (macOS/Linux)
```json
{
"mcpServers": {
"files-mcp-ts": {
"command": "node",
"args": [
"/path/to/files-mcp-ts/dist/index.js"
]
}
}
}
```
**Note:** Use absolute paths and proper Windows path escaping (double backslashes) for the `args` parameter.
### Windsurf IDE Integration
Once configured, this MCP server integrates seamlessly with Windsurf IDE. You'll see:
1. **Server Status Panel** - Shows `files-mcp-ts` as enabled with a green status indicator
2. **Available Tools Display** - Lists all 3 tools (`read_file`, `list_files`, `write_file`) with descriptions
3. **Automatic Tool Discovery** - Windsurf automatically detects and registers your server's capabilities
4. **Ready-to-Use Integration** - AI assistants in Windsurf can immediately use your file operations
**Configuration in Windsurf:**
The server appears in the MCP configuration panel where you can:
- Toggle the server on/off with the "Enabled" switch
- View all available tools and their descriptions
- Access configuration options via the "Configure" button
- Monitor connection status in real-time
## API Reference
### Tools
#### `read_file`
Reads and returns the contents of a text file.
**Parameters:**
- `path` (string, required) – File path to read
**Returns:** File contents as text
**Example:**
```json
{
"name": "read_file",
"arguments": {
"path": "./example.txt"
}
}
```
#### `list_files`
Lists all files and directories in the specified directory.
**Parameters:**
- `directory` (string, required) – Directory path to list
**Returns:** Newline-separated list of file/directory names
**Example:**
```json
{
"name": "list_files",
"arguments": {
"directory": "./src"
}
}
```
#### `write_file`
Writes text content to a file, creating or overwriting as needed.
**Parameters:**
- `path` (string, required) – File path to write to
- `content` (string, required) – Text content to write
**Returns:** Success confirmation message
**Example:**
```json
{
"name": "write_file",
"arguments": {
"path": "./output.txt",
"content": "Hello, World!"
}
}
```
### Resources
#### Understanding Resources vs Tools
**Resources** are static or dynamic content that MCP clients can access directly, while **Tools** are functions that clients can call with parameters.
| Aspect | Tools | Resources |
|--------|-------|-----------|
| **Usage** | Call with parameters | Request by URI |
| **Flexibility** | Can target any file/directory | Fixed to server's working directory |
| **Parameters** | Required | None |
| **Purpose** | Perform actions | Provide information |
| **Example** | `list_files("./src")` | `file://current-directory` |
**Tool Examples:**
```json
// read_file - REQUIRES path parameter
{"name": "read_file", "arguments": {"path": "./example.txt"}}
// list_files - REQUIRES directory parameter
{"name": "list_files", "arguments": {"directory": "./src"}}
// write_file - REQUIRES path AND content parameters
{"name": "write_file", "arguments": {"path": "./new.txt", "content": "Hello!"}}
```
**Resource Example:**
```
URI: "file://current-directory"
Returns: "src\ndist\npackage.json\nREADME.md"
No parameters needed - just request the URI
```
#### `file://current-directory`
Provides a real-time listing of files in the server's working directory.
**URI:** `file://current-directory`
**MIME Type:** `text/plain`
**Content:** Newline-separated list of files and directories
**How it works:**
```typescript
// In src/index.ts - when a client requests the resource
if (uri === 'file://current-directory') {
const files = await fs.readdir('.'); // Read current directory
return {
contents: [{
uri,
mimeType: 'text/plain',
text: files.join('\n') // Return as newline-separated list
}]
};
}
```
**Example Output:**
If the server runs in a directory containing `src/`, `dist/`, `package.json`, `README.md`, the resource returns:
```
src
dist
package.json
README.md
```
**Key Benefits:**
- **Always current** - Reflects real-time directory state
- **Efficient** - No function call needed, just request the URI
- **Cacheable** - MCP clients can cache and refresh as needed
- **Different from `list_files` tool** - This resource shows the server's working directory, while the tool can list any specified directory
### How to Access Resources
**❌ Common Misconception:**
You cannot access resources by simply typing the URI like `file://current-directory` in a chat or browser. Resources are **MCP protocol endpoints**, not web URLs.
**✅ Correct Usage:**
Resources must be accessed through MCP clients:
**In Windsurf IDE or Claude Desktop:**
```
Ask the AI: "Show me the current directory resource from the MCP server"
```
The AI assistant will use the MCP interface to fetch the resource for you.
**In Your Own MCP Client Code:**
```javascript
// Example client implementation
const response = await mcpClient.readResource({
uri: "file://current-directory"
});
console.log(response.contents[0].text);
```
**Key Concept:**
- **Resource URI** = The "address" of the content (`file://current-directory`)
- **MCP Client** = The "postal service" that fetches it (Windsurf, Claude Desktop, etc.)
- **You** = The person requesting the content
Think of resources like internal API endpoints that only work through the MCP protocol, not as direct web URLs you can visit in a browser.
## Development
### Extending the Server
1. **Adding new tools:** Register additional handlers in the `setupToolHandlers()` method
2. **Adding new resources:** Register additional handlers in the `setupResourceHandlers()` method
3. **Modifying existing functionality:** Edit the respective handler functions in `src/index.ts`
### Development Workflow
1. Make changes to `src/index.ts`
2. Test with `pnpm dev` for immediate feedback
3. Build with `pnpm build` for production
4. Test the built version with `pnpm start`
### Code Quality
- The project uses TypeScript strict mode for type safety
- All file operations use async/await patterns
- Proper error handling with MCP-specific error codes
- Input validation for all tool parameters
### Security Considerations
- File paths are not sanitized by default – consider adding path validation for production use
- The server has access to the entire file system – run in a sandboxed environment if needed
- No authentication or authorization is implemented – suitable for trusted environments only
## Security & Access Control
### MCP Protocol Isolation
**Important:** MCP resources are **NOT accessible from outside** the MCP server ecosystem. This isolation is intentional and provides security benefits.
### What MCP Resources Are NOT:
- ❌ **Not web URLs** - Cannot access via HTTP/HTTPS requests
- ❌ **Not REST API endpoints** - No direct HTTP access
- ❌ **Not file system paths** - Cannot browse to them like files
- ❌ **Not network services** - No TCP/UDP ports exposed
### What MCP Resources ARE:
- ✅ **Internal protocol endpoints** - Only work within MCP ecosystem
- ✅ **Client-server communication** - Require MCP client to access
- ✅ **Stdio-based** - Communication over standard input/output
- ✅ **Process-to-process** - Server spawned by MCP client
### Security Architecture:
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Outside │ │ MCP Client │ │ MCP Server │
│ World │───▶│ (Windsurf/ │◄──▶│ (files-mcp-ts) │
│ │ │ Claude) │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
❌ ✅ ✅
Cannot access Can access Provides
resources directly via MCP protocol resources
```
### Security Benefits:
1. **No network exposure** - Server doesn't listen on network ports
2. **Controlled access** - Only authorized MCP clients can connect
3. **Process isolation** - Server runs as subprocess of client
4. **No direct file system exposure** - Resources mediated through MCP protocol
5. **Client-level authentication** - Access control handled by MCP client
6. **Sandboxing possible** - Client can restrict server capabilities
### External Access Considerations:
If external access is needed, you would need to build a separate HTTP bridge service, but this would defeat the security purpose of MCP's isolated design. The `file://current-directory` URI only has meaning **within the MCP context** - it's not a universal resource locator like HTTP URLs.
## Contributing
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
### Development Setup
1. Fork the repository
2. Clone your fork: `git clone <your-fork-url>`
3. Install dependencies: `pnpm install`
4. Make your changes
5. Test thoroughly with `pnpm dev`
6. Build and verify: `pnpm build && pnpm start`
7. Submit a pull request
## Related Resources
- [Model Context Protocol Specification](https://modelcontextprotocol.io/)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [Claude Desktop MCP Guide](https://docs.claude.com/en/docs/mcp)
TDQS
B3.4/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a clear, distinct purpose: listing directory contents, reading a file, and writing to a file. There is no overlap or ambiguity.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern with underscores: list_files, read_file, write_file. The pattern is uniform and predictable.
Tool Count4/5
With 3 tools, the set is minimal but still covers basic file operations. It is slightly thin but not unreasonable for a focused file server.
Completeness3/5
The toolset provides list, read, and write operations, but misses common file operations like delete, create directory, or rename. This leaves notable gaps for typical file management tasks.
Maintenance
ActivityInactive
ResponsivenessNo issues