mcp-server-axiom-js
The mcp-server-axiom-js is a JavaScript port of the Axiom MCP server that allows AI agents to query and analyze data in Node.js environments. With this server, you can:
Execute Axiom Processing Language (APL) queries on datasets, including complex operations like aggregations, filtering, joins, unions, time-based operations, and string manipulations
List all available Axiom datasets
Retrieve detailed information and schema for specific datasets
A JavaScript port of the Axiom MCP server that enables querying data using Axiom Processing Language (APL), allowing AI agents to explore datasets, execute queries, and analyze data stored in Axiom.
Provides Node.js integration for the Axiom MCP server, packaged as an npm module for easier integration with Node.js environments to query and analyze data stored in Axiom.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-axiom-js show me the top 10 error logs from yesterday"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Server for Axiom
A JavaScript port of the official Axiom MCP server that enables AI agents to query data using Axiom Processing Language (APL).
This implementation provides the same functionality as the original Go version but packaged as an npm module for easier integration with Node.js environments.
Installation & Usage
MCP Configuration
You can run this MCP server directly using npx. Add the following configuration to your MCP configuration file:
{
"axiom": {
"command": "npx",
"args": ["-y", "mcp-server-axiom"],
"env": {
"AXIOM_TOKEN": "<AXIOM_TOKEN_HERE>",
"AXIOM_URL": "https://api.axiom.co",
"AXIOM_ORG_ID": "<AXIOM_ORG_ID_HERE>"
}
}
}Local Development & Testing
Installation
npm install -g mcp-server-axiomEnvironment Variables
The server can be configured using environment variables:
AXIOM_TOKEN(required): Your Axiom API tokenAXIOM_ORG_ID(required): Your Axiom organization IDAXIOM_URL(optional): Custom Axiom API URL (defaults to https://api.axiom.co)AXIOM_QUERY_RATE(optional): Queries per second limit (default: 1)AXIOM_QUERY_BURST(optional): Query burst capacity (default: 1)AXIOM_DATASETS_RATE(optional): Dataset list operations per second (default: 1)AXIOM_DATASETS_BURST(optional): Dataset list burst capacity (default: 1)PORT(optional): Server port (default: 3000)
Running the Server Locally
Using environment variables:
export AXIOM_TOKEN=your_token
mcp-server-axiomUsing a config file:
mcp-server-axiom config.jsonExample config.json:
{
"token": "your_token",
"url": "https://custom.axiom.co",
"orgId": "your_org_id",
"queryRate": 2,
"queryBurst": 5,
"datasetsRate": 1,
"datasetsBurst": 2
}Related MCP server: Perplexity MCP Server
API Endpoints
GET /: Get server implementation infoGET /tools: List available toolsPOST /tools/:name/call: Call a specific toolAvailable tools:
queryApl: Execute APL querieslistDatasets: List available datasets
Example Tool Calls
Query APL:
curl -X POST http://localhost:3000/tools/queryApl/call \
-H "Content-Type: application/json" \
-d '{
"arguments": {
"query": "['logs'] | where ['severity'] == \"error\" | limit 10"
}
}'List Datasets:
curl -X POST http://localhost:3000/tools/listDatasets/call \
-H "Content-Type: application/json" \
-d '{
"arguments": {}
}'License
MIT
Available Tools
3 toolsgetDatasetInfoAndSchemaC
Get dataset info and schema
Inputs: dataset (required).
listDatasetsB
List all available Axiom datasets
Inputs: no named parameters.
queryAplA
Instructions
Query Axiom datasets using Axiom Processing Language (APL). The query must be a valid APL query string.
ALWAYS get the schema of the dataset before running queries rather than guessing. You can do this by getting a single event and projecting all fields.
Keep in mind that there's a maximum row limit of 65000 rows per query.
Prefer aggregations over non aggregating queries when possible to reduce the amount of data returned.
Be selective in what you project in each query (unless otherwise needed, like for discovering the schema). It's expensive to project all fields.
ALWAYS restrict the time range of the query to the smallest possible range that meets your needs. This will reduce the amount of data scanned and improve query performance.
NEVER guess the schema of the dataset. If you don't where something is, use search first to find in which fields it appears.
Examples
Basic:
Filter: ['logs'] | where ['severity'] == "error" or ['duration'] > 500ms
Time range: ['logs'] | where ['_time'] > ago(2h) and ['_time'] < now()
Project rename: ['logs'] | project-rename responseTime=['duration'], path=['url']
Aggregations:
Count by: ['logs'] | summarize count() by bin(['_time'], 5m), ['status']
Multiple aggs: ['logs'] | summarize count(), avg(['duration']), max(['duration']), p95=percentile(['duration'], 95) by ['endpoint']
Dimensional: ['logs'] | summarize dimensional_analysis(['isError'], pack_array(['endpoint'], ['status']))
Histograms: ['logs'] | summarize histogram(['responseTime'], 100) by ['endpoint']
Distinct: ['logs'] | summarize dcount(['userId']) by bin_auto(['_time'])
Search & Parse:
Search all: search "error" or "exception"
Parse logs: ['logs'] | parse-kv ['message'] as (duration:long, error:string) with (pair_delimiter=",")
Regex extract: ['logs'] | extend errorCode = extract("error code ([0-9]+)", 1, ['message'])
Contains ops: ['logs'] | where ['message'] contains_cs "ERROR" or ['message'] startswith "FATAL"
Data Shaping:
Extend & Calculate: ['logs'] | extend duration_s = ['duration']/1000, success = ['status'] < 400
Dynamic: ['logs'] | extend props = parse_json(['properties']) | where ['props.level'] == "error"
Pack/Unpack: ['logs'] | extend fields = pack("status", ['status'], "duration", ['duration'])
Arrays: ['logs'] | where ['url'] in ("login", "logout", "home") | where array_length(['tags']) > 0
Advanced:
Make series: ['metrics'] | make-series avg(['cpu']) default=0 on ['_time'] step 1m by ['host']
Join: ['errors'] | join kind=inner (['users'] | project ['userId'], ['email']) on ['userId']
Union: union ['logs-app*'] | where ['severity'] == "error"
Fork: ['logs'] | fork (where ['status'] >= 500 | as errors) (where ['status'] < 300 | as success)
Case: ['logs'] | extend level = case(['status'] >= 500, "error", ['status'] >= 400, "warn", "info")
Time Operations:
Bin & Range: ['logs'] | where ['_time'] between(datetime(2024-01-01)..now())
Multiple time bins: ['logs'] | summarize count() by bin(['_time'], 1h), bin(['_time'], 1d)
Time shifts: ['logs'] | extend prev_hour = ['_time'] - 1h
String Operations:
String funcs: ['logs'] | extend domain = tolower(extract("://([^/]+)", 1, ['url']))
Concat: ['logs'] | extend full_msg = strcat(['level'], ": ", ['message'])
Replace: ['logs'] | extend clean_msg = replace_regex("(password=)[^&]", "\1**", ['message'])
Common Patterns:
Error analysis: ['logs'] | where ['severity'] == "error" | summarize error_count=count() by ['error_code'], ['service']
Status codes: ['logs'] | summarize requests=count() by ['status'], bin_auto(['_time']) | where ['status'] >= 500
Latency tracking: ['logs'] | summarize p50=percentile(['duration'], 50), p90=percentile(['duration'], 90) by ['endpoint']
User activity: ['logs'] | summarize user_actions=count() by ['userId'], ['action'], bin(['_time'], 1h)
Inputs: query (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
The three tools have clearly distinct purposes: listDatasets enumerates available datasets, getDatasetInfoAndSchema retrieves metadata and structure for a specific dataset, and queryApl executes analytical queries. There is no overlap in functionality, making it easy for an agent to select the appropriate tool.
Two tools (listDatasets, getDatasetInfoAndSchema) follow a consistent verb_noun pattern with camelCase, while queryApl uses a different verb style and abbreviation. The deviation is minor, as the naming remains readable and the tools are clearly related to Axiom datasets.
With three tools, this server is well-scoped for its purpose of interacting with Axiom datasets. Each tool serves a distinct and essential function: listing, inspecting, and querying datasets, which covers the core workflows without unnecessary complexity.
The tool surface provides comprehensive coverage for dataset exploration and querying, including listing, metadata retrieval, and advanced querying with APL. A minor gap exists in dataset management operations (e.g., create, update, delete datasets), but the provided tools enable effective data analysis within existing datasets.
Maintenance
Related MCP Connectors
The official MCP Server for the Mux API
Related MCP Servers
- AlicenseBqualityDmaintenanceThis server is a server that installs other MCP servers for you. Install it, and you can ask Claude to install MCP servers hosted in npm or PyPi for you. Requires npx and uv to be installed for node and Python servers respectively.2188 npm1,537MIT
- AlicenseAqualityDmaintenanceadvance mcp server utilizing Perplexity, without the need for an API key677 npm98GPL 3.0
- AGPL 3.0
- AlicenseNot gradedqualityDmaintenanceEnables creation and deployment of MCP servers on Cloudflare Workers, with local testing and one-command deployment.11 npm5MIT