Skip to content

calc MCP server

Use calc through the Model Context Protocol (MCP) from an AI assistant. The hosted server needs no local installation.

Endpoint

https://calc-mcp.fly.dev/mcp

The server uses Streamable HTTP. GET /health needs no credentials.

Authentication

Claude Desktop with WorkOS

After Gmatter enables WorkOS, members connect https://calc-mcp.fly.dev/mcp from Customize > Connectors. Claude discovers the authorization server, prompts for Google sign-in, and refreshes its token automatically. Do not add an API-key header or OAuth client credentials.

Only verified email addresses in Gmatter's configured domains can connect. calc-mcp validates the access token's signature, issuer, and audience, then reads the user's verified email from the WorkOS Management API (GET /user_management/users/{id}) using the official workos crate. Profiles are cached for five minutes per user.

AuthKit's OIDC /oauth2/userinfo endpoint cannot be used for this. AuthKit issues MCP access tokens with aud set to this server's resource indicator, and userinfo accepts only tokens audienced to AuthKit itself, so it answers 401 for every token calc-mcp can receive.

Gmatter operators

Configure AuthKit before enabling the connector:

  1. Enable Client ID Metadata Document and Dynamic Client Registration under Connect > Configuration.
  2. Enable Google social login.
  3. Register https://calc-mcp.fly.dev/mcp as a Resource Indicator and set it as the default.
  4. Set CALC_MCP_OAUTH_ISSUER to the AuthKit issuer, CALC_MCP_OAUTH_ALLOWED_EMAIL_DOMAINS to the comma-separated Gmatter email domains, and CALC_MCP_OAUTH_WORKOS_API_KEY to a WorkOS API key in the calc production deployment. All three must be set together or the server refuses to start.

The API key must belong to the same WorkOS environment as the issuer — a production key cannot read a staging user, and vice versa.

No custom AuthKit JWT template, client ID, or client secret is required when AuthKit supports CIMD/DCR.

API-key clients

Existing integrations send an API key on every request:

Header Purpose
x-api-key Authenticates your organization.

Missing or invalid credentials receive 401 Unauthorized.

Client configuration

API-key clients

Add the hosted server to any client that supports HTTP MCP servers:

{
  "mcpServers": {
    "calc": {
      "type": "http",
      "url": "https://calc-mcp.fly.dev/mcp",
      "headers": {
        "x-api-key": "YOUR_API_KEY"
      }
    }
  }
}

Tools

Tool Purpose
run_calc_script Runs JavaScript against calc for one participant.
describe_calc_tables Returns DDL for the participant-scoped sql() tables.
get_request_shape Returns the calculation-request shape.
search_calc_api Searches the calc API surface.

run_calc_script requires a non-blank participantKey and code. Set participantKey on each call, so one MCP connection can query different participants:

// run_calc_script arguments
{
  participantKey: 'ag_vend_austin_tx_000',
  code: `
    const response = await fetch(
      '/programs?program_supplier_key=corteva&time_frame=2026',
    );
    const programs = await response.json();
    return programs.length;
  `,
}

Scripts can call calc API paths through fetch, and run DuckDB SQL through sql(). One sql() reads two things, in one database, so a single statement can join them:

  • The flat, participant-scoped calc tables, when the tool call carries programSupplierKey and timeFrame. Call describe_calc_tables for their DDL. The programs table includes only released programs the session participant is enrolled in.
  • Any response fetch() already returned, passed as an argument — it becomes data, data2, and so on, in argument order.
// run_calc_script arguments
{
  participantKey: 'ag_vend_austin_tx_000',
  programSupplierKey: 'corteva',
  timeFrame: '2026',
  code: `
    return sql(
      'SELECT program_key, program_label FROM programs ORDER BY 1',
    );
  `,
}

Pass programSupplierKey and timeFrame together or not at all. Omit both for a script that only reduces fetch() responses. Keep using fetch() for calculations and /programs/skus.

Scripts cannot access the filesystem, arbitrary network hosts, or host globals. A script cannot override its participant with request headers.

Limits

Each script has a 10-second wall-clock limit, 128 MiB heap limit, and a 50,000-character result limit. Requests may also be rate-limited; honor Retry-After when the server responds with 429 Too Many Requests.