# How to Integrate Macro Inc. with Other Systems: A Complete Guide to MCP, OAuth, and Webhook APIs

> Integrate Macro Inc. with other systems. Learn to use MCP, OAuth, and webhook APIs for seamless system connections in this comprehensive guide.

- Repository: [Macro/macro](https://github.com/macro-inc/macro)
- Tags: how-to-guide
- Published: 2026-08-20

---

**Integrate Macro Inc. with external systems using the MCP Client crate for OAuth-authenticated API calls, service clients for database operations, and webhook endpoints for bidirectional event streaming.**

Macro Inc. is a Rust-based microservices workspace that exposes multiple integration layers through the **Macro Connect Platform (MCP)** protocol. Whether you're connecting Slack, Google, GitHub, Stripe, or custom third-party services, the architecture provides standardized patterns for authentication, API consumption, and event handling. This guide walks through the core integration mechanisms with production-ready code examples from the `macro-inc/macro` repository.

## Understanding Macro Inc.'s Integration Architecture

The integration stack consists of four primary layers that work together to enable secure, scalable connections with external systems.

### API Gateway: The Unified Entry Point

All service endpoints aggregate through a single **Axum router** in the document storage service. This router handles webhook receivers, OAuth callbacks, and REST API exposure.

The main router definition lives in [`services/document_storage_service/src/api/router.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/api/router.rs). Public endpoints are documented via Swagger in [`services/document_storage_service/src/api/swagger.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/api/swagger.rs), which includes the webhook registration routes used by external services to push events into Macro.

### Service Clients: Database-Native Integration

Each microservice ships a thin client crate that wraps SQLx queries and HTTP calls. These are the preferred mechanism for programmatic access to Macro's backends:

| Client Crate | Purpose | Key Module |
|-------------|---------|------------|
| `macro_db_client` | Document and core data operations | `document::v2::create` |
| `comms_db_client` | Channels, messages, webhooks | Communications service bridge |
| `email_db_client` | Email synchronization and sending | Gmail/Outlook integration |

Example from the seed CLI showing document creation via `macro_db_client`:

```rust
// tooling/seed_cli/src/service/db/mod.rs
macro_db_client::document::v2::create::create_document(&client, args).await?;

```

### MCP Client: Third-Party SaaS Integration

The `crates/mcp_client` crate implements the **MCP protocol**—Macro's standardized interface for OAuth-based third-party integrations. It provides three core capabilities:

1. **OAuth credential handling** ([`outbound/oauth.rs`](https://github.com/macro-inc/macro/blob/main/outbound/oauth.rs))
2. **Persistent credential storage** ([`outbound/pg_server_repo.rs`](https://github.com/macro-inc/macro/blob/main/outbound/pg_server_repo.rs))
3. **Provider-specific adapters** ([`domain/provider_registry/mod.rs`](https://github.com/macro-inc/macro/blob/main/domain/provider_registry/mod.rs))

Built-in providers include **Slack**, **Google**, **GitHub**, **Stripe**, and **Cal.com**. Each provider follows a manifest-based registration pattern under `crates/mcp_client/src/domain/provider_registry/`.

### Webhooks: Inbound Event Processing

Macro accepts push events from integrated services through dedicated webhook endpoints. The webhook router in `crates/webhook/src/domain/models/*.rs` validates and transforms external payloads into internal `WebhookEvent` records.

## Setting Up OAuth Credentials for Macro Inc. Integrations

Before making authenticated API calls, you must provision credentials through Macro's identity and configuration systems.

### Step 1: Register the Integration in FusionAuth

**FusionAuth** serves as the SSO provider for all OAuth flows. For local development:

1. Navigate to `http://localhost:9011` (available when running the local stack)
2. Create an OAuth application for your target service (Google, GitHub, etc.)
3. Note the generated **client ID** and **client secret**

### Step 2: Inject Credentials via Doppler or Environment Variables

Environment variables follow the `*_CLIENT_ID` / `*_CLIENT_SECRET_KEY` naming convention. The `macro_env_var` crate loads these securely at runtime using procedural macros.

Reference the local environment setup in [`tooling/xtask_local/src/local/local_env.rs`](https://github.com/macro-inc/macro/blob/main/tooling/xtask_local/src/local/local_env.rs):

```rust
// Example pattern from local_env.rs
pub const GOOGLE_CLIENT_ID: &str = env!("GOOGLE_CLIENT_ID");
pub const GOOGLE_CLIENT_SECRET_KEY: &str = env!("GOOGLE_CLIENT_SECRET_KEY");

```

For production, credentials are managed through **Doppler**. For local testing, use the stubbed credentials generated by [`tooling/xtask_local/src/local/kickstart.rs`](https://github.com/macro-inc/macro/blob/main/tooling/xtask_local/src/local/kickstart.rs).

### Step 3: Enable the Provider in the MCP Registry

Provider registration requires two artifacts in `crates/mcp_client/src/domain/provider_registry/`:

1. A **JSON manifest** (e.g., [`slack/manifest.json`](https://github.com/macro-inc/macro/blob/main/slack/manifest.json)) declaring scopes and endpoints
2. An **outbound adapter** implementing the provider's API contract

## Using the MCP Client to Integrate Macro Inc. with External APIs

The `McpClient` struct is the primary interface for authenticated HTTP calls to third-party services.

### Complete Example: Sending a Slack Message

```rust
// Cargo.toml dependency:
// mcp_client = { path = "crates/mcp_client" }

use mcp_client::McpClient;
use mcp_client::domain::models::server::OAuthServer;
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize client with environment-loaded credentials
    let client = McpClient::new().await?;
    
    // Obtain access token for Slack provider
    let token = client
        .oauth()
        .get_access_token(OAuthServer::Slack)
        .await?;
    
    // Send message via Slack Web API
    let resp = client
        .http()
        .post("https://slack.com/api/chat.postMessage")
        .bearer_auth(&token)
        .json(&serde_json::json!({
            "channel": "#general",
            "text": "Hello from Macro!"
        }))
        .send()
        .await?;
    
    println!("Slack response: {:?}", resp.text().await?);
    Ok(())
}

```

Source: [`crates/mcp_client/src/outbound/oauth.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/outbound/oauth.rs)

### Stripe Checkout Session Creation

```rust
// Using the Stripe adapter from outbound module
let session = client
    .stripe()
    .create_checkout_session(CreateCheckoutSessionArgs {
        amount: 5000, // cents
        currency: "usd",
        success_url: "https://yourservice.com/success",
    })
    .await?;

```

Source: [`crates/mcp_client/src/outbound/mod.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/outbound/mod.rs)

## Implementing Webhooks for Bidirectional Macro Inc. Integration

Many integrations require external services to push events back into Macro. The webhook system handles validation, storage, and downstream processing.

### Registering a Webhook Endpoint

```bash
curl -X POST http://localhost:8080/api/webhook \
     -H "Content-Type: application/json" \
     -d '{
           "url": "https://github.com/your/repo/events",
           "events": ["push", "pull_request"],
           "secret": "my-webhook-secret"
        }'

```

### Processing Inbound Events

Webhook payloads are stored as `WebhookEvent` records defined in [`crates/webhook/src/domain/events.rs`](https://github.com/macro-inc/macro/blob/main/crates/webhook/src/domain/events.rs). Services consume these through:

- **Direct database queries** via `comms_db_client`
- **Real-time Pub/Sub subscription** to internal Kafka topics

Example handler from the email service validating Gmail push notifications:

```rust
// services/email_service/src/api/gmail/webhook.rs
pub async fn handle_gmail_webhook(
    payload: WebhookPayload,
    token: OidcToken,
) -> Result<impl IntoResponse, AppError> {
    validate_oidc_token(&token).await?;
    store_webhook_event(payload).await?;
    Ok(StatusCode::OK)
}

```

## Local Development and Testing for Macro Inc. Integrations

The `xtask_local` tooling provides a complete development environment with stubbed integration secrets.

### Starting the Full Stack

```bash

# Spin up PostgreSQL, LocalStack, FusionAuth, OpenSearch, etc.

# with dummy credentials for Google, GitHub, and Stripe

just stack up --no-doppler

```

The kickstart script in [`tooling/xtask_local/src/local/kickstart.rs`](https://github.com/macro-inc/macro/blob/main/tooling/xtask_local/src/local/kickstart.rs) generates predictable test credentials, enabling end-to-end integration testing without production secrets.

### Seeding Test Data

The seed CLI demonstrates programmatic service client usage:

```rust
// tooling/seed_cli/src/entity/gmail/mod.rs
// Builds Pub/Sub push envelope for Gmail watch notifications
let envelope = PubSubEnvelope {
    message: Message {
        data: base64::encode(notification),
        attributes: HashMap::new(),
    },
    subscription: "projects/macro/subscriptions/gmail".into(),
};

client.post("http://localhost:8090/email/gmail/webhook")
    .json(&envelope)
    .send()
    .await?;

```

## Key Files for Macro Inc. Integration Development

| File Path | Purpose |
|-----------|---------|
| [`crates/mcp_client/src/lib.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/lib.rs) | Public API for the MCP client |
| [`crates/mcp_client/src/domain/provider_registry/mod.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/domain/provider_registry/mod.rs) | Provider registration and discovery |
| [`crates/mcp_client/src/outbound/oauth.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/outbound/oauth.rs) | OAuth token acquisition and refresh |
| [`services/document_storage_service/src/api/swagger.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/api/swagger.rs) | HTTP endpoint documentation |
| `crates/webhook/src/domain/models/*.rs` | Webhook payload schemas |
| [`tooling/xtask_local/src/local/kickstart.rs`](https://github.com/macro-inc/macro/blob/main/tooling/xtask_local/src/local/kickstart.rs) | Local stack initialization |
| [`tooling/seed_cli/src/service/db/mod.rs`](https://github.com/macro-inc/macro/blob/main/tooling/seed_cli/src/service/db/mod.rs) | Service client usage examples |
| [`crates/macro_db_client/README.md`](https://github.com/macro-inc/macro/blob/main/crates/macro_db_client/README.md) | Primary database client documentation |
| [`crates/comms_db_client/README.md`](https://github.com/macro-inc/macro/blob/main/crates/comms_db_client/README.md) | Communications client documentation |

## Summary

- **API Gateway**: Unified Axum router in [`services/document_storage_service/src/api/router.rs`](https://github.com/macro-inc/macro/blob/main/services/document_storage_service/src/api/router.rs) exposes all endpoints
- **Service Clients**: `macro_db_client`, `comms_db_client`, and `email_db_client` provide type-safe database access
- **MCP Protocol**: `crates/mcp_client` standardizes OAuth flows with built-in providers for Slack, Google, GitHub, Stripe, and Cal.com
- **Webhooks**: Inbound events are validated in `crates/webhook/src/domain/models/*.rs` and stored as `WebhookEvent` records
- **Local Development**: `just stack up --no-doppler` runs full integration tests with stubbed credentials via `xtask_local`

## Frequently Asked Questions

### What authentication methods does Macro Inc. support for integrations?

Macro Inc. uses **OAuth 2.0** as the primary authentication mechanism through FusionAuth, with API keys supported for webhook verification. The `McpClient` in [`crates/mcp_client/src/outbound/oauth.rs`](https://github.com/macro-inc/macro/blob/main/crates/mcp_client/src/outbound/oauth.rs) handles token acquisition, refresh, and secure storage in PostgreSQL via [`pg_server_repo.rs`](https://github.com/macro-inc/macro/blob/main/pg_server_repo.rs).

### How do I add a new third-party provider to Macro Inc.?

Create a new directory under `crates/mcp_client/src/domain/provider_registry/` containing a [`manifest.json`](https://github.com/macro-inc/macro/blob/main/manifest.json) file with scopes and endpoint definitions, plus an outbound adapter implementing the provider's API. Reference existing implementations like `slack/` or `stripe/` for structure.

### Can I test Macro Inc. integrations without production credentials?

Yes. The `tooling/xtask_local` package spins up a complete local stack with **stubbed integration secrets** for Google, GitHub, and Stripe. Run `just stack up --no-doppler` to start all services, then use the seed CLI to simulate real integration scenarios without external API calls.

### What is the difference between service clients and the MCP client?

**Service clients** (`macro_db_client`, `comms_db_client`, `email_db_client`) are internal-facing crates for direct database access within the Macro ecosystem. The **MCP client** is external-facing, providing OAuth-authenticated HTTP calls to third-party SaaS APIs with credential management and provider-specific adapters.