Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ new version heading in the same commit.

## [Unreleased]

## [0.459.1] - 2026-10-12
### Fixed
- **The "DataForSEO (v2 tools)" connector now authenticates.** The v2 server reads its login from
`DATAFORSEO_USERNAME`, not `DATAFORSEO_LOGIN`, so a connector added from the 0.458.0 catalog entry got
HTTP 401 on every call. The entry now sets `DATAFORSEO_USERNAME` from the same `secret:DATAFORSEO_LOGIN`
vault key, so one stored login serves both versions. The v3 entry was unaffected.
**For admins:** if you added "DataForSEO (v2 tools)" on 0.458.0, remove it and add it again with the same name.

## [0.459.0] - 2026-10-12
### Changed
- **Picking an assignee on an Inbox proposal card accepts it.** The card's assignee picker now moves an
Expand Down
4 changes: 3 additions & 1 deletion docs/connectors/dataforseo.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ remote session to drop.
skills already name those tools.
3. Fill both fields with `secret:DATAFORSEO_LOGIN` / `secret:DATAFORSEO_PASSWORD`. They are resolved from
the vault at launch, and an unresolvable reference is blanked and audited as
`connector.secret.unresolved`.
`connector.secret.unresolved`. The login lands in a different env var per version: v3 reads
`DATAFORSEO_LOGIN`, v2 reads only `DATAFORSEO_USERNAME` and answers every call with HTTP 401 without it.
The catalog entries set the right one; a hand-built connector must too.

**Keep the connector's NAME when replacing an old one.** The MCP server key is the connector id (a slug of
its label), and tool names are `mcp__<id>__<tool>`. Replacing a `DataforSEO` connector with one labelled
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agent-os",
"version": "0.459.0",
"version": "0.459.1",
"description": "A generic, governed operating system for running autonomous agents safely across brands. Ships with a local web console.",
"license": "MIT",
"type": "commonjs",
Expand Down
5 changes: 3 additions & 2 deletions scripts/connector-auth-stub-test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ async function main() {
assert(/catalog/.test(authStubRemedy({ url: 'https://mcp.dataforseo.com/mcp' })), 'the hosted-DataForSEO remedy points at the catalog entry');

console.log('\n\x1b[1m2) DataForSEO catalog entries run locally, pinned, with vault creds\x1b[0m');
for (const [type, ver] of [['dataforseo', /^3\./], ['dataforseo-v2', /^2\./]]) {
// The login env var is per version: v2 only reads DATAFORSEO_USERNAME and 401s on every call without it.
for (const [type, ver, login] of [['dataforseo', /^3\./, 'DATAFORSEO_LOGIN'], ['dataforseo-v2', /^2\./, 'DATAFORSEO_USERNAME']]) {
const e = CATALOG.find((c) => c.type === type);
const spec = e && npxSpec({ transport: e.transport, command: e.command, args: e.args });
const m = spec && /^dataforseo-mcp-server@(\d+\.\d+\.\d+)$/.exec(spec);
assert(e?.transport === 'stdio' && m && ver.test(m[1]), `${type}: stdio, exact pinned version (${spec})`);
assert(e?.fields.map((f) => f.key).join() === 'DATAFORSEO_LOGIN,DATAFORSEO_PASSWORD' && e.fields.every((f) => /secret:/.test(f.placeholder || '')), `${type}: API login + password fields, vault refs suggested`);
assert(e?.fields.map((f) => f.key).join() === `${login},DATAFORSEO_PASSWORD` && e.fields[0].placeholder === 'secret:DATAFORSEO_LOGIN' && e.fields.every((f) => /secret:/.test(f.placeholder || '')), `${type}: ${login} + password fields, both from the same vault keys`);
}

console.log('\n\x1b[1m3) npx pre-fetch\x1b[0m');
Expand Down
4 changes: 3 additions & 1 deletion src/connectors/connectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,11 @@ export const CATALOG: CatalogEntry[] = [
transport: 'stdio',
command: 'npx',
args: ['-y', 'dataforseo-mcp-server@2.9.13'],
// v2 reads DATAFORSEO_USERNAME (v3 reads DATAFORSEO_LOGIN, falling back to USERNAME). The env var
// differs; the vault key does not, so one stored DATAFORSEO_LOGIN serves both versions.
fields: [
{
key: 'DATAFORSEO_LOGIN',
key: 'DATAFORSEO_USERNAME',
label: 'API login',
placeholder: 'secret:DATAFORSEO_LOGIN',
help: 'The API login from app.dataforseo.com/api-access (not your dashboard login). Store it in Settings → Secrets and enter secret:DATAFORSEO_LOGIN here.',
Expand Down
Loading