▸ Read atomeve.dev/start.md and set up SEO Improver agent in my project: install it, wire up and verify its credentials, and run it once.Improves your search rankings, week over week.
Each week it:
You get a rankings snapshot and a short report of this week's actions.
If your blog is on GitHub, it can open a pull request with the highest-confidence changes. It never pushes to your default branch and never merges.
Setup lives in SETUP.md.
The agent reads rankings through a Google service account that your Search Console property trusts. Any Google Cloud project on any of your Google accounts works; the only thing that ties it to your site is adding its email as a user in Search Console.
With the gcloud CLI signed in:
gcloud services enable searchconsole.googleapis.com
gcloud iam service-accounts create seo-improver
gcloud iam service-accounts keys create /tmp/seo-improver-key.json \
--iam-account=seo-improver@PROJECT_ID.iam.gserviceaccount.com
Without gcloud: in the Cloud Console, enable the Search Console API, create a service account (no roles needed), and add a JSON key under Keys, then Add key. Keep the key file outside the project and delete it once the env var is set.
Then the one step that is always manual: in Search Console, select the property, open Settings, then Users and permissions, click Add user, and add the service account's email. Restricted permission is enough; the agent only reads.
Set GSC_CREDENTIALS_JSON to the entire key-file JSON as a single line.
To verify: mint an access token from the key (JWT bearer grant against
https://oauth2.googleapis.com/token, scope https://www.googleapis.com/auth/webmasters.readonly)
and GET https://www.googleapis.com/webmasters/v3/sites. The token-minting code ships in
agent/lib/search-console.ts, ready to reuse. Free and read-only. The property
must appear with a permissionLevel other than siteUnverifiedUser; an empty list means
the user-add step is missing or still propagating (it can take a minute).
DataForSEO provides the competitive layer: who ranks above you, search volume, keyword gaps. Sign up at dataforseo.com (trial credit available), then copy the API login and password from the API Access page. The API credentials are separate from your dashboard sign-in.
To verify: GET https://api.dataforseo.com/v3/appendix/user_data with HTTP Basic auth
(login:password). Free and read-only; expect status_code: 20000 in the response body.
Local runs read .env.local (gitignored). Deployed and scheduled runs read Vercel
project env: vercel env add NAME production takes the value from stdin, so pipe it in.
Keep GSC_CREDENTIALS_JSON on a single line, quoted so the embedded quotes and
backslashes survive dotenv parsing.
Fill in the <!-- project-config --> block at the top of agent/instructions.md with
your property, domain, and optional keywords and blog repo. Leaving the blog repo unset
keeps the agent report-only. Setting it lets the agent open pull requests against your
blog: it runs the gh CLI in its sandbox and never pushes to your default branch. gh
authenticates from GH_TOKEN; if the GitHub CLI is signed in locally, gh auth token
prints one, or create a fine-grained token with write access to just that repo.
The exact source npx atom-eve add installs — instructions, tools, and skills. Read it here, or copy any file straight into your project.
connections/dataforseo.tsimport { defineMcpClientConnection } from "eve/connections";
// DataForSEO uses HTTP Basic auth (login:password); `auth` only emits Bearer
// tokens, so the header is built here at the connection layer and the model
// never sees the credentials.
export default defineMcpClientConnection({
url: "https://mcp.dataforseo.com/mcp",
description:
"DataForSEO rankings data: live SERP results by keyword/location, the domain's ranked keywords with position and search volume, keyword gaps against competitors, and search volume lookups.",
headers: {
Authorization: `Basic ${Buffer.from(
`${process.env.DATAFORSEO_LOGIN ?? ""}:${process.env.DATAFORSEO_PASSWORD ?? ""}`,
).toString("base64")}`,
},
// The hosted server exposes every DataForSEO module; this agent needs
// exactly four read tools.
tools: {
allow: [
"serp_organic_live_advanced",
"dataforseo_labs_google_ranked_keywords",
"dataforseo_labs_google_domain_intersection",
"keywords_data_google_ads_search_volume",
],
},
});