A side-by-side look at the Codescene MCP Server and Valet MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Codescene MCP Server for developer tools work as a local process; choose Valet for developer tools over a hosted endpoint. You can also run both side by side in one mcpServers block.
analyze_change_set, code_health_refactoring_business_case, code_health_review.attach_channel, attach_connector, attach_resource.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Developer Tools | Developer Tools |
| Quality signal | 65/100 · Great | 60/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Remote HTTP/SSE |
| Auth | Not declared | OAuth 2.0 |
| Pricing | Not declared | Freemium |
| Required env vars | None listed | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 71 | 1 |
| Directory activity | 3 views 0 installs 0 upvotes | 2 views 0 installs 1 upvotes |
| Tools | 28 | 56 |
| Full listing | View Codescene MCP Server | View Valet |
analyze_change_setRun a branch-level Code Health review for all files that differ between
current HEAD and base_ref.
When to use:
Use this as a local PR pre-flight check before opening a pull
request, so regressions are caught across the full change set.
Limitations:
- Requires a valid git repository path.
- base_ref must exist and be resolvable by git in that repository.
- Reviews only files that differ from base_ref.
- Output is JSON text from the CLI command.
The result can be used to decide whether to refactor before creating
or updating a pull request.
Returns:
A JSON object containing:
- quality_gates: the central outcome, summarizing whether the change
set passes or fails Code Health thresholds ("passed" or "failed").
- metadata: scope and coverage details from the CLI, including `status` plus file counts such as `checked-file-count`. Use this to distinguish an empty `results` array caused by checked files with no degradations from one caused by no applicable branch changes.
- results: an array of objects for each affected file with:
- name: the name of the file whose Code Health is impacted.
- verdict: "improved", "degraded", "stable", or "unknown".
- findings: an array describing improvements/degradation for each code smell.
Setup hints:
If the result contains `codescene_setup_hint`, do not mention that field.
Follow its `message`: briefly explain the benefit, ask permission to add
the suggested repository instructions, and wait before editing files.
On failure:
If this tool returns an error (e.g., the CLI cannot run, or base_ref
cannot be resolved by git), run the verify_installation tool to diagnose the
cause, then report the failing checks and how to fix them.
Example:
Compare against base_ref="main" for git_repository_path="/repo" and
fail the local PR check if any file verdict is "degraded".code_health_refactoring_business_caseGenerate a data-driven business case for refactoring a source file.
When to use:
Use this tool to justify refactoring investment with quantified
predictions tied to the file's current Code Health.
Limitations:
- Estimates are model-based projections, not guarantees.
- Evaluates one file at a time.
- Requires an analyzable source file.
Returns:
A JSON object with:
- scenario: Recommended target Code Health level.
- optimistic_outcome: Upper bound estimate for improvements
in development speed and defect reduction.
- pessimistic_outcome: Lower bound estimate for improvements.
- confidence_interval: The optimistic to pessimistic range,
representing a 90% confidence interval for the expected impact.
On failure:
If this tool returns an error (e.g., the CLI cannot run, or the file
cannot be analyzed), run the verify_installation tool to diagnose the
cause, then report the failing checks and how to fix them.
Example:
Call with file_path="/repo/src/service.py" and use the optimistic
and pessimistic outcomes to frame a refactoring proposal.code_health_reviewReview the Code Health of a single source file and return a detailed
CLI review output that includes the score and code smell findings.
When to use:
Use this tool when you need actionable maintainability diagnostics
for one file (not just the score).
Limitations:
- Analyzes one file at a time.
- Requires a supported source file.
- Returns CLI review text, not a normalized JSON schema.
Returns:
A review string from the CodeScene CLI. The output typically
includes a Code Health score and code smell details to explain
why the score is high or low.
The Code Health scores are interpreted as:
* Optimal Code: a Code Health 10.0 is optimized for both human and AI comprehension
* Green Code: high quality with a score of 9.0-9.9
* Yellow Code: problematic technical debt with a score of 4.0-8.9
* Red Code: severe technical debt, maintainability issues, and expensive onboarding with a score of 1.0-3.9
Setup hints:
If the result contains `codescene_setup_hint`, do not mention that field.
Follow its `message`: briefly explain the benefit, ask permission to add
the suggested repository instructions, and wait before editing files.
On failure:
If this tool returns an error (e.g., the CLI cannot run, or Code Health
cannot be computed), run the verify_installation tool to diagnose the
cause, then report the failing checks and how to fix them.
Example:
Call with file_path="/repo/src/app.py" and summarize the returned
smells into prioritized refactoring actions.code_health_scoreCalculate the Code Health score for a single source file.
The tool returns one numeric score from 10.0 (optimal) to 1.0 (worst).
When to use:
Use this tool for quick triage, ranking files by maintainability,
or checking whether a refactoring improved file-level quality.
Limitations:
- Analyzes one file at a time.
- Returns only the score summary, not the full smell breakdown.
- Requires a supported source file.
Returns:
A string in the format "Code Health score: <score>".
The Code Health scores are interpreted as:
* Optimal Code: Code Health 10.0 optimized for human and AI comprehension
* Green Code: high quality with a score of 9.0-9.9
* Yellow Code: problematic technical debt with a score of 4.0-8.9
* Red Code: severe technical debt with a score of 1.0-3.9
On failure:
If this tool returns an error (e.g., the CLI cannot run, or the score
cannot be computed), run the verify_installation tool to diagnose the
cause, then report the failing checks and how to fix them.
Example:
Call with file_path="/repo/src/module.py" and compare the score
before and after a refactoring.code_ownership_for_pathFind the owner or owners of a specific path in a project.
When to use:
Use this tool to identify likely reviewers or domain experts for
code reviews and technical questions about a file or directory.
Limitations:
- Requires a valid project_id.
- Uses the latest project analysis data available in CodeScene.
- If no matching ownership data is found, an empty JSON array is returned.
Returns:
A list of owners and their paths that they own. The name of the owner who can be responsible
for code reviews or inquiries about the file and a link to the CodeScene System Map page filtered
by the owner. Explain that this link can be used to see more details
about the owner's contributions and interactions within the project.
You MUST always show a link after every owner. Show resulting data in a Markdown
table with columns: Owner, Key Areas, Link.
On failure:
If this tool returns an error (e.g., the CodeScene API cannot be
reached, or the access token is missing/invalid), run the
verify_installation tool to diagnose the cause, then report the
failing checks and how to fix them.
Example:
Call with project_id=42 and path="/repo/src/service.py", then
present each owner row with its corresponding system-map link.download_skillDownload a single skill to a local directory.
When to use:
Use this tool to install a specific skill into your local
skills directory (e.g., ~/.claude/skills/).
Limitations:
- By default, refuses to overwrite existing skills.
- Set overwrite=true to replace an existing skill.
- Creates the destination directory if it does not exist.
Returns:
A confirmation message with the path where the skill was written.
Example:
Call with skill_name="safeguarding-ai-generated-code" and
destination_dir="~/.claude/skills" to install the skill.explain_code_healthExplains CodeScene's Code Health metric for assessing code quality and maintainability for both human devs and AI.
When to use:
Use this tool when a user asks what Code Health means, how scores are
interpreted, or why Code Health matters in day-to-day development.
Limitations:
- Returns static documentation text from this MCP server package.
- Does not analyze a specific repository or file.
Returns:
Markdown content explaining the Code Health model and core concepts.
Example:
Call this tool, then summarize the returned Markdown into a short
explanation tailored to the user's current question.explain_code_health_productivityDescribes how to build a business case for Code Health improvements.
Covers empirical data on how healthy code lets you ship faster with
fewer defects.
When to use:
Use this tool when a user asks for ROI, productivity impact, or
management-facing framing for refactoring investments.
Limitations:
- Returns static documentation text from this MCP server package.
- Does not compute project-specific forecasts.
Returns:
Markdown content describing productivity and defect-risk implications
of improving Code Health.
Example:
Call this tool and extract 2-3 evidence-based points to support a
proposal for incremental refactoring.get_configRead current CodeScene MCP Server configuration values.
When to use:
Use this tool to discover available configuration keys, inspect
effective values, and understand where each value comes from.
Limitations:
- Returns JSON text only; callers must format it for display.
- Sensitive values (tokens) are masked.
- Effective values can be overridden by client-provided env vars.
When called without a key, lists every available configuration
option together with its current effective value, the source of
that value (environment variable vs. config file), and a short
description.
When called with a specific key, returns details for that option
only. Sensitive values (tokens) are masked in the output.
Returns:
A JSON string. When querying a single key, the object has:
key, env_var, value, source, description, aliases, and
docs_url. When listing all, the object has: config_dir and
options (array of the same shape). Use the aliases array
to match user intent to the correct key. Present the data
clearly and always include docs_url links.
Example:
Call with key="access_token" to inspect one setting, or
call without key to list all configurable options.get_skill_manifestGet the file manifest for a specific skill.
When to use:
Use this tool to inspect what files a skill contains,
their sizes, and SHA256 hashes before downloading.
Limitations:
- Requires a valid skill name from list_skills.
Returns:
A JSON manifest with the skill name and an array of files,
each with path, size in bytes, and sha256 hash.
Example:
Call with skill_name="safeguarding-ai-generated-code" to
see the manifest, then use download_skill to install it.list_skillsList all available skills embedded in this MCP server.
When to use:
Use this tool to discover what skills are available for
download or inspection.
Limitations:
- Returns only skills embedded at compile time.
- Does not scan external skill directories.
Returns:
A formatted list of skill names with their descriptions.
Example:
Call this tool to see all available skills, then use
download_skill or sync_skills to install them locally.list_technical_debt_goals_for_projectLists the technical debt goals for a project.
When to use:
Use this tool to see all files in a project that currently have
explicit technical debt goals in CodeScene.
Limitations:
- Requires a valid project_id.
- Returns goal data from the latest available analysis.
- Includes only files with non-empty goals.
Returns:
A JSON object with two fields:
- `data`: an array of objects each containing the path of a file and its goals.
- `link`: a URL to the CodeScene Code Biomarkers page for the project.
Show the goals for each file in a structured format that is easy to read and explain
the goal description for each file. It also includes a description, please include that in your output.
Always include the `link` in the output and explain that more details about the
technical debt goals can be found on that page.
On failure:
If this tool returns an error (e.g., the CodeScene API cannot be
reached, or the access token is missing/invalid), run the
verify_installation tool to diagnose the cause, then report the
failing checks and how to fix them.
Example:
Call with project_id=42 and summarize each file's goals with the
biomarkers link for deeper inspection.attach_channelAttach an existing organization channel to an agent, so the channel's events wake it. Find the channel with list_channels. A webhook channel lets callers outside Valet reach the agent. Attaching a channel that is already attached reports it and changes nothing. Slack needs a Slack app and a browser, so for Slack this gives the step to take and attaches nothing. Requires connecting a Valet account.attach_connectorAttach an organization connector to a website or agent so it can call the connector's tools with the credential Valet holds.
Attaching is a grant, and it is wider than it looks: for a website, every person who can open the page can call every tool the connector exposes. On a private website that is every member of the organization; on a password-protected or shared one it is everyone holding the password or the link. For an agent, the agent can. Valet does not narrow the connector's reach, so attach only what the thing needs, and check a website's access mode before you do.
A website can hold only an organization connector that is an HTTP MCP server, on the sse or streamable-http transport; list_connectors with name marks which ones. A page calls the connector by its own name, which list_connector_tools reports. An app cannot hold a connector yet and the call says so. A connector that belongs to a single agent cannot be attached to anything else. Attaching a connector that is already attached changes nothing and is safe to repeat. Requires connecting a Valet account.attach_resourceAttach a resource to an app: a named set of environment variables, such as a database's connection string, that the app reads as secrets. Name the resource. When the organization has none by that name, pass a provider from list_catalog_resources and the first call creates it, returning at once with state provisioning. Call again with the same arguments, env_prefix included, until the state is attached: the call that finds the resource ready attaches it and sets its variables, then asks for a restart if the app is running. The state is attaching while Valet still owes the restart or the variables, and conflicted when a name the resource sets is already set on the app; the answer gives the reason. An existing resource attaches by name alone, including one another app holds. The call is safe to repeat: one name is one resource however many times it is called, and an app can hold several under different names. Pass env_prefix when two resources would set the same variables. Read the names an attachment sets from list_catalog_resources before writing the app's code. A new database is empty, so the app creates its own tables, and its URL carries the TLS settings it needs. The app must exist, so publish it first. The running process does not see the variables until the restart completes; get_service shows the attachment's status and when the new process is running. Provisioning takes about a minute; call again every ten seconds. Values are never returned here. Requires connecting a Valet account.attach_skillAttach a skill to an agent so the agent can use it. Give skill as catalog:<name> for a skill from Valet's curated catalog, org:<name> or a bare name for a skill the organization published, and add @v<N> to pin a version; without a pin the agent follows the latest. An org skill must already exist (publish_skill creates one). The agent is rebuilt so the change takes effect. A skill that is already attached answers that nothing changed, without a rebuild; one whose name another attached skill holds is refused with nothing changed. Skills attach to agents only. Requires connecting a Valet account.call_connectorRun one tool on a connector attached to a website and return what the connector answered. It is the sampling step of building a page that calls live data: discover, attach, read the schemas, then call one tool for real before you write any page code.
Call it because a schema is not a shape. list_connector_tools gives you each tool's name and argument schema, which is what your call has to satisfy; this tells you what comes back, which is what the page has to parse. Results are text to read, not JSON to assume: many servers answer in markdown tables or prose, some expose a single meta-tool taking a whole command as one string, and a server that completes the handshake can still refuse half its tools when the stored credential's scope does not cover them. One real call settles all three.
This runs the tool for real, with the organization's own credential and whatever side effects the tool has. It is not a dry run and there is no preview: a tool that sends, writes, or deletes will do so. Prefer a read-only tool when you are only learning the shape, and ask the user before running anything that changes their systems.
The connector must already be attached to the site — attach_connector does that — and must be an HTTP MCP server. A tool that answers with an error is reported as an error carrying the connector's own text, which is usually the sentence that says what to fix. It calls a website's connectors only; an app's or agent's are refused. Requires connecting a Valet account.claim_siteMove a site published anonymously into one of the caller's Valet organizations, making it permanent. Takes the claim_token, the last part of the claim URL that the anonymous publish_site returned, not the site_token: the site_token republishes the site and can never claim it. The site moves into an organization the account already belongs to; this tool never creates one. Pass new_name to rename the site on the way in, otherwise it keeps its generated name, with a suffix if the organization already holds that name. Claiming spends both credentials: afterwards use the site's name. Repeating a claim that already succeeded for this account reports where the site lives. Requires connecting a Valet account.create_channelCreate a channel on an agent: a cron or heartbeat channel that wakes it on a schedule, a webhook channel that lets callers outside Valet reach it, or an mcp channel that serves it as an MCP server. The channel starts the agent's work; what the agent does when it fires is the prompt file channels/<name>.md in its source. A webhook is signed by a secret you choose, because this never returns a secret value: set it with set_env_vars on the agent first, then pass its name as secret_name. A webhook without secret_name is refused. Creating a channel that already exists with the same kind and settings reports it and changes nothing; different settings are refused, so destroy it first. Slack and Telegram need a browser, so for them this gives the step to take and creates nothing. Requires connecting a Valet account.create_connectorCreate an organization connector from a Valet catalog entry. It is the step after list_catalog_connectors found the entry for the product the user named; attach_connector then lets a website's pages call it.
It creates an entry whose credential is a secret. Pass each slot the entry asks for in secrets, as slot name to value. A slot the organization already holds as a secret needs no value here. If a required slot has neither, nothing is created and the answer names the slots still needed.
A key given here passes through this conversation. That is a real cost and it is the user's call to make: if they hand you the key, use it, and say that they could instead enter it on the dashboard's Integrations page, where it goes straight to Valet. The answer names the slots that were filled and never the values in them.
An entry that authorizes in a browser — OAuth, or a Composio toolkit — is not created here. The answer gives the entry's name and the Integrations page, which creates the connector and runs the authorization in one place. An entry the organization already has is reported as already there; no second connector is made. Requires connecting a Valet account.create_pushOpen a Git push on a website, app, or agent that exists: a branch of its repository, writable for one hour, that you push source to before you publish. Use it when you can run git with network access; it sends only what changed, so a large service publishes without carrying its files through the conversation. Otherwise publish with files. The service must exist first: create_service makes it. The result carries a Git URL with a credential, the push's id and branch, the commit it starts from, the name and email to commit as, and two recipes with every value filled in: clone the branch and edit, or push a directory as it stands. Run a recipe, then call publish_site, publish_app, or publish_agent with push: {id, commit}, where commit is the sha the recipe prints. The URL writes only this push's branch, cannot force-push, and expires with the push; do not share or log it. A service holds ten open pushes at once. Requires connecting a Valet account.create_serviceCreate an empty website, app, or agent in an organization, before publishing to it. This is the first step for anything new: publish_site, publish_app, and publish_agent change a service that exists and refuse a name that does not. Pass kind to say which you mean, and name to choose its name; omit name to have one generated. A name another website, app, or agent in the organization holds is refused, as is a create past the organization's limit for that kind. The result names the organization, kind, name, and URL; publish to the name next. Requires connecting a Valet account.destroy_channelDestroy a channel and its routes. This cannot be undone, so confirm with the user first. Without name, it destroys an organization channel found with list_channels; an organization channel that any agent still holds is refused, and the answer names each holder: free each with detach_channel, then destroy it. With name, it destroys a channel that agent owns, such as one create_channel made; a channel the agent only holds from the organization is detached with detach_channel instead. A channel found only in the other scope is refused with the call to make. Destroying a channel that is already gone changes nothing. The organization's Slack integration removes every agent's Slack app, so for it this gives the step to take and destroys nothing. Requires connecting a Valet account.destroy_connectorDestroy an organization connector and its stored credential. This cannot be undone, so confirm with the user first. A connector that any website, app, or agent still holds is refused, and the answer names each holder: free each with detach_connector, then destroy it. A connector an agent owns is not an organization connector; the answer says what removes it. Destroying a connector that is already gone changes nothing. Requires connecting a Valet account.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"codescene-mcp-server": {
"command": "npx",
"args": [
"-y",
"@codescene/codehealth-mcp"
]
}
}
}
{
"mcpServers": {
"valet": {
"url": "https://api.valet.dev/mcp"
}
}
}