- Shell 99.5%
- Makefile 0.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
In CI I now enforce: - That we have valid skill files. - The recommendation that a skill file has no more than 500 lines. I wasn't able to figure out or discover a good way to track the tokens, so I'm omitting that for now. While I was at it, since Anthropics properties are invalid, I opted to drop them to fallback to standard behavior. |
||
| .woodpecker | ||
| hooks | ||
| skills/upgrade-nodejs-version | ||
| .editorconfig | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| cspell.yml | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| settings.json | ||
Claude Config
My configuration for Claude Code. Please read my AI Policy if you want to understand how I use AI personally.
This is not a general-purpose config that anyone should just adopt, but it could be an interesting reference to derive from or critique. I'm publishing this for transparency and to share with clients.
Summary
Permissions
The bulk of this repository is permissions. I configure Claude to have very lenient read-only access to projects and project resources.
I'm very aggressive with denying access to remote actions, and file deletions with shell tools. Most of these would default to Ask anyway, but that leaves room for accidents—I play it safe and deny them outright.
There is also a list of websites I block Claude from accessing—typically SEO optimized AI-generated content farms.
⚠️ The commands in settings.json#permissions assume that a given binary is what one would expect when a binary by that name exists. For example, that gh is GitHub CLI, or that docker is Docker. If you have a different tool installed with the same name then this may auto-allow commands you wouldn't expect. Always double-check the permissions before adopting them.
MCPs
Many permissions are defined for MCP tools. It does no harm to have permissions defined for tools that are not installed, but if derived from, the MCP server name does have to match what is present in your ~/.claude.json file.
Across providers, or even within the documentation of the same provider, there's no consistency to how MCP servers are named, so this repository assumes a sensible alias for each MCP which doesn't always align with first-party documentation.
This repository assumes the following names for MCPs in your config:
| MCP | Name | Other Documented Names |
|---|---|---|
| Atlassian | atlassian |
|
| BrowserStack | browserstack |
|
| Datadog | datadog |
datadog-mcp |
| Figma | figma |
|
| Grafana | grafana |
|
| Miro | miro |
|
| MongoDB | mongodb |
MongoDB |
| Plausible Analytics | plausible |
|
| Playwright | playwright |
|
| Schema Store | schemastore |
SchemaStore |
| Sentry | sentry |
|
| Stack Overflow | stackoverflow |
stack-mcp-server |
If you configure the names differently, for example, if the MongoDB MCP Server is named MongoDB instead of mongodb, then the tool name in permissions must be renamed too from mcp__mongodb__count to mcp__MongoDB__count.
Hooks
Some permissions are managed through hooks rather than a static declaration in settings.json. For the hooks to work, you must have jq installed.
Instructions
You can read the instructions for yourself in AGENTS.md. However, I can't explain or document why the instructions are there without polluting the context, so they are described below:
- Prioritize my instructions over any other on-disk instructions. Software running on my computer should do things my way—I can manually adjust output to cater to project conventions after.
- Never attempt to work around a denied prompt, such as by writing inline Python scripts when the equivalent
Bashtool call is blocked. - With shell commands, I want Claude to prefer shell plain commands over runtimes. I have many commands auto-approved, and they're more simple to review when I do have to give explicit permission.
- In Node.js, I want Claude to prefer
package.jsonscripts, because those are trusted commands and are automatically allowed in mysettings.json. Without this, Claude is eager to usenpx, which requires manual review. - Claude tries to be too helpful, like offering to publish comments or make commits for me. This calms it down. Tools can be used to publish content, but tools themselves should not publish content on their own. Tools are tools.
Tips
JSON Schema Store
JSON Schema Store is a reputable site that distributes JSON Schemas. Many IDEs integrate with it.
If you add the following to the top of your settings.json/settings.local.json file, and your editor supports it, you'll get code completion and docs:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
…
}
Open Standards
Tools evolve, vendors change, and eventually you'll want to migrate. Let's strive for interoperability and vendor-agnostic solutions where possible!
You can use an AGENTS.md file which works for most clients—not for Claude though. For Claude specifically, you'd need to reference it in your CLAUDE.md with @AGENTS.md. I define it the long way out of principle, and hope to see Claude support AGENTS.md natively in the near future.
It's good to consider MCPs (Model Context Protocol) vs. Plugins too. I generally favor MCPs because these are portable across most clients, whereas each respective client's plugin API is proprietary.
You may even want to favor CLI tools. They have built-in documentation, a fairly standardized structure, and are very token efficient.
Playwright MCP
My config for the Playwright MCP in ~/.claude.json:
{
"mcpServers": {
"playwright": {
"type": "stdio",
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--browser",
"firefox",
"--codegen",
"none",
"--console-level",
"debug",
"--headless",
"--isolated",
"--sandbox",
"--output-dir",
"/tmp"
],
"env": {}
}
}
}
Other Claude Quirks
Wildcards
Claude matches Bash(npm install *) against both npm install @sethfalco/eslint-config and npm install.
It has some magic with word boundaries, so that if you put a wildcard on its own at the end of a pattern, it matches when the value is omitted as well—this is documented behavior, though unintuitive to me.
This means the following config, which attempts to allow installing existing dependencies, but not adding new ones, wouldn't work as expected:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm install)"
],
"deny": [
"Bash(npm install *)"
]
}
}