bach-concur-mcp-server 1.0.0
A Model Context Protocol (MCP) server that integrates with SAP Concur expense management system
License: MIT
Requires Python: >=3.10
Keywords: ai-integration, expense-management, fastmcp, mcp, model-context-protocol, sap-concur

# Bach Concur MCP Server

A **Model Context Protocol (MCP)** server that integrates with **SAP Concur** expense management system, built with **FastMCP** and **fast-agent**.

[![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](https://github.com/rongquanfeng/concur-mcp-server)
[![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![PyPI](https://img.shields.io/pypi/v/bach-concur-mcp-server.svg)](https://pypi.org/project/bach-concur-mcp-server/)

## 📁 Project Structure

```
bach-concur-mcp-server/
├── src/
│   └── bach_concur_mcp/          # Main package
│       ├── __init__.py
│       ├── server.py              # Server entry point
│       ├── sdk.py                 # Concur SDK wrapper
│       └── tools/                 # MCP tools
│           ├── __init__.py
│           ├── reports.py         # Report management tools
│           ├── expenses.py        # Expense management tools
│           └── utils.py           # Utility tools
├── tests/                         # Test suite
├── examples/                      # Configuration examples
│   ├── claude_desktop_config.json
│   ├── fastagent_config.yaml
│   └── env.template
├── pyproject.toml                 # Package configuration
└── README.md
```

## 🚀 Features

- **📊 List Expense Reports**: Retrieve and analyze your Concur expense reports
- **🔍 Report Details**: Get detailed information about specific reports
- **💰 Expense Management**: Create, update, and delete expense entries
- **🤖 AI-Powered Analysis**: Claude Sonnet 4.0 provides intelligent expense insights
- **🔌 MCP Integration**: Works with Claude Desktop and fast-agent
- **🔐 Secure Authentication**: OAuth2 password grant flow with Concur API
- **⚡ uvx Support**: Run instantly without installation

## 📋 Prerequisites

- **Python 3.10+**
- **SAP Concur Developer Account** with API credentials
- **Anthropic API Key** (for AI analysis with fast-agent)
- **uv** or **uvx** package manager (recommended)

## 🔧 Installation & Usage

### Option 1: uvx (Recommended - No Installation Required)

The easiest way to run the Concur MCP server is with **uvx**:

#### Run from PyPI (Recommended)

```bash
# Run directly from PyPI - no installation needed!
uvx bach-concur-mcp-server \
  --client-id "your_client_id" \
  --client-secret "your_client_secret" \
  --username "your_username" \
  --password "your_password"
```

#### Run from Local Directory

```bash
# Clone the repository first
git clone https://github.com/rongquanfeng/concur-mcp-server.git
cd concur-mcp-server

# Option A: Using command-line arguments (recommended)
uvx --from . bach-concur-mcp-server \
  --client-id "your_client_id" \
  --client-secret "your_client_secret" \
  --username "your_username" \
  --password "your_password"

# Option B: Using environment variables
export CONCUR_CLIENT_ID="your_client_id"
export CONCUR_CLIENT_SECRET="your_client_secret"
export CONCUR_USERNAME="your_username"
export CONCUR_PASSWORD="your_password"
uvx --from . bach-concur-mcp-server
```

#### Run Directly from GitHub

```bash
# Option A: Using command-line arguments (recommended)
uvx --from git+https://github.com/rongquanfeng/concur-mcp-server bach-concur-mcp-server \
  --client-id "your_client_id" \
  --client-secret "your_client_secret" \
  --username "your_username" \
  --password "your_password"

# Option B: Using environment variables
export CONCUR_CLIENT_ID="your_client_id"
export CONCUR_CLIENT_SECRET="your_client_secret"
export CONCUR_USERNAME="your_username"
export CONCUR_PASSWORD="your_password"
uvx --from git+https://github.com/rongquanfeng/concur-mcp-server bach-concur-mcp-server
```

#### Command-Line Help

```bash
# View all available options
uvx --from . bach-concur-mcp-server --help

# Check version
uvx --from . bach-concur-mcp-server --version
```

### Option 2: Traditional Installation

```bash
# Clone the repository
git clone https://github.com/bachstudio/concur-mcp-server.git
cd concur-mcp-server

# Using uv (recommended)
uv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
uv pip install -r requirements.txt

# Or using pip
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
pip install -r requirements.txt

# Configure environment variables
cp env.template .env
nano .env  # Edit with your credentials

# Run the server
python concur_mcp_server_robust.py
```

### Option 3: Install as Package

```bash
# Install from PyPI (Recommended)
pip install bach-concur-mcp-server

# Or install from GitHub
pip install git+https://github.com/rongquanfeng/concur-mcp-server

# Or install from local directory for development
pip install -e .

# Run the installed command
bach-concur-mcp-server \
  --client-id "your_client_id" \
  --client-secret "your_client_secret" \
  --username "your_username" \
  --password "your_password"
```

## 🔌 Integration with AI Assistants

### Claude Desktop (Using uvx)

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

#### Method 1: From PyPI (Recommended)

```json
{
  "mcpServers": {
    "concur-reports": {
      "command": "uvx",
      "args": [
        "bach-concur-mcp-server",
        "--client-id",
        "your_client_id",
        "--client-secret",
        "your_client_secret",
        "--username",
        "your_username",
        "--password",
        "your_password"
      ]
    }
  }
}
```

#### Method 2: From GitHub

```json
{
  "mcpServers": {
    "concur-reports": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/rongquanfeng/concur-mcp-server",
        "bach-concur-mcp-server",
        "--client-id",
        "your_client_id",
        "--client-secret",
        "your_client_secret",
        "--username",
        "your_username",
        "--password",
        "your_password"
      ]
    }
  }
}
```

#### Method 3: Using Environment Variables

```json
{
  "mcpServers": {
    "concur-reports": {
      "command": "uvx",
      "args": ["bach-concur-mcp-server"],
      "env": {
        "CONCUR_CLIENT_ID": "your_client_id",
        "CONCUR_CLIENT_SECRET": "your_client_secret",
        "CONCUR_USERNAME": "your_username",
        "CONCUR_PASSWORD": "your_password"
      }
    }
  }
}
```

### Claude Desktop (Traditional Method)

```json
{
  "mcpServers": {
    "concur-reports": {
      "command": "python",
      "args": ["/path/to/concur-mcp-server/concur_mcp_server_robust.py"],
      "env": {
        "CONCUR_CLIENT_ID": "your_client_id",
        "CONCUR_CLIENT_SECRET": "your_client_secret",
        "CONCUR_USERNAME": "your_username",
        "CONCUR_PASSWORD": "your_password"
      }
    }
  }
}
```

### Fast-Agent Integration

Edit `fastagent.config.yaml`:

#### Using uvx

```yaml
default_model: "sonnet"

mcp:
  servers:
    concur_reports:
      command: "uvx"
      args:
        - "--from"
        - "git+https://github.com/rongquanfeng/concur-mcp-server"
        - "bach-concur-mcp-server"
      env:
        CONCUR_CLIENT_ID: "your_client_id"
        CONCUR_CLIENT_SECRET: "your_client_secret"
        CONCUR_USERNAME: "your_username"
        CONCUR_PASSWORD: "your_password"
```

#### Traditional Method

```yaml
default_model: "sonnet"

mcp:
  servers:
    concur_reports:
      command: "python"
      args: ["/path/to/concur_mcp_server_robust.py"]
      env:
        CONCUR_CLIENT_ID: "your_client_id"
        CONCUR_CLIENT_SECRET: "your_client_secret"
        CONCUR_USERNAME: "your_username"
        CONCUR_PASSWORD: "your_password"
```

Then run with fast-agent:

```bash
# Quick analysis
uv run concur_expense_agent.py --agent ConcurExpenseAgent --message "Analyze my expense reports"

# Interactive mode
uv run concur_expense_agent.py

# Use different models
uv run concur_expense_agent.py --model sonnet --agent ConcurExpenseAgent --message "Detailed analysis"
```

## 🔨 Available Tools

| Tool                         | Description                                           |
| ---------------------------- | ----------------------------------------------------- |
| **Report Management**        |                                                       |
| `list_concur_reports`        | Retrieve expense reports with optional limit          |
| `get_concur_report_details`  | Get detailed information about a specific report      |
| `create_concur_report`       | Create a new expense report                           |
| **Expense Management**       |                                                       |
| `list_concur_expenses`       | List expenses in a report                             |
| `get_concur_expense_details` | Get detailed info for a specific expense              |
| `create_concur_expense`      | Create a new expense entry (defaults to INCTS)        |
| `update_concur_expense`      | Update an existing expense                            |
| `delete_concur_expense`      | Delete an expense entry                               |
| **Utility Tools**            |                                                       |
| `get_concur_expense_types`   | Get available expense types                           |
| `get_concur_payment_types`   | Get available payment types                           |
| `test_concur_connection`     | Test the connection to Concur API                     |
| `get_concur_api_guide`       | Get comprehensive API documentation and code examples |

## 📊 Example AI Analysis

The AI agent provides intelligent insights like:

```
## Expense Reports Summary

### Total Value: $4,401.52 across 7 reports

### Status Breakdown:
- 5 reports Submitted & Pending Approval ($2,521.00)
- 2 reports Not Submitted ($1,880.52)

### Recommendations:
1. Follow up on old pending reports
2. Submit draft reports worth $1,880.52
3. Review approval process workflow
```

## ⚙️ Configuration Options

The server supports two ways to provide credentials: **command-line arguments** or **environment variables**.

### Command-Line Arguments (Recommended for Direct Usage)

When running the server directly with `uvx` or `python`, you can pass credentials as command-line arguments:

```bash
bach-concur-mcp-server \
  --client-id "your_client_id" \
  --client-secret "your_client_secret" \
  --username "your_username" \
  --password "your_password"
```

**Available Arguments:**

| Argument          | Description              | Environment Variable Override |
| ----------------- | ------------------------ | ----------------------------- |
| `--client-id`     | Concur API client ID     | `CONCUR_CLIENT_ID`            |
| `--client-secret` | Concur API client secret | `CONCUR_CLIENT_SECRET`        |
| `--username`      | Concur username          | `CONCUR_USERNAME`             |
| `--password`      | Concur password          | `CONCUR_PASSWORD`             |
| `--help`          | Show help message        | -                             |
| `--version`       | Show version information | -                             |

**Note:** Command-line arguments take precedence over environment variables.

## 🔐 Environment Variables

The following environment variables are required (when not using command-line arguments):

| Variable               | Description                                  |
| ---------------------- | -------------------------------------------- |
| `CONCUR_CLIENT_ID`     | Your Concur app client ID                    |
| `CONCUR_CLIENT_SECRET` | Your Concur app client secret                |
| `CONCUR_USERNAME`      | Your Concur username                         |
| `CONCUR_PASSWORD`      | Your Concur password                         |
| `ANTHROPIC_API_KEY`    | Your Anthropic API key (for fast-agent only) |

### Setting Up Environment Variables

#### For Local Development

Create a `.env` file in the project root:

```bash
CONCUR_CLIENT_ID=your_client_id
CONCUR_CLIENT_SECRET=your_client_secret
CONCUR_USERNAME=your_username
CONCUR_PASSWORD=your_password
ANTHROPIC_API_KEY=your_anthropic_api_key
```

#### For uvx Usage

Export environment variables before running:

```bash
export CONCUR_CLIENT_ID="your_client_id"
export CONCUR_CLIENT_SECRET="your_client_secret"
export CONCUR_USERNAME="your_username"
export CONCUR_PASSWORD="your_password"
```

Or pass them inline:

```bash
CONCUR_CLIENT_ID="..." CONCUR_CLIENT_SECRET="..." uvx --from . bach-concur-mcp-server
```

## 🧪 Testing

### Test the MCP Server

```bash
# Test connection
python -c "from concur_expense_sdk import ConcurExpenseSDK; sdk = ConcurExpenseSDK(); print(sdk.test_connection())"

# Test with fast-agent
fast-agent check
```

### Test uvx Installation

```bash
# Test local installation
uvx --from . bach-concur-mcp-server --help

# Test from GitHub (if pushed)
uvx --from git+https://github.com/rongquanfeng/concur-mcp-server bach-concur-mcp-server --help
```

## 🏗️ Architecture

```
┌─────────────────┐
│  Claude / AI    │
│    Assistant    │
└────────┬────────┘
         │
         │ MCP Protocol
         │
┌────────▼────────┐
│   FastMCP       │
│   MCP Server    │
└────────┬────────┘
         │
         │ REST API
         │
┌────────▼────────┐
│   SAP Concur    │
│   Expense API   │
└─────────────────┘
```

## 🚨 Security Notes

- **Never commit** `.env`, `fastagent.secrets.yaml`, or any files with credentials
- Use **environment variables** or **secure secret management** in production
- The `.gitignore` file protects sensitive files from being committed
- When using uvx, be careful not to expose credentials in command history

## 📚 Documentation

- [FastMCP Documentation](https://gofastmcp.com/)
- [fast-agent Documentation](https://fast-agent.ai/)
- [Model Context Protocol Specification](https://modelcontextprotocol.io/)
- [SAP Concur API Documentation](https://developer.concur.com/)
- [Project Documentation (LobeHub)](https://lobehub.com/zh/mcp/yourusername-concur-mcp-server)

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

## 🙋‍♂️ Support

If you encounter issues:

1. Check the [Issues page](https://github.com/rongquanfeng/concur-mcp-server/issues)
2. Review the [fast-agent documentation](https://fast-agent.ai/)
3. Ensure your Concur API credentials are correct
4. Verify your environment variables are properly set

## 🏗️ Built With

- **[FastMCP](https://gofastmcp.com/)** - MCP server framework
- **[fast-agent](https://fast-agent.ai/)** - AI agent framework
- **[Claude Sonnet 4.0](https://www.anthropic.com/)** - AI analysis
- **[SAP Concur API](https://developer.concur.com/)** - Expense data source
- **[uv/uvx](https://docs.astral.sh/uv/)** - Fast Python package installer

## 🌟 Credits

Developed by **bachstudio**

---

**Note**: This is a community project and is not officially affiliated with or endorsed by SAP Concur.