Skip to main content

MCP server for the Lightbulb Partners Agents platform — Claude Code, Codex, and Cursor integration

Project description

Lightbulb MCP

MCP server and helper CLI for the Lightbulb Partners Agents 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.

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

pip install lightbulb-mcp

Console scripts:

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

Quick start — wire up Claude Code

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:

{
  "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.

CLI

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

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:

{
  "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.

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

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

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:

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.8.0

  • Full typed coverage for the commerce surface. lightbulb/tool_descriptors.py now carries descriptors for every connector op in the commerce domain — Shopify intelligence (shopify.analytics_query, shopify.list_abandoned_checkouts, shopify.list_locations, shopify.list_collections, shopify.list_fulfillment_orders, shopify.list_discounts, shopify.list_refunds, shopify.list_transactions, shopify.bulk_operation_*), metafields (shopify.get_metafields, shopify.update_metafield, shopify.list_metafield_definitions), segment execution (shopify.tag_customers_bulk, shopify.create_price_rule), the storefront-neutral ecommerce.* ops (search_products, search_orders, search_customers, get_inventory, get_product_reviews, create_discount, update_customer), and the Square POS ops (search_catalog, search_orders, list_payments, list_customers, get_inventory). MCP consumers — Claude Code, Codex, Cursor — now see proper Python signatures with documented params instead of the generic arguments: str = "{}" JSON blob.
  • Codegen log: 24 typed via descriptor for domain actions, 53 typed via descriptor for connector ops (up from 32). Total descriptor surface: 84 (24 domain + 60 connector).
  • This release pairs with a platform-side rework that exposes each connector op as a top-level OpenAI function tool (encoded connector__action) inside the commerce domain agent, ending the silent Unknown tool failures from earlier versions where the prompt advertised dotted op names that the function-call schema couldn't accept.

0.7.0

  • Typed signatures + curated descriptions for the highest-value tools. A new lightbulb/tool_descriptors.py carries hand-curated metadata (multi-line description + per-field types) for 56 priority tools across finance, CRM, legal, HR, coding, plus the most-used connector ops (Xero, QuickBooks, Stripe, Square, Slack, GitHub, Gmail, Microsoft 365, Notion, Jira, Clio, Shopify). When a descriptor exists, codegen emits a typed Python signature like def finance_lbo_model(message: str = "", target_company: Optional[str] = None, entry_multiple: Optional[float] = None, …) and a rich docstring; FastMCP picks these up so Claude Code / Codex see proper input schemas instead of an opaque inputs: str JSON-string parameter.
  • Tools without a descriptor still generate fine via the original message + inputs JSON shape — descriptor coverage expands incrementally over future patches without breaking existing flows.
  • Codegen log: 24 typed via descriptor for domain actions, 32 typed via descriptor for connector ops. Total surface unchanged at 849 generated + 156 hand-written = 1005 tools.

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lightbulb_mcp-0.8.0.tar.gz (184.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lightbulb_mcp-0.8.0-py3-none-any.whl (140.9 kB view details)

Uploaded Python 3

File details

Details for the file lightbulb_mcp-0.8.0.tar.gz.

File metadata

  • Download URL: lightbulb_mcp-0.8.0.tar.gz
  • Upload date:
  • Size: 184.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for lightbulb_mcp-0.8.0.tar.gz
Algorithm Hash digest
SHA256 c36e3ae38d3bbd9e4b657456e1a43b70c2192831d1c696995db9cfa6f0e1c58e
MD5 d02dc2decfcf8968ead21f6230a2a55a
BLAKE2b-256 ca08054193759b3e7ebbfd6685556725190f2c544501fdbc21e8781a0693aec8

See more details on using hashes here.

File details

Details for the file lightbulb_mcp-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: lightbulb_mcp-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 140.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for lightbulb_mcp-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9479f70f97b2b13c62c0b4390cd01c9d2b28fb65fcfdedd742eeb40c1c4b2fa8
MD5 91812a2f8b746b81cea65b44cace9a9c
BLAKE2b-256 81f7b54d53c736422d07f94a89afc1cbec13afd9e3d11479235efd30183e6c17

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page