Skip to main content
Glama
README.md
# x-mcp

`x-mcp` is an X API MCP server built in Node.js. It exposes dedicated MCP tools generated from the upstream X OpenAPI spec, keeps secrets in Vault, keeps non-secret configuration in Postgres, and enforces tenant-aware auth scope as `tenant/user` or `tenant/account`.

The scope model is tenant/user or tenant/account.

## What It Does

- Generates one `x_api_*` MCP tool per documented X API `operationId`
- Exposes discovery tools for LLMs: `x_schema_discovery` and `x_query_suggestion`
- Stores tenant-scoped app credentials and tenant/principal-scoped user credentials in Vault-backed profiles
- Stores defaults, metadata, and non-secret runtime configuration in Postgres
- Protects mutating tools with `authorizationKey` when `MCP_ADMIN_AUTH_KEY` is configured
- Supports stdio, HTTP, or both MCP transports

## Runtime Layout

Key files:

- [src/config/env.js](src/config/env.js): environment parsing and validation
- [src/runtime/createRuntimeContext.js](src/runtime/createRuntimeContext.js): shared runtime bootstrap
- [src/services/xInventory.js](src/services/xInventory.js): generated inventory loading and search
- [src/services/xAuth.js](src/services/xAuth.js): Vault/Postgres-backed credential profile storage and auth resolution
- [src/services/xApi.js](src/services/xApi.js): authenticated X API execution layer
- [src/mcp/server.js](src/mcp/server.js): MCP tool registration, mutation guards, and generated endpoint wiring
- [src/http/server.js](src/http/server.js): HTTP MCP transport with auth, limits, and access logging

Persistence model:

- Vault stores actual secret values.
- Postgres stores profile metadata, default profile selectors, and all non-secret config.
- `APP_NAME` is the single naming source for derived Vault paths and Postgres table names.

## Generated Inventory

Committed artifacts:

- [artifacts/x-api.openapi.json](artifacts/x-api.openapi.json)
- [artifacts/x-api.endpoint-inventory.json](artifacts/x-api.endpoint-inventory.json)

Generate them with:

```bash
npm run inventory:generate
```

Check that the committed artifacts are current with:

```bash
npm run inventory:check
```

## MCP Tool Families

All tools return JSON inside MCP text content.

Core tools:

- `x_connection_info`: runtime, inventory, Vault, and Postgres connection metadata
- `x_scope_info`: resolve tenant/principal scope paths and persistence details
- `x_health_check`: validate Vault and Postgres connectivity for a selected scope
- `x_schema_discovery`: search the generated X endpoint inventory
- `x_query_suggestion`: recommend a safe tool sequence for a workflow

Credential tools:

- `x_auth_upsert_app_credentials`
- `x_auth_upsert_principal_credentials`
- `x_auth_get_scope_credentials`
- `x_auth_delete_profile`

Config tools:

- `x_config_list`
- `x_config_get`
- `x_config_set`
- `x_config_delete`

Generated X API tools:

- one `x_api_*` tool per OpenAPI `operationId`
- rich tool descriptions include use cases, auth prerequisites, parameter constraints, response shape, common failures, and safety warnings

Generic fallback:

- `x_api_request`

## Auth And Scope Model

App-scoped credentials are stored per tenant:

- Vault path: `${APP_NAME}/tenants/<tenant>/x-api/app-profiles/<profileKey>`
- Postgres key: `x.auth.app.profile.<profileKey>.meta`

Principal-scoped credentials are stored per tenant principal:

- Vault path: `${APP_NAME}/tenants/<tenant>/<users|accounts>/<principal>/x-api/profiles/<profileKey>`
- Postgres key: `x.auth.principal.profile.<profileKey>.meta`

Default selectors are stored in Postgres:

- `x.auth.app.defaultProfileKey`
- `x.auth.principal.defaultProfileKey`

Supported auth types:

- bearer token
- OAuth 2 user token
- OAuth 1a user token

If `MCP_ADMIN_AUTH_KEY` is configured, every mutating tool requires `authorizationKey`, including generated mutating endpoint tools and mutating `x_api_request` calls.

## Environment

See [.env.example](.env.example) for the full set. The most important groups are:

- `POSTGRES_*`
- `VAULT_*`
- `MCP_*`
- `X_API_*`

The default local scope is controlled by:

- `MCP_CONFIG_DEFAULT_TENANT_ID`
- `MCP_CONFIG_DEFAULT_USER_ID`
- `MCP_CONFIG_DEFAULT_ACCOUNT_ID`
- `MCP_CONFIG_DEFAULT_PRINCIPAL_TYPE`

## Local Development

Install dependencies and generate the inventory:

```bash
npm ci
npm run inventory:generate
```

Run stdio:

```bash
npm run start:stdio
```

Run HTTP:

```bash
npm run start:http
```

Run both:

```bash
npm run start:both
```

## MCP Client Registration

VS Code example:

```json
{
  "command": "npm",
  "args": ["run", "start:stdio"],
  "cwd": "/Users/lesterjohn/Documents/GitHub/X-mcp"
}
```

Claude Desktop example:

```json
{
  "mcpServers": {
    "x-mcp": {
      "command": "npm",
      "args": ["run", "start:stdio"],
      "cwd": "/Users/lesterjohn/Documents/GitHub/X-mcp"
    }
  }
}
```

If you need HTTP transport, point the client at `http://127.0.0.1:3000/mcp` after starting `npm run start:http`.

## Infrastructure

[docker-compose.yml](docker-compose.yml) runs local Postgres, Vault, and the HTTP MCP service. It preserves Vault Raft persistence and runs `vault-unseal-key-init` before Vault starts.

## External Services Mode

[docker-compose.external.yml](docker-compose.external.yml) is the supported External Services Mode for existing Vault and Postgres infrastructure. It requires `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `VAULT_ADDR`, and `VAULT_TOKEN` to be provided by the deployment environment.

[initdb/001_config.sh](initdb/001_config.sh) creates `${APP_NAME}_config` with tenant/principal primary keys.

## Production Vault

[vault-production/README.md](vault-production/README.md) covers migration from the local development Vault to the Raft-backed production layout used by `x-mcp`.

## CI And Push Enforcement

GitHub Actions in [.github/workflows/inventory-and-tests.yml](.github/workflows/inventory-and-tests.yml) regenerates the X API inventory, fails if artifacts are stale, uploads the generated inventory artifacts, and runs `npm run verify`.

The local pre-push hook in [.githooks/pre-push](.githooks/pre-push) also runs:

```bash
npm run verify
```

This repository is configured to use `.githooks` as `core.hooksPath`.

## Verification

Run the full verification path with:

```bash
npm run verify
```

The test suite covers:

- HTTP auth and transport behavior
- generated X tool registration and mutation auth enforcement
- discovery and query-suggestion behavior
- Vault token indexing and fallback semantics
- Vault production migration scaffolding
- X inventory artifact presence and push/test enforcement

## License

MIT. See [LICENSE](LICENSE).

TDQS

B3.4/5.0

Scored across 179 tools

Disambiguation3/5

Most x_api_* tools target distinct resource actions, but overlapping families exist (e.g., account_activity_subscription vs activity_subscription, get_users_timeline vs get_users_posts, reposted_by vs reposts) that could cause misselection. Descriptions help differentiate, but the sheer volume of similarly named tools makes boundaries less clear.

Naming Consistency4/5

The dominant pattern is x_api_<verb>_<resource> and is applied consistently across the huge endpoint set. Minor deviations exist: 'remove' vs 'delete', 'add' vs 'create', and unofficial core tools use x_config_*/x_auth_* prefixes, but the pattern is still readable and predictable.

Tool Count1/5

With 179 tools, this is an extreme count far beyond the calibration guidance for well-scoped servers. The server appears to be a raw auto-generated wrapper around the entire X API, which overwhelms agents and makes discovery and selection impractical.

Completeness5/5

The tool surface is remarkably comprehensive, covering CRUD and lifecycle operations for posts, users, lists, DMs, media, spaces, trends, compliance, webhooks, activities, articles, community notes, and insights. Core auth/config utilities plus a generic x_api_request fallback ensure no obvious dead ends exist.

Maintenance

ActivitySlowing
ResponsivenessNo issues