Atlas / MCP servers / thelunarcompany / Lunar

LunarBLOCK

mcp/thelunarcompany/lunar

lunar.dev: Agent native MCP Gateway for governance and security

Verdict
BLOCK
Grade
F
Trust score
59 /100
Exposed tools
134 116r · 15w · 3d
Transport
sse · stdio · streamable-http
License
MIT
Stars
501
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Lunar.dev is an open-source platform for managing, governing and optimizing third-party API consumption across applications and AI agent workloads at scale.

Consumption Management for the AI Era

As AI agents and autonomous workflows increasingly rely on external APIs, there's a growing need for a mediation layer that acts as a central aggregation point between applications, agents, and the services they depend on.

Lunar.dev provides that layer—serving as a unified API Gateway for AI, delivering:

  • Live API Traffic Visibility: Get real-time metrics on latency, errors, cost, and token usage across all outbound traffic, including LLM and agent calls.
  • AI-Aware Policy Enforcement: Control tool access, throttle agent actions, and govern agentic traffic with fine-grained rules.
  • Advanced Traffic Shaping: Apply rate limits, retries, priority queues, and circuit breakers to manage load and ensure reliability.
  • Cost & Performance Optimization: Identify waste, smooth traffic peaks, and reduce overuse of costly APIs through smart gateway policies.
  • Centralized MCP Aggregation: Streamline operations by consolidating multiple MCP servers into a single gateway, enhancing security, observabi
Read from source at commit 7950bc3c774aOBSERVED · 2026-09-30
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add testkit-mcp-server --env ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} --env GEMINI_API_KEY=${GEMINI_API_KEY} --env MAX_RESPONSE_TOKENS=${MAX_RESPONSE_TOKENS} --env VITE_AUTH0_AUDIENCE=${VITE_AUTH0_AUDIENCE} -- npx -y @mcpx/[email protected]
claude-desktop
{
  "mcpServers": {
    "testkit-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@mcpx/[email protected]"
      ],
      "env": {
        "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}",
        "GEMINI_API_KEY": "${GEMINI_API_KEY}",
        "MAX_RESPONSE_TOKENS": "${MAX_RESPONSE_TOKENS}",
        "VITE_AUTH0_AUDIENCE": "${VITE_AUTH0_AUDIENCE}"
      }
    }
  }
}
03

Exposed tools (134)

116 read · 15 write · 3 destructive. Blast radius: 3 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
DebuggingreadTrace issues across the stack.
LegacyreadSaved unavailable tools
OperatorsreadOperator access
ReadersreadRead-only access
addwrite
another-skillreadA group-less skill
argreadan arg
assigneereadAssignee username or email
audiencereadTarget audience for the summary, such as reviewers or release managers.
auth_linearreadAuthenticate with Linear
automated-e2e-regression-suite-orchestration-flaky-quarantinewriteRun the full browser regression suite, retry flaky specs, and quarantine persistently failing tests.
bodyreadThe issue body
brand-voice-guidelinesreadReference for tone, terminology, and formatting when drafting external copy.
calculation_summaryreadExplain a calculation result with assumptions and a short confidence note
channelreadThe Slack channel ID.
channelIdreadThe Slack channel that contains the thread.
channels.listreadList Slack channels in the workspace.
chat.postMessagewritePost a message to a Slack channel.
codebase-onboarding-tourreadGenerate a guided, top-to-bottom tour of an unfamiliar repository for a brand-new engineer: start from the entry points and build and run scripts, map the high-level module boundaries and how a request flows from the edge through the service layer down to the data stores, call out the project
commit-msgwriteDraft a commit message from the staged changes and commit
create_issuewriteCreate a GitHub issue
create_repositorywriteCreate a repository
custom_read_filereadCustom read tool for TypeScript files only
custom_repository_reportreadGenerate a repository health report with customized defaults.
custom_safe_readreadRead a **file** safely
cyclereadOptional cycle name or number
delete_filedestructiveDelete a file
delete_repodestructiveDelete a repository
delete_repositorydestructiveDelete an existing repository after validating ownership.
descriptionreadIssue description
diagnostic_summaryreadDraft a short diagnostic summary when an MCP server is unhealthy
draftreaddraft
draft-docs-answerreadDraft an answer from docs.
draft-mereadA skill to draft on.
draft-release-notesreadDraft release notes from merged changes.
echoread
empty-bodywriteCreate a skill before writing instructions.
encodingreadFile encoding
errorreadThe connection or health-check error
evaluatereadEvaluate a deterministic calculation
existingreadExisting desc
explain-library-upgradereadExplain relevant upgrade notes from current docs.
expressionreadThe expression or formula that was evaluated
full-stack-debugging-copilotreadTrace an issue across the browser, API, database, and logs in one pass.
get-library-docsreadFetch documentation for a Context7 library.
get-user-dataread
getEnvread
greetreadsays hi
greet-canonicalizedreadsays hi
health_checkreadCheck whether the remote server is healthy
imported-skillreadImported description
incident_channel_updatewriteCompose a concise incident or rollout update for a Slack channel
includeRiskAssessmentreadInclude deployment, rollback, and compatibility risk notes.
includeRisksreadWhether to include risk notes
internal_pr_templatereadInternal template for pull request updates
issueIdreadLinear issue ID
issue_templatewriteCreate a standard issue draft
issue_triage_summaryreadSummarize open Linear issues
labelsreadComma-separated labels
libraryIdreadThe Context7 library ID.
limitreadMax results
list_dirreadList a directory
list_issuesreadList issues in a repository
list_projectsreadList active Linear projects for a team
list_reposreadList repositories
masked_readreadMasked read
missing-skillreadUpdated description.
missing_descriptionread
my-skillreadDoes a thing
my-toolreadDoes something
newreadd
ownerreadRepository owner
pathreadFile path
pingreadPing the server to check connectivity.
post_messagewritePost a message to a Slack channel
powerOfTworead
prNumberreadPull request number
priorityreadIssue priority
projectNamereadLinear project name
publish-mewriteA skill to publish.
pullNumberreadPull request number whose diff and metadata should be analyzed.
quarterly-board-deck-assemblerreadCompile metrics, narrative, and appendix slides into the standard board template.
read_filereadReads the contents of a file from the filesystem
readersread
release-notes-generatorreadSummarize merged PRs since the last tag into grouped, human-readable release notes.
release_notesreadPrepare release notes
release_promptreadPrepare release notes
reload-toolsreadreloads tools
reporeadTarget repository
repo-reviewreadReview repository changes
request_authentication_linkreadauth
resolve-library-idreadResolve a package name to a Context7 library ID.
resource-onlyreadExisting desc
review-prsreadReviews pull requests and explains when changes need follow-up.
review-pull-requestsreadReview repository changes with the local project rules.
review-pull-requests-v2readUpdated description.
reviewFocusreadArea reviewers should focus on
safe_readreadRead a file safely
search-docsreadSearch docs.
search_messagesreadSearch recent Slack messages
search_repositoriesreadSearch repositories
shared_namereadShared name tool
simple_toolreadA tool without parameters
skillreaddesc
sprint_planning_briefreadDraft a sprint planning brief from Linear project and issue context
stale_toolread
statusreadWorkflow status filter
summarizereadUPDATED
summarize-threadreadSummarize a Slack thread for handoff.
summarize_promptreadSummarize recent file changes
take_screenshotreadCapture a browser screenshot
teamKeyreadLinear team key
temporary-skillreadTemporary skill for route testing.
temporary-skill-updatedreadUpdated details without touching capabilities.
test-toolreadA test tool
textreadThe message text.
threadTsreadThe timestamp of the parent thread message.
titlereadThe issue title
toggle_featurereadToggle a feature flag
toolread
tool1readTest tool
tool2readAnother tool
tool3readNo params tool
tool_areadA tool
topicreadtopic
triagereadTriage issue
update_issue_statuswriteMove a Linear issue to another workflow status
updated-skillreadUpdated description.
valid-mock-skillreadA valid mock skill.
whoamiread
workspace_file_briefreadSummarize important local files and suggest next files to inspect
write-release-noteswriteSummarize merged changes.
write_filewriteWrite a file
write_pull_requestwriteDraft a pull request summary
04

Trust audit

BLOCKgrade F · trust 59/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (10 observation(s))
Network
declared (13 observation(s))
Shell
declared (7 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
mcpx/mcpx-e2e-tests/src/loadScenario.ts:15
const raw = yaml.load(fs.readFileSync(file, 'utf8')) as any;
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
mcpx/mcpx-e2e-tests/src/playwrightMcp.ts:29
const { createConnection } = await (new Function('spec', 'return import(spec)')(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
mcpx/Dockerfile:103
ENV UI_URL=http://127.0.0.1:${UI_PORT}
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
mcpx/mcpx-e2e-tests/src/aiAgents/claudeDesktop.ts:32
const DEFAULT_MCP_URL = 'http://127.0.0.1:9000/mcp';
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
mcpx/mcpx-e2e-tests/src/aiAgents/cursor.ts:23
const DEFAULT_URL = 'http://127.0.0.1:9000/mcp';
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
mcpx/mcpx-e2e-tests/src/aiAgents/cursorCli.ts:23
const DEFAULT_URL = 'http://127.0.0.1:9000/mcp';
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
mcpx/packages/mcpx-server/src/services/env-resolver.test.ts:34
API_KEY: "fixedEnforcedByCatalog",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
mcpx/packages/mcpx-server/src/services/env-resolver.test.ts:44
API_KEY: "fixedEnforcedByCatalog",
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
delete_file, delete_repo, delete_repository
Why it matters. 3 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.dcignore
.dcignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
interceptors/lunar-ts-interceptor/.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
mcpx/.version
.version
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
mcpx/mcpx-e2e-tests/.eslintrc.js
.eslintrc.js
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
mcpx/packages/mcpx-server/.it.env
.it.env
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
mcpx/packages/mcpx-server/it/docker-compose.it.test.yml:9
- ../../../testkit-mcp-server/dist:/app
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
mcpx/packages/mcpx-server/it/docker-compose.it.test.yml:11
- ../../../testkit-mcp-server/node_modules:/app/node_modules
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
mcpx/packages/mcpx-server/src/services/audit-log/audit-log-diff.test.ts:2
import { DEFAULT_CONFIG } from "../../config.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
mcpx/packages/mcpx-server/src/services/audit-log/audit-log-diff.test.ts:3
import { Config } from "../../model/config/config.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
mcpx/packages/mcpx-server/src/services/audit-log/audit-log-diff.test.ts:4
import { ToolGroup } from "../../model/config/permissions.js";
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
mcpx/mcpx-e2e-tests/README.md:102
url: http://127.0.0.1:9000/mcp
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
example-consumer-app/python/requirements.txt
aiohttp, aioconsole, lunar_interceptor
Why it matters. 3 requirement(s) not pinned with ==
Fix. pin exact versions
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
mcpx/demo-client/package.json
@anthropic-ai/sdk, @google/genai, @modelcontextprotocol/sdk, dotenv, winston, @types/node, ts-node, typescript
Why it matters. 8 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
mcpx/mcpx-e2e-tests/package.json
@modelcontextprotocol/sdk, @playwright/mcp, axios, @playwright/test, @types/dockerode, @types/jest, @types/js-yaml, @typescript-eslint/eslint-plugin
Why it matters. 19 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
mcpx/package.json
@eslint/js, concurrently, prompts, globals, typescript-eslint, typescript, eslint
Why it matters. 7 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
mcpx/packages/mcpx-server/package.json
@modelcontextprotocol/sdk, @opentelemetry/api, @opentelemetry/exporter-prometheus, @opentelemetry/sdk-metrics, @types/cors, @types/luxon, cors, dotenv
Why it matters. 34 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-09-30 · audit v0.4.1 · source sha 7950bc3c774afull audit observations/trust-audit/mcp-server/thelunarcompany__lunar.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-09-307950bc3c774aBLOCKF59first audit
06

Questions

What is the Lunar MCP server?

lunar.dev: Agent native MCP Gateway for governance and security

What tools does Lunar expose?

134 in total: 116 read-only, 15 that write, and 3 that can delete or overwrite (delete_file, delete_repo, delete_repository). Every one is listed on this page with its risk.

Is Lunar safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (59/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 3 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does Lunar need?

It reads ANTHROPIC_API_KEY, GEMINI_API_KEY, MAX_RESPONSE_TOKENS, VITE_AUTH0_AUDIENCE, VITE_AUTH0_CLIENT_ID, VITE_AUTH0_DOMAIN and VITE_AUTH_BFF_URL from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Lunar run?

It speaks sse, stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @mcpx/testkit-mcp-server at 1.0.0.

How current is this page?

The grade is for one exact copy of the source (7950bc3c774a), read on 2026-09-30. The repository is watched and re-audited when it changes.

Advertisement