How Macro's MCP Server Exposes Tool Coverage for External AI Agents
Macro's MCP server exposes tool coverage by running a Streamable HTTP binary that returns a dynamically constructed prompt listing available tools, their capabilities, and fully-qualified URLs for cross-referencing Macro items.
Macro is workspace productivity software that builds document, search, and communication tools. Its Macro Connect Protocol (MCP) server enables external AI agents—such as large language models—to discover and invoke Macro's native functionality through a well-defined HTTP interface. This article breaks down exactly how the server advertises its tool coverage to authorized callers.
The MCP Server Architecture
The MCP server is implemented as a standalone Rust service that bridges external AI clients with Macro's internal infrastructure.
Starting the Streamable HTTP Server
In services/mcp_service/src/main.rs, the server initializes and binds to a configurable address:
// services/mcp_service/src/main.rs
// Launches the MCP server and logs the listening endpoint
println!("MCP server listening on http://{addr}/mcp");
The binary is typically started via the project's just runner:
# Start the MCP server from repository root
just run_mcp_server
Once running, the server exposes the /mcp endpoint where external agents request tool coverage information.
Building the Tool Coverage Prompt
Tool coverage exposure happens through a prompt construction pipeline that combines static instructions with runtime configuration.
The Core Handler: tool_service.rs
services/mcp_service/src/tool_service.rs implements the primary request handler. It performs three critical functions:
- Extracts the authenticated user from incoming requests
- Supplies a base URL — the public Macro web-app URL used to construct fully-qualified links
- Returns tool coverage instructions describing which Macro-native tools are available
This handler ensures that every AI agent receives context-specific information tied to the requesting user's environment.
Composing Instructions in prompt/src/lib.rs
The crates/prompt crate assembles the final instruction payload. In crates/prompt/src/lib.rs, two key components work together:
MCP_STATIC_INSTRUCTIONS— A constant holding the static portion of the prompt, including a description of the available toolsetbuild_instructionsfunction — Interpolates the server's public URL and appends static instructions
// crates/prompt/src/lib.rs
pub fn build_instructions(base_url: &str) -> String {
format!("{}\n\nBase URL: {}", MCP_STATIC_INSTRUCTIONS, base_url)
}
The resulting prompt tells the AI exactly which tools it can invoke and how to format references to Macro items.
Declaring Available Toolsets
The specific tools exposed to external agents are enumerated in crates/prompt/src/connected_toolsets.rs. This file defines the connected toolsets — concrete integrations that the MCP server advertises.
Typical toolset categories include:
document— Creation, editing, and retrieval of Macro documentssearch— Querying across workspace contentemail— Message composition and thread management
This list is injected into the generated prompt, giving AI agents a complete inventory of callable capabilities.
Authentication and Secure Access
Before receiving tool coverage information, external agents must authenticate. The MCP layer implements this through two mechanisms.
Bearer Token Validation
services/mcp_auth_proxy/src/inbound/middleware.rs handles OAuth flows and bearer token validation. The proxy sits between external clients and Macro's internal services:
// services/mcp_auth_proxy/src/inbound/middleware.rs
// Validates Authorization: Bearer <token> headers
Only authenticated and authorized agents can reach the /mcp endpoint to retrieve tool coverage.
Configuration and Caching
services/mcp_service/src/config.rs manages runtime settings including:
- Public base URL for link generation
- Redis connection for session/auth caching
- Server bind address and port
Link Generation for AI Responses
When AI agents reference Macro items in their responses, they cannot use Macro-specific markup like <m-document-mention>. Instead, the MCP server instructs them to use plain URLs.
The crates/prompt/src/mcp_item_links.rs module generates these URLs:
- Converts internal Macro identifiers to public web-app URLs
- Ensures MCP clients render responses as clickable references in the host UI
Practical Usage Example
Retrieving Tool Coverage
# Query the MCP endpoint for available tools
curl -s http://localhost:8080/mcp \
-H "Authorization: Bearer $MCP_TOKEN" | jq .instructions
Sample response excerpt:
{
"instructions": "You are an external AI agent. The following Macro tools are available: \
document, search, email, calendar. Use plain URLs (e.g., \
https://app.macro.com/doc/123) when referring to Macro items. \
Base URL: https://app.macro.com"
}
Invoking an Exposed Tool
import requests
import json
BASE = "http://localhost:8080/mcp"
headers = {"Authorization": "Bearer <MCP_TOKEN>"}
# Call a tool documented in the coverage prompt
payload = {
"tool": "document.create",
"params": {
"title": "Q4 Roadmap",
"content": "Strategic priorities and timelines..."
}
}
resp = requests.post(
f"{BASE}/tool",
json=payload,
headers=headers
)
print(json.dumps(resp.json(), indent=2))
Key Implementation Files
| File Path | Purpose |
|---|---|
services/mcp_service/src/main.rs |
Server initialization and HTTP binding |
services/mcp_service/src/tool_service.rs |
Core handler for tool coverage requests |
services/mcp_service/src/config.rs |
Runtime configuration (URL, Redis, ports) |
crates/prompt/src/lib.rs |
Prompt assembly with static instructions |
crates/prompt/src/connected_toolsets.rs |
Enumerated list of exposed toolsets |
services/mcp_auth_proxy/src/inbound/middleware.rs |
Bearer token and OAuth validation |
crates/prompt/src/mcp_item_links.rs |
URL generation for AI response links |
Summary
- Macro's MCP server runs as a Streamable HTTP binary in
services/mcp_service/src/main.rs, exposing the/mcpendpoint for external AI agents - Tool coverage is communicated through a dynamically constructed prompt combining
MCP_STATIC_INSTRUCTIONSfromcrates/prompt/src/lib.rswith runtime base URL configuration - Available tools are explicitly declared in
crates/prompt/src/connected_toolsets.rs, giving agents a complete capability inventory - Authentication via
services/mcp_auth_proxyensures only authorized agents access tool coverage and invocation endpoints - Plain URL generation through
crates/prompt/src/mcp_item_links.rsenables AI responses to reference Macro items with clickable links
Frequently Asked Questions
What protocol does Macro use to expose tools to external AI agents?
Macro implements the Macro Connect Protocol (MCP), a Streamable HTTP-based protocol defined in the services/mcp_service crate. MCP returns structured prompts describing available tools rather than exposing raw API schemas, making it easier for LLM agents to understand and use Macro capabilities.
How does an AI agent discover which tools it can call through Macro's MCP server?
The agent sends an authenticated GET request to the /mcp endpoint. The server responds with a prompt built by build_instructions() in crates/prompt/src/lib.rs, which includes the enumerated toolsets from crates/prompt/src/connected_toolsets.rs and instructions on how to invoke them.
Why does Macro's MCP server use plain URLs instead of native markup in AI responses?
MCP clients cannot render Macro-specific tags like <m-document-mention>. The crates/prompt/src/mcp_item_links.rs module generates fully-qualified HTTPS URLs (based on the configured base URL from services/mcp_service/src/config.rs) that any client can display as standard clickable links.
What authentication is required to access Macro's MCP tool coverage?
Requests must include a valid Authorization: Bearer <token> header. The services/mcp_auth_proxy/src/inbound/middleware.rs component validates these tokens against Macro's OAuth infrastructure. Unauthenticated requests are rejected before reaching the tool service handler.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →