Skip to main content
Glama
kulvir88

WWIDE MCP Server

by kulvir88
README.md
# WWIDE MCP Server

Model Context Protocol (MCP) server for WWIDE Events, providing AI agents access to LinkedIn, Salesforce, and Xero.

## Features

- **LinkedIn**: Search people/companies, get profiles and company info
- **Salesforce**: SOQL queries, CRUD operations on any object
- **Xero**: Invoices, contacts, chart of accounts, create invoices

## Quick Start

### 1. Install Dependencies

```bash
# Create virtual environment
python -m venv venv
source venv/bin/activate  # Linux/macOS
# or: venv\Scripts\activate  # Windows

# Install dependencies
pip install -r requirements.txt
```

### 2. Configure Environment

Copy `.env.example` to `.env` and fill in your credentials (or use existing `.env`):

```bash
cp .env.example .env
```

### 3. Run the Server

**For local AI clients (Claude Desktop, etc.):**
```bash
python -m wwide_mcp
# or
python __main__.py
```

**For remote access (HTTP/SSE):**
```bash
python -m wwide_mcp --transport sse --port 8000
```

## OAuth Setup

LinkedIn uses cookies (already configured), but Salesforce and Xero require OAuth authorization.

### First-Time Authorization

1. **Start the OAuth callback server** (in a separate terminal):
   ```bash
   python oauth_server.py
   ```

2. **Get auth URLs** using the MCP tools:
   - `salesforce_get_auth_url()` → visit URL, authorize, copy code
   - `xero_get_auth_url()` → visit URL, authorize, copy code

3. **Exchange codes for tokens**:
   - `salesforce_exchange_code(code="...")` 
   - `xero_exchange_code(code="...")`

4. Tokens are saved to `./tokens/` and auto-refresh.

## Claude Desktop Configuration

Add to `~/.config/claude/config.json` (Linux) or `~/Library/Application Support/Claude/config.json` (macOS):

```json
{
  "mcpServers": {
    "wwide": {
      "command": "python",
      "args": ["-m", "wwide_mcp"],
      "cwd": "/path/to/wwide-mcp-server",
      "env": {}
    }
  }
}
```

## Available Tools

### Health & Status
- `health_check()` - Check all service connections

### LinkedIn
- `linkedin_search_people(keywords, limit, company, title)`
- `linkedin_search_companies(keywords, limit)`
- `linkedin_get_profile(profile_id)`
- `linkedin_get_company(company_id)`

### Salesforce
- `salesforce_get_auth_url()` - Get OAuth URL
- `salesforce_exchange_code(code)` - Complete OAuth
- `salesforce_query(soql)` - Run SOQL query
- `salesforce_get_record(object_name, record_id, fields)`
- `salesforce_create_record(object_name, data)`
- `salesforce_update_record(object_name, record_id, data)`
- `salesforce_describe_object(object_name)`
- `salesforce_list_objects()`

### Xero
- `xero_get_auth_url()` - Get OAuth URL
- `xero_exchange_code(code)` - Complete OAuth
- `xero_get_invoices(status, contact_id, limit)`
- `xero_get_contacts(search, limit)`
- `xero_get_contact(contact_id)`
- `xero_create_invoice(contact_id, line_items, ...)`
- `xero_get_accounts(account_type)`
- `xero_get_organisation()`

## Project Structure

```
wwide-mcp-server/
├── __main__.py          # Entry point
├── oauth_server.py      # OAuth callback handler
├── requirements.txt     # Dependencies
├── .env                 # Credentials (git-ignored)
├── tokens/              # OAuth tokens (git-ignored)
└── src/
    ├── __init__.py
    ├── config.py        # Settings management
    ├── server.py        # Main MCP server
    └── services/
        ├── __init__.py
        ├── linkedin.py  # LinkedIn client
        ├── salesforce.py # Salesforce client
        └── xero.py      # Xero client
```

## Security Notes

- Never commit `.env` or `tokens/` to git
- LinkedIn cookies expire periodically - refresh when needed
- OAuth tokens auto-refresh but may need re-authorization if revoked
- Run on localhost only unless behind a secure reverse proxy

## Troubleshooting

**"Not authenticated" errors:**
- Run OAuth flow for the service (see OAuth Setup above)

**LinkedIn "401 Unauthorized":**
- Cookies have expired - get fresh `li_at` and `JSESSIONID` from browser

**Salesforce "INVALID_SESSION_ID":**
- Re-run OAuth flow: `salesforce_get_auth_url()` → authorize → `salesforce_exchange_code()`

**Xero "token_expired":**
- Usually auto-refreshes, but if persistent: re-run OAuth flow

---

*WWIDE Events - Agentic Transformation*