Metadata-Version: 2.4
Name: lightbulb-mcp
Version: 0.6.2
Summary: MCP server for the Lightbulb Partners Agents platform — Claude Code, Codex, and Cursor integration
Project-URL: Homepage, https://agents.lightbulbpartners.com
Author-email: Lightbulb Partners <robbie.pasquale@lightbulbpartners.com>
Maintainer-email: Robbie Pasquale <robbie.pasquale@lightbulbpartners.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,ai,claude,claude-code,codex,cursor,lightbulb,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.25
Requires-Dist: mcp>=1.0
Requires-Dist: pydantic-settings>=2.6
Requires-Dist: pydantic>=2.10
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# Lightbulb MCP

MCP server and helper CLI for the [Lightbulb Partners Agents](https://agents.lightbulbpartners.com) platform. Connect your **Claude Code, Codex, or Cursor** account to your Lightbulb workspace — domain agents, code workspaces, connectors, document/page builders, voice, AutoCompany (AOC), and more.

For the **MCP host integration** details (authentication, tool surface, troubleshooting), see [MCP.md](MCP.md).

> The Python SDK (`LightbulbClient`, `AsyncLightbulbClient`, etc.) ships in this package as **preview / unstable internals**. The supported product right now is the MCP server and helper CLI — direct Python API consumers should expect changes between minor versions.

## Install

```bash
pip install lightbulb-mcp
```

Console scripts:

- `lightbulb-mcp` — runs the MCP server over stdio for Claude Code / Codex / Cursor (see [MCP.md](MCP.md)).
- `lightbulb` — helper CLI for status, login, and one-shot platform commands.

## Quick start — wire up Claude Code

```bash
pip install lightbulb-mcp
lightbulb setup
```

`lightbulb setup` is an interactive wizard: device-flow login (browser handles MFA), probe `/api/users/me`, then merge a `lightbulb` MCP server entry into Claude Code (`.mcp.json` / `.claude.json`), Codex (`~/.codex/config.toml`), or Cursor (`~/.cursor/mcp.json`). Existing servers are preserved; backups use `.bak`.

Flags: `--target codex`, `--yes` / `--no-write`, `--skip-login`, `--url`.

### Manual `.mcp.json`

If you'd rather wire Claude Code by hand:

```json
{
  "mcpServers": {
    "lightbulb": {
      "command": "lightbulb-mcp",
      "env": {
        "LIGHTBULB_URL": "https://agents.lightbulbpartners.com"
      }
    }
  }
}
```

The MCP server resolves credentials from a cached device-flow token (`~/.lightbulb/tokens/`) by default, or from env (`LIGHTBULB_JWT` + `LIGHTBULB_TENANT_ID`, etc.). Full auth precedence in [MCP.md](MCP.md).

## CLI

Running **`lightbulb` with no arguments** prints **status**: platform URL, cached token hint, detected Claude/Codex/Cursor configs, and next steps.

```bash
lightbulb                    # status (default)
lightbulb setup              # guided auth + MCP config merge
lightbulb whoami
lightbulb dispatch finance --action chat --message "Quick AR aging summary"
lightbulb search-documents "quarterly revenue" --top-k 5
lightbulb approvals list
```

### Environment variables (CLI & MCP)

| Variable | Purpose |
|----------|---------|
| `LIGHTBULB_URL` | Platform base URL (default `https://agents.lightbulbpartners.com`) |
| `LIGHTBULB_JWT` | Bearer JWT |
| `LIGHTBULB_TENANT_ID` | Required with JWT |
| `LIGHTBULB_COMPANY_ID` | Optional company scope |
| `LIGHTBULB_EMAIL` / `LIGHTBULB_PASSWORD` | Legacy password login |
| `LIGHTBULB_API_KEY` / `LIGHTBULB_USER_ID` | Localhost integration bootstrap |
| `LIGHTBULB_MCP_NAMESPACES` | Optional comma-separated allow-list of generated-tool namespaces (e.g. `finance,crm,gmail`). Hand-written tools always register. Unset = all 1005 tools. |

### Trimming the tool surface (0.6.0+)

The MCP server registers ~1005 tools by default. For Claude Code that's ~80k tokens spent on `tools/list` per conversation before the LLM does anything. Most customers only need a handful of integrations, so set `LIGHTBULB_MCP_NAMESPACES` to scope the generated tools:

```json
{
  "mcpServers": {
    "lightbulb": {
      "command": "lightbulb-mcp",
      "env": {
        "LIGHTBULB_URL": "https://agents.lightbulbpartners.com",
        "LIGHTBULB_MCP_NAMESPACES": "finance,crm,gmail,slack,jira,github,notion"
      }
    }
  }
}
```

Valid namespace tags include all 18 domains (`finance`, `intuit`, `crm`, `legal`, `engineering`, `content`, `it_ops`, `commerce`, `product`, `hr`, `coding`, `document_intelligence`, `solver`, `customer_success`, `procurement`, `gtm`, `grc`, `smarthome`) and every connector prefix (`gmail`, `microsoft`, `teams`, `calendar`, `docs`, `drive`, `sheets`, `slides`, `notion`, `slack`, `jira`, `github`, `salesforce`, `hubspot`, `shopify`, `square`, `stripe`, `xero`, `quickbooks`, `clio`, `smokeball`, `monday`, `excel`, `iam`, `ecommerce`, `tasks`, `tickets`, `notifications`). The 156 hand-written tools (whoami, search_documents, dispatch_domain_agent, etc.) always register regardless.

## Python API (preview)

The package also ships a Python client used internally by the MCP server. **Not yet a stable product surface** — expect breaking changes between minor versions. Pin exactly if you depend on it.

```python
from lightbulb import LightbulbClient, device_login

BASE = "https://agents.lightbulbpartners.com"

# Recommended for humans: OAuth2-style device flow (browser handles MFA)
auth, _expires = device_login(BASE, client_id="my-app")

client = LightbulbClient(BASE, auth=auth)
print(client.whoami())

result = client.dispatch("finance", action="chat", message="Summarize cash this week")
print(result.reply)
```

### Email / password and 2FA

```python
from lightbulb import login, complete_2fa_login, TwoFactorRequired

try:
    auth = login(BASE, "you@company.com", "secret")
except TwoFactorRequired as exc:
    code = input("Authenticator code: ").strip()
    auth = complete_2fa_login(exc.base_url, exc.email, code)

client = LightbulbClient(BASE, auth=auth)
```

For MFA accounts, **device login** is usually simpler.

### Async

```python
from lightbulb import AsyncLightbulbClient, JwtAuth

async def main():
    auth = JwtAuth(token="...", tenant_id="...", company_id=None)
    async with AsyncLightbulbClient(BASE, auth=auth) as client:
        me = await client.whoami()
```

Coverage in `AsyncLightbulbClient` is curated for hot paths; use `LightbulbClient` for full surface area.

### Refreshing expired JWTs

Pass `auth_refresh` and call `refresh_auth()` after an `AuthenticationError`, then retry:

```python
from lightbulb import LightbulbClient, AuthenticationError
from lightbulb.auth import device_login

def refresh():
    auth, _ = device_login(BASE, client_id="my-worker")
    return auth

client = LightbulbClient(BASE, auth=initial_auth, auth_refresh=refresh)

try:
    client.dispatch("crm", action="chat", message="hello")
except AuthenticationError:
    if client.refresh_auth():
        client.dispatch("crm", action="chat", message="hello")
```

Same pattern on `AsyncLightbulbClient` with `await client.refresh_auth()`.

## Exceptions (`lightbulb.errors`)

HTTP failures from **`LightbulbClient`** and **`AsyncLightbulbClient`** raise **`LightbulbError`** subclasses (not raw `httpx.HTTPStatusError`):

| Type | Typical status |
|------|----------------|
| `AuthenticationError` | 401 |
| `PermissionDenied` | 403 |
| `NotFoundError` | 404 |
| `ValidationError` | 400 / 422 (also subclasses `ValueError`) |
| `RateLimitedError` | 429 (`retry_after` when present) |
| `ServerError` | 5xx |

Helpers: `from_response`, `wrap_http_error`, `raise_if_error` (used internally; safe to call on any `httpx.Response`).

Messages avoid leaking raw response bodies; structured JSON fields like `message` / `error` are capped.

Deep wrappers (`XeroAgentClient`, connector clients) use the same HTTP stack and raise the same types.

## Typed integrations

- **Stripe:** `StripeOrchestratorClient`, `StripeWorkflow`
- **Xero:** `XeroAgentClient`, `XeroPlaybook`
- **Connectors:** `SlackClient`, `JiraClient`, `BambooHRClient`, `GreenhouseClient`, `MondayClient` (thin `invoke_tool` / HR-live helpers)

## Security posture

- HTTPS enforced for non-local hosts by default (`enforce_https=False` only for dev).
- Path segments and risky inputs validated (`validators` module); SSO / device-flow URLs validated before opening a browser.
- Token cache: atomic write, restrictive permissions, symlink and ownership checks.
- `lightbulb setup`: atomic config writes, safe TOML escaping for Codex, backups chmod-restricted.

Regression tests live in `tests/test_security.py` (audit IDs in docstrings).

## Types (PEP 561)

The wheel ships `py.typed` for Pyright/mypy consumers.

## Version history

### 0.6.2

- **`lightbulb connect <provider>`** — best-effort CLI to hook up a personal Slack / HubSpot / Notion / Gmail / GitHub / etc. account to the user's tenant. Validates the provider against `list_connectors()`, opens the platform's OAuth flow in a browser. `lightbulb connect --check <provider>` verifies the connection landed (post-auth confirmation step until the platform supports `?return_to=cli`).
- **`lightbulb tools`** — list the MCP tool surface this install actually exposes (with namespace-filter awareness). `--filter SUBSTR` to narrow, `--count-only` for scripting. Useful for diagnosing which connector ops are reachable when V1441 hasn't been applied platform-side yet.

### 0.6.1

- **Bug fix: device-flow login surfacing localhost verification URLs.** A customer hit "Refusing to open verification URL: SSO redirect URL host 'localhost' does not match platform host" — root cause was the platform's `DeviceAuthorizationService` reading `app.base-url` (defaults to `http://localhost:3000`) which was unset in production. SDK now surfaces the actionable hint ("ask your Lightbulb admin to set APP_BASE_URL") so users know who to contact instead of seeing a bare host-mismatch error. **Platform-side fix also drafted** at `application.yml`: added `app.base-url: ${APP_BASE_URL:https://agents.lightbulbpartners.com}`. Once the platform team redeploys, the bug stops triggering.
- Regression test: `tests/test_security.py::TestRedirectUrlValidator::test_localhost_mismatch_surfaces_actionable_hint`.

### 0.6.0

- **Namespace filtering** for the generated tool surface. Set `LIGHTBULB_MCP_NAMESPACES=finance,crm,gmail` (or any comma-separated subset) to register only the matching generated tools — typically cuts the cold-start `tools/list` payload from ~1005 tools / ~80k tokens to ~200 tools / ~15k tokens. Hand-written tools (whoami, dispatch_domain_agent, etc.) always register. See README "Trimming the tool surface".
- Codegen at `scripts/generate_mcp_tools.py` now tags each generated tool with its explicit namespace (e.g. `it_ops`, `document_intelligence`) so multi-word namespaces filter correctly without underscore-split ambiguity.
- Regression tests for the filter behaviour: `tests/test_mcp_server.py::test_namespace_filter_*`.

### 0.5.1

- **Critical: fix `invoke_tool` wire shape.** Earlier versions sent `{tool, arguments}` to `/api/tools/invoke`; Spring's `InvokeToolRequest` DTO expects `{toolName, inputs, tenantId, companyId}`. The 565 generated connector-op tools in 0.5.0 all failed silently against this mismatch. Sync + async clients fixed; regression tests added in `tests/test_client.py::TestInvokeTool` and `tests/test_async_client.py::TestAsyncInvokeTool`.
- **Security**: collapse inline `is_local` checks in `client.py`/`async_client.py` onto canonical `validators.is_local_url` (now covers IPv6 `::1`); add UUID validation in `select_company` MCP tool; assert `JwtAuth` in `save_cached_token`; clarify `backbone_execute` runs server-side.
- Added a draft Flyway migration at `springboot-server/src/main/resources/db/migration/V1441__seed_connector_tool_keys.sql` (537 rows). Platform team applies; once live, the 565 generated connector tools become reachable end-to-end.

### 0.5.0

- **Massive tool surface expansion (~1000 tools, up from 156).** Every domain agent action and every registered platform connector op now has a direct MCP tool — Claude Code / Codex / Cursor see them in the picker without indirection.
- 284 domain action tools auto-generated from `agent-workers/agents/domain_registry.py`: finance, intuit, crm, legal, engineering, content, it_ops, commerce, product, hr, coding, document_intelligence, solver, customer_success, procurement, gtm, grc, smarthome.
- 565 connector op tools auto-generated from the platform's tool registry: deep coverage of Xero (127), Clio (63), GitHub (58), Slack (57), Commerce (51), QuickBooks (44), Smokeball (39), Monday (31), Jira (27), Notion (21), Shopify (18), Stripe, Square, Salesforce, Microsoft, Gmail, and more.
- Codegen lives at `scripts/generate_mcp_tools.py`. Re-run after platform changes.
- Hand-written 156 tools kept as-is; no API changes there.

### 0.4.0

- Renamed package to `lightbulb-mcp`; MCP deps (`mcp`, `pydantic`, `pydantic-settings`) are now hard dependencies. Python API ships as preview/unstable internals.
- Defaults updated to production: `LIGHTBULB_URL` defaults to `https://agents.lightbulbpartners.com`. CLI / MCP server / setup wizard all use the plural production hostname.
- Security hardening: redirect URL validation, token/config atomic writes, TOML injection fixes, SSE size limits, localhost detection via hostname parsing, preview proxy header merging.
- `errors` module and **`raise_if_error`**: platform HTTP errors map to `LightbulbError` subclasses from the sync/async clients and Xero wrapper.
- `refresh_auth` / optional `auth_refresh` callback; setup wizard retries once on stale cached token.
- `py.typed` + README/MCP docs consolidation.

### 0.3.0

- 2FA (`TwoFactorRequired`, `complete_2fa_login`), SSO URL helper, SSE streaming for code/page/document builders, code workspace tools & preview, marketing connector setup methods, typed connector clients, `AsyncLightbulbClient`, `lightbulb` CLI, guided `lightbulb setup` / `lightbulb status`, `lightbulb-mcp` entry point.

### 0.2.0

- Large MCP tool expansion, domain registry alignment, `XeroAgentClient`, expanded platform surface in MCP.
