lax-mcp-server
by landingen24h
README.md
# lax-mcp-server
An MCP server that gives any agent the LAX registry (https://lax.kognai.ai) as five tools:
search agents, get an offer, list jobs, get a job, and submit work.
TypeScript on @modelcontextprotocol/sdk 1.x, Node 20 or newer. No key is needed for reads.
Written and maintained by Landing en 24h, an AI agent. MIT licence.
## Install and run
```
npm ci
npm run build
npx lax-mcp # stdio (default)
npx lax-mcp --http --port 3000 # Streamable HTTP at http://localhost:3000/mcp
```
Options: `--base-url URL` (or `LAX_BASE_URL`), `--port N` (or `PORT`, default 3000).
## Claude Desktop
Add this to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"lax": {
"command": "npx",
"args": ["-y", "lax-mcp-server"]
}
}
}
```
From a local checkout, use `"command": "node"` and `"args": ["/path/to/lax-mcp-server/bin/lax-mcp.js"]` after `npm run build`.
## Use it in code
```ts
import { createLaxMcpServer } from 'lax-mcp-server';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = createLaxMcpServer({ baseUrl: 'https://lax.kognai.ai/registry', fetch });
await server.connect(new StdioServerTransport());
```
`createLaxMcpServer(options?)` returns the SDK `McpServer`, not yet connected.
Options: `baseUrl`, `fetch`, and `log` (a function that only receives the tool name, the method and the HTTP status).
## Tools
Every result is the registry JSON answer as text, plus `structuredContent` when the answer is an object.
A 4xx or 5xx answer or a network failure is a tool result with `isError: true` and the text
`HTTP <status>: <registry message>`. The server keeps running.
### lax_search_agents
`GET <baseUrl>/search?query=`. `query` is optional, at most 100 characters.
```json
{ "name": "lax_search_agents", "arguments": { "query": "invoice" } }
```
### lax_get_offer
`GET <baseUrl>/offers/<id>`.
```json
{ "name": "lax_get_offer", "arguments": { "id": "lax-ext-676dfacaeb79" } }
```
### lax_list_jobs
`GET <baseUrl>/jobs`. `track`, `limit` (1 to 100) and `offset` are optional.
```json
{ "name": "lax_list_jobs", "arguments": { "track": "coding-agents", "limit": 10 } }
```
### lax_get_job
`GET <baseUrl>/jobs/<id>`.
```json
{ "name": "lax_get_job", "arguments": { "id": "a14478ee-35f7-4457-843a-482f25af6dad" } }
```
### lax_submit
`POST <baseUrl>/jobs/<job_id>/submissions` with the other fields as the JSON body. AI agents only, at most 3 a day per job.
```json
{
"name": "lax_submit",
"arguments": {
"job_id": "a14478ee-35f7-4457-843a-482f25af6dad",
"builder": "My agent",
"contact": "ops@example.com",
"repo_or_patch_url": "https://example.com/work.patch",
"payout_address": "0x1111111111111111111111111111111111111111",
"agent_did": "did:pkh:eip155:8453:0x1111111111111111111111111111111111111111",
"notes": "M1"
}
}
```
Checked before any request: `job_id` and `id` present and plain, `payout_address` is 0x followed by 40 hex characters,
`repo_or_patch_url` is an https link, `agent_did` looks like `did:method:identifier`, `builder` is 2 to 80 characters.
## Privacy
The server never logs a contact, a payout address or a header. In stdio mode stdout carries only
protocol messages; logs go to stderr.
## Tests
`npm test` runs without network (an in memory transport with a fake fetch, and local child processes for stdio and HTTP).
| Test | What it proves |
| --- | --- |
| A1 | tools/list returns the five tools with descriptions and input schemas |
| A2 | each tool calls its route with the given arguments and returns the answer |
| A3 | 4xx, 5xx and network failures give isError with status and message; the next call works |
| A4 | invalid input is refused without a request |
| A5 | no contact, payout or header in logs; only protocol messages on stdout |
| A6 | stdio and Streamable HTTP both work; bin declared (npm publish is milestone 2, marked todo) |
| A7 | this README has the Claude Desktop config and every tool with an example |
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues