Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Dependencies
node_modules
npm-debug.log

# Build output
dist

# Tests
src/tests
*.test.ts
coverage

# Git
.git
.gitignore

# Documentation
*.md
!README.md

# IDE
.vscode
.idea
.cursor

# Environment files
.env
.env.local
.env.*.local

# macOS
.DS_Store

# Logs
logs
*.log

# Temporary files
tmp
temp
*.tmp
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ logs
data
coverage
.claude
.smithery
45 changes: 44 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,57 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
```bash
npm install # Install dependencies
npm run build # Compile TypeScript to ./dist
npm start # Start the server
npm start # Start the server in stdio mode (default)
npm run start:http # Start the server in HTTP mode on port 3000
npm run watch # Development build with file watching
npm run debug # Debug with MCP inspector
npm test # Run tests
npm run test:watch # Run tests with file watching
npm run test:coverage # Run tests with coverage report
```

## Running the Server

### Stdio Mode (Local/Default)
The default mode runs the server using stdio transport for local MCP clients:
```bash
npm start
# or
node dist/index.js
```

### HTTP Mode (Remote Hosting)
Run as an HTTP server with SSE (Server-Sent Events) transport:
```bash
# Default port 3000
npm run start:http

# Custom port
node dist/index.js --http --port 8080
```

When running in HTTP mode, the following endpoints are available:
- `POST /sse` - MCP SSE endpoint for client connections
- `GET /health` - Health check endpoint
- `POST /message` - Message endpoint (handled by SSE transport)

### Docker Mode
Run as a Docker container (runs HTTP mode on port 80 by default):
```bash
# Build and run
docker build -t ynab-mcp-server .
docker run -d -p 80:80 -e YNAB_API_TOKEN=your_token --name ynab-mcp ynab-mcp-server

# Health check
curl http://localhost/health

# View logs
docker logs ynab-mcp

# Map to different host port
docker run -d -p 3000:80 -e YNAB_API_TOKEN=your_token --name ynab-mcp ynab-mcp-server
```

## Git Best Practices

ALWAYS use conventional commits format (Refer to https://www.conventionalcommits.org/en/v1.0.0/) when creating git commit messages.
Expand Down
12 changes: 4 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@ COPY . .
# Build the project
RUN npm run build

# Expose any port if required (not strictly necessary for stdio based MCP)
# Expose port 80 for HTTP server
EXPOSE 80

# Set environment variable placeholder (user should override these values in production)
ENV YNAB_API_TOKEN=""
# optional:
# ENV YNAB_BUDGET_ID=""

# Define the command to run your app using node
CMD ["node", "dist/index.js"]
# Run the HTTP server by default on port 80
CMD ["node", "dist/index.js", "--http", "--port", "80"]
150 changes: 142 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,110 @@ npm install
# Build the project
npm run build

# Run locally with stdio (default)
npm start

# Run as HTTP server (for remote hosting)
npm run start:http

# Run as HTTP server on custom port
node dist/index.js --http --port 8080
```

## Deployment Modes

### Local Mode (Stdio)
The default mode uses stdio transport for local MCP clients like Claude Desktop:
```bash
npm start
```

### HTTP Server Mode
Run as an HTTP server with SSE (Server-Sent Events) transport for remote hosting:
```bash
# Default port 3000
npm run start:http

# Custom port
node dist/index.js --http --port 8080
```

When running in HTTP mode, the server exposes:
- `POST /sse` - MCP SSE endpoint for client connections
- `GET /health` - Health check endpoint (returns `{"status": "ok", "version": "0.1.2"}`)
- `POST /message` - Message endpoint (handled by SSE transport)

Example health check:
```bash
curl http://localhost:3000/health
```

#### Connecting MCP Clients to HTTP Server

The HTTP/SSE mode is designed for MCP clients that support remote server connections. Clients connect to the SSE endpoint:

```
POST http://localhost:3000/sse
```

> **Note:** Claude Desktop currently only supports local stdio-based MCP servers (spawned via `command`). Use the [Local Development](#local-development) configuration for Claude Desktop. HTTP mode is intended for other MCP clients, web applications, or remote hosting scenarios.

### Docker Deployment
Run the server in a Docker container with HTTP mode (runs on port 80 by default):

```bash
# Build the Docker image (builds for linux/amd64)
docker build -t ynab-mcp-server .

# Run the container on port 80
docker run -d \
-p 80:80 \
-e YNAB_API_TOKEN=your_token_here \
-e YNAB_BUDGET_ID=your_budget_id \
--name ynab-mcp \
ynab-mcp-server

# Check health
curl http://localhost/health

# View logs
docker logs ynab-mcp

# Stop and remove
docker stop ynab-mcp
docker rm ynab-mcp
```

Map to different host port (e.g., 3000):
```bash
docker run -d \
-p 3000:80 \
-e YNAB_API_TOKEN=your_token_here \
--name ynab-mcp \
ynab-mcp-server

# Access on port 3000
curl http://localhost:3000/health
```

Custom container port:
```bash
docker run -d \
-p 8080:8080 \
-e YNAB_API_TOKEN=your_token_here \
--name ynab-mcp \
ynab-mcp-server \
node dist/index.js --http --port 8080
```

**Multi-platform builds:**
The Dockerfile is configured for linux/amd64 by default. To build for other platforms:
```bash
# Build for multiple platforms using buildx
docker buildx build --platform linux/amd64,linux/arm64 -t ynab-mcp-server .

# Build for specific platform
docker buildx build --platform linux/arm64 -t ynab-mcp-server .
```

## Project Structure
Expand Down Expand Up @@ -176,35 +280,65 @@ npx -y @smithery/cli install @calebl/ynab-mcp-server --client claude

### Local Development

Add this configuration to your Claude Desktop config file:
To set up the MCP server locally with Claude Desktop:

**MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
**1. Clone and build the project:**
```bash
git clone https://github.com/calebl/ynab-mcp-server.git
cd ynab-mcp-server
npm install
npm run build
```

**2. Get your YNAB Personal Access Token:**
- Go to https://app.ynab.com/settings/developer
- Create a new Personal Access Token
- Copy the token (you'll only see it once)

**3. Add the server to Claude Desktop:**

Open your Claude Desktop config file:
- **MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`

Add the following configuration (replace the placeholders with your values):

```json
{
"mcpServers": {
"ynab-mcp-server": {
"command": "node",
"args":["/absolute/path/to/ynab-mcp-server/dist/index.js"]
"args": ["/absolute/path/to/ynab-mcp-server/dist/index.js"],
"env": {
"YNAB_API_TOKEN": "your_ynab_personal_access_token"
}
}
}
}
```

### After Publishing
**4. Restart Claude Desktop** to load the new MCP server.

**5. Verify the connection** by asking Claude: "List my YNAB budgets"

> **Tip:** You can optionally add `"YNAB_BUDGET_ID": "your_default_budget_id"` to the `env` object to set a default budget, so you don't have to specify it with each request.

### After Publishing (via npx)

Add this configuration to your Claude Desktop config file:

**MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
- **MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`

```json
{
"mcpServers": {
"ynab-mcp-server": {
"command": "npx",
"args": ["ynab-mcp-server"]
"args": ["-y", "ynab-mcp-server"],
"env": {
"YNAB_API_TOKEN": "your_ynab_personal_access_token"
}
}
}
}
Expand Down
Loading