32 KiB
adapter-1c-mcp
Thin MCP proxy for the 1C REST adapter.
Target host:
docker.cin.su
Runtime URL:
http://docker.cin.su:8021
MCP endpoint for Codex:
http://docker.cin.su:8021/mcp
The server responds with MCP protocol 2025-06-18 and returns
Mcp-Session-Id during initialize.
Legacy SSE endpoint:
http://docker.cin.su:8021/sse
Direct JSON-RPC endpoint for smoke tests:
http://docker.cin.su:8021/mcp
Codex config:
[mcp_servers.adapter-1c-mcp]
enabled = true
url = "http://docker.cin.su:8021/mcp"
Already running Codex Desktop windows can keep the MCP tool list from their startup time. Restart Codex Desktop, or start a fresh session, after changing MCP server configuration.
How The Adapter URL Is Passed
The MCP proxy does not hard-code the 1C adapter address. Pass it with:
ONEC_ADAPTER_URL=http://docker-gpu.cin.su:8011
Optional adapter bearer token:
ONEC_ADAPTER_TOKEN=
Timeout for adapter HTTP calls:
ONEC_ADAPTER_TIMEOUT_SECONDS=4
These variables are configured in:
core/deploy/docker/adapter-1c-mcp/.env.example
For real deployment, create a non-committed .env next to the compose file and set the actual adapter URL/token there.
Deploy
Deploy both REST adapter and MCP proxy, then run live verification when a test base is available:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context>
Multiple test bases can be verified in one deploy:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-1>,<base-id-2>
Duplicate base ids are rejected before verification starts, so persisted reports are not overwritten by an accidental repeated base value.
To make post-deploy checks deterministic, pass an explicit metadata object selector. This is optional; without it the smoke discovers a module-capable object automatically.
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-ObjectGuid <metadata-object-guid> `
-ObjectKind <metadata-kind>
Saved-state preparation defaults to ConfigSave for the base configuration
save layer. Use -SavedStateTable ConfigCASSave when the strict smoke should
target an extension/CAS save layer instead:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-SavedStateTable ConfigCASSave
The deploy script prints Docker container summaries for both services, then the
verify script prints /health status and contract_version before running the
REST and MCP selector-chain smoke tests. The selector-chain smoke also checks,
when a routine name is available from module metadata, that
metadata.resolve_overrides returns write_plan_evidence.next_resolution for
metadata.saved_state.modules.search with the same base_id and routine query,
plus a public object ref/kind/name and semantic
layer=base_saved_state|extension_saved_state; public follow-ups never require
ConfigSave, ConfigCASSave, or owner_guid. The smoke then follows that
resolver. If a saved-state stream exposes write_plan_target,
the smoke composes it with write_plan_evidence.target and checks the resulting
read-only metadata.write.plan; when the test base has no saved-state stream,
that last composition step records skipped_no_saved_state_target.
These selector-chain reports are written under
reports/1c-sql/<base-id>/selector-chain-rest-smoke.json and
reports/1c-sql/<base-id>/selector-chain-mcp-smoke.json. Each report includes
a top-level coverage block summarizing whether override evidence was found,
whether the saved-state resolver ran, whether a write_plan_target was
available, and which steps were skipped. The verify script validates that both
selector-chain report files are written, parse as JSON, pass, and include the
expected coverage sections.
Use -RequireSelectorChainWritePlanComposition when the test base is expected
to contain a matching saved-state stream and the selector-chain smoke must fail
instead of accepting skipped_no_saved_state_target.
Verification also runs the read-only write-plan safety smoke through both REST
and MCP onec_request; the MCP smoke also checks that live methods without
payload.base_id are stopped by adapter_1c_mcp_policy.v1 with
base_id_required, and that low-level storage.*/query.* fallback calls are
blocked as diagnostic_method unless diagnostics are explicitly requested. The
verify script validates the written write-plan safety reports after each smoke.
Then verification runs REST saved-state form/module write-loop smoke tests
through metadata.write; if the test base has no pending
ConfigSave/ConfigCASSave rows, those saved-state checks record
skipped_no_saved_state and pass by default. The saved-state report files are
also parsed and checked after the smoke commands. Before those smoke tests,
verification generates read-only saved-state-strict-readiness.json and
saved-state-copy-plan.json reports for the selected -SavedStateTable. The
copy plan is generated through scripts/plan_1c_saved_state_copy.py using the
same object selector arguments, so the later persisted-report check has fresh
copy-preparation evidence. At the end, verification runs
scripts/check_1c_verify_reports.py against the persisted report set, so the
same report validation can be repeated offline without calling the adapter.
The offline validator checks that selector-chain coverage includes
metadata.resolve_overrides evidence, the expected
metadata.saved_state.modules.search next step, saved-state resolution, and
attempted metadata.write.plan composition. It also verifies write-plan safety
outcomes: effective form writes must route to metadata.write.plan,
uncontrolled replacement must be blocked, controlled replacement must be
planned through metadata.module.write_apply, drift must be blocked, and MCP
policy checks must block missing base_id and diagnostic fallback.
Saved-state write smoke reports are checked in both modes: empty-state skips
must include successful preflight counts and skipped=true; real
write-and-rollback runs must include allowed write plans, expected apply
methods, and rollback evidence. The same persisted report validator also checks
saved-state-strict-readiness.json and saved-state-copy-plan.json when
saved-state write smoke reports are enabled. Readiness must match the requested
base_id and selected save-layer table; in strict mode it must be ready=true.
The copy plan must match the requested base_id, resolve a concrete object,
list active source rows from the matching storage family, be plan_ready, and
show clear target collision status for ConfigSave/ConfigCASSave. The family
must match the target save layer: Config -> ConfigSave for base changes and
ConfigCAS -> ConfigCASSave for extension/CAS changes. The validator also
checks that readiness, copy-plan target table, saved-state form smoke table, and
saved-state module smoke module_ref table are the same.
scripts/check_powershell_scripts.py also guards the verify/deploy wiring for
these strict flags and asserts that check_1c_verify_reports.py --self-test
covers selector-chain, safety, saved-state, and copy-plan failure classes.
Persisted report validation also pins the expected JSON schema value for each
report type, so stale or unrelated report files fail before their contents are
trusted.
The same validator checks report identity: each persisted JSON must match the
requested base_id, and REST/MCP reports must match their expected
transport. When verification provides expected endpoints, REST/MCP reports
must also match the configured endpoint_url.
To require an actual saved-state write-and-rollback instead of allowing the empty-state skip:
python scripts\check_1c_saved_state_strict_readiness.py `
--base-id <base-id-from-project-context> `
--saved-state-table ConfigSave `
--report reports\1c-sql\<base-id>\saved-state-strict-readiness.json `
--json
This readiness check is read-only. It checks REST adapter health, row counts in
the selected save-layer table, and saved-state form/module discovery. Use
--saved-state-table ConfigSave for the base save layer or
--saved-state-table ConfigCASSave for the CAS/extension save layer. If it
reports blocked_no_saved_state_rows, there are no unactivated Configurator
changes in the selected save layer. To prepare a strict write test, copy the
target object from the main configuration storage (Config/ConfigCAS) into
the selected save layer through the approved saved-state workflow, then rerun
readiness before enabling strict mode.
To produce a read-only copy preparation plan for a concrete object:
python scripts\plan_1c_saved_state_copy.py `
--base-id <base-id-from-project-context> `
--kind <metadata-kind> `
--name <metadata-object-name> `
--target-table ConfigSave `
--report reports\1c-sql\<base-id>\saved-state-copy-plan.json `
--json
The copy plan does not write SQL. It lists active storage rows for the selected
object only from the matching source family, checks whether the intended
ConfigSave/ConfigCASSave target already contains the same FileName values,
and records the intended save-layer target. --target-table ConfigSave plans
from Config; --target-table ConfigCASSave plans from ConfigCAS. Normal
verification regenerates this file automatically before saved-state smoke tests
and uses -SavedStateTable to pick the same target table for the copy plan,
form smoke, and module smoke. Run the command manually when choosing a target
object for strict readiness or when preparing evidence without the full
deploy/verify flow. The offline persisted-report validator checks this file by
default, so regenerate the plan whenever the chosen object, target table, or
base changes.
To generate the reviewed SQL preparation script from that plan without executing SQL:
python scripts\prepare_1c_saved_state_copy_sql.py `
--plan reports\1c-sql\<base-id>\saved-state-copy-plan.json `
--expected-base-id <base-id-from-project-context> `
--expected-target-table ConfigSave `
--sql-out reports\1c-sql\<base-id>\prepare-saved-state-copy.sql `
--report reports\1c-sql\<base-id>\prepare-saved-state-copy-sql.json `
--json
This generator does not call the adapter and does not write SQL. It refuses
plans that are not plan_ready, have target collisions, or mix storage
families. The generated SQL is a manual review artifact: it starts a
transaction, rechecks that the save-layer target has no planned FileName
values, copies only the planned rows with INSERT ... SELECT, verifies the
copied row count, and commits only if those guards pass.
To execute the reviewed preparation SQL, use the explicit SQL-write gate. This is not run by deploy/verify:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\execute_1c_saved_state_copy_sql.ps1 `
-Server <sql-server> `
-Database <sql-database> `
-User <sql-user> `
-Password <sql-password> `
-ExpectedBaseId <base-id-from-project-context> `
-ExpectedTargetTable ConfigSave `
-IUnderstandThisWritesToSql
The executor validates the generated SQL report, checks that the SQL file still
looks like the reviewed saved-state copy artifact, records the SQL SHA1, runs
the SQL through System.Data.SqlClient, and immediately calls the read-only
post-copy verifier. Credentials can also be supplied with ONEC_SQL_SERVER,
ONEC_SQL_DATABASE, ONEC_SQL_USER, and ONEC_SQL_PASSWORD. Do not commit
credentials or execution reports containing environment-specific connection
details.
After the SQL preparation has been executed, verify the saved-state copy read-only before enabling strict write smoke:
python scripts\verify_1c_saved_state_copy.py `
--plan reports\1c-sql\<base-id>\saved-state-copy-plan.json `
--expected-base-id <base-id-from-project-context> `
--expected-target-table ConfigSave `
--report reports\1c-sql\<base-id>\saved-state-copy-verify.json `
--require-ready `
--json
Before the SQL preparation is executed, this verifier is expected to report
blocked_missing_target_rows. After preparation it must report ready=true by
comparing the save-layer FileName, PartNo, byte sizes, and BinarySHA1
values against the reviewed active-source rows from the copy plan.
Also generate the guarded cleanup script before executing the preparation SQL, so there is a reviewed way to remove the prepared working-copy rows later:
python scripts\prepare_1c_saved_state_cleanup_sql.py `
--plan reports\1c-sql\<base-id>\saved-state-copy-plan.json `
--expected-base-id <base-id-from-project-context> `
--expected-target-table ConfigSave `
--sql-out reports\1c-sql\<base-id>\cleanup-saved-state-copy.sql `
--report reports\1c-sql\<base-id>\cleanup-saved-state-copy-sql.json `
--json
The cleanup SQL deletes only the planned FileName/PartNo rows from the
selected save layer, and only when their current BinarySHA1 still matches the
reviewed copy plan. It rolls back if the rows are missing, extra/mismatched, or
if the deleted row count differs from the plan.
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-RequireSavedStateWriteSmoke
To require selector-chain evidence to resolve all the way to a concrete
read-only metadata.write.plan composition:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-RequireSelectorChainWritePlanComposition
To skip saved-state write-loop checks entirely:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-SkipSavedStateWriteSmoke
To skip only the read-only write-plan safety smoke:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-BaseId <base-id-from-project-context> `
-SkipWritePlanSafetySmoke
To validate the latest persisted reports without contacting REST or MCP:
python scripts\check_1c_verify_reports.py --base-id <base-id-from-project-context>
Add --rest-adapter-url <url> --mcp-url <url> when the persisted REST/MCP
reports should be pinned to specific endpoints.
Add --saved-state-table ConfigSave or --saved-state-table ConfigCASSave
when the persisted saved-state reports must be pinned to a specific save-layer
table.
Add --max-report-age-seconds <seconds> when the persisted reports must also
be fresh enough for a deployment gate.
Use --skip-saved-state-copy-plan only when intentionally validating an older
report bundle that does not include saved-state-copy-plan.json.
To run the offline validator's synthetic soft/strict self-test:
python scripts\check_1c_verify_reports.py --self-test
To run the whole offline/static verification-stack preflight:
python scripts\check_1c_adapter_verification_stack.py --base-id <base-id-from-project-context>
The verification-stack preflight passes the default REST/MCP endpoint URLs to
the persisted report validator. Override them with --rest-adapter-url and
--mcp-url for non-default deployments.
It also passes --saved-state-table, defaulting to ConfigSave, so
persisted copy-plan/form/module reports must match the intended save-layer
table.
Pass multiple base ids after --base-id to validate several persisted report
directories in one run.
Use --max-report-age-seconds to reject stale report files during the
verification-stack preflight.
To save a machine-readable verification-stack summary:
python scripts\check_1c_adapter_verification_stack.py `
--base-id <base-id-from-project-context> `
--json `
--report reports\1c-sql\<base-id>\adapter-verification-stack-check.json
The saved stack report keeps per-command return codes, compact parsed summaries for JSON-producing checks, and truncated stdout/stderr tails for diagnostics. For persisted verify-report checks, the parsed summary also includes per-base REST/MCP selector-chain composition status, write-plan safety check counts, and saved-state write smoke status, including the saved-state copy-plan target, source-row count, and target collision status.
To deploy without live verification:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\deploy_1c_adapter_stack.ps1 `
-SkipVerify
Low-level MCP-only deploy:
docker --host ssh://docker.cin.su compose `
--env-file core\deploy\docker\adapter-1c-mcp\.env.example `
-f core\deploy\docker\adapter-1c-mcp\compose.yaml `
up -d --build
Container name:
adapter-1c-mcp
Health
Invoke-RestMethod http://docker.cin.su:8021/health
docker --host ssh://docker.cin.su ps --filter name=adapter-1c-mcp
docker --host ssh://docker.cin.su logs --tail 80 adapter-1c-mcp
Smoke test MCP initialize:
$body = @{
jsonrpc = "2.0"
id = 1
method = "initialize"
params = @{
protocolVersion = "2025-06-18"
capabilities = @{}
clientInfo = @{ name = "smoke"; version = "1" }
}
} | ConvertTo-Json -Depth 10
Invoke-WebRequest `
-Uri "http://docker.cin.su:8021/mcp" `
-Method Post `
-ContentType "application/json" `
-Headers @{ Accept = "application/json, text/event-stream" } `
-Body $body
Tools
The MCP proxy exposes a small stable tool surface:
onec_health
onec_help
onec_request
onec_job_get
onec_job_cancel
access_role_users
access_role_profiles
access_role_audit_export
access_role_audit_analyze
access_user_explain
access_users_search
access_object_explain
access_keys_query
access_object_keys_resolve
access_object_roles
access_object_subjects
access_rls_discover
Use onec_request(method, payload) for uncommon or newly added adapter methods
until a dedicated alias is useful enough to keep stable.
The access_* tools are lightweight aliases for common access-audit workflows;
they only forward to REST adapter methods such as access.role.users and keep
all BSP/access-rights logic in the REST adapter.
For object access checks, pass object names/public refs first; the REST adapter resolves GUIDs, SQL numbers, BSP identifiers, synonyms, and readable role-rights names internally. Example:
python scripts\smoke_1c_access_object.py `
--base-id upo_test `
--ref "РегистрСведений.УОП_АктуальныеСпецификации" `
--action write
Use access_object_roles or access_object_subjects for the question "which
roles/users can read or write this metadata object". Do not depend on
metadata.objects.list kind=Role: some live bases do not expose roles as regular
metadata objects through that route.
For BSP data-access keys, keep the metadata object and concrete data record separate:
{
"base_id": "upo_test",
"kind": "object",
"object_ref": "Справочники.Номенклатура",
"record_ref": "00112233445566778899AABBCCDDEEFF"
}
Here kind=object is the access_keys_query area, not the metadata kind.
object_ref is resolved to the internal BSP SQL number and record_ref to the
record id. The same public pair works with access_object_keys_resolve and
access_object_explain; do not invent object_sql_number in MCP code.
For BSP role-right checks, action=write means add or modify rights. Read-only
roles must not be returned for write; query action=read separately when you
need visibility roles. Returned permissions keep source_fields from
ПраваРолей so suspicious mappings can be verified against the live base.
access.snapshot.extract also supports this access graph and defaults to the
BSP extractor preset when queries are not supplied. Passing preset=bsp
explicitly is still fine, but the old "No extractor queries were provided"
discovery response should not appear for a normal BSP base.
When access_object_subjects is called with include_access_key_scope=true,
the regular limit only trims returned roles/profiles/groups/users. Scope
diagnostics use separate controls: access_key_scope_subject_limit limits how
many matched groups/users are checked, and access_key_scope_limit limits rows
read from each BSP access-key extractor. Check access_key_scope.coverage and
access_key_scope.truncated before treating the scope sample as complete.
For local audit artifacts, use the workspace script:
python scripts\export_1c_access_role_audit.py `
--base-id upo_test `
--role "запись изменение номенклатура поставщиков" `
--user-threshold 30
It writes CSV, JSON export, analysis JSON, and a summary file under
reports/1c-access/<base_id>/. By default it also writes a self-contained
HTML report with findings, counters, artifact links, and a filterable user table;
pass --no-html to skip it.
Architecture contract:
- The REST adapter owns 1C behavior, payload validation, decoding, owner
resolution, RAG/tool-facing data shape, and method documentation through
help.methods. - MCP is a transport proxy: JSON-RPC/MCP framing, adapter URL/token handling,
generic
onec_request, job polling/cancellation helpers, and lightweight agent-safety checks such as requiringbase_idfor live database methods. - Do not add method-specific 1C business logic to MCP. Put it in the adapter,
expose it through
/rpc, and make it discoverable viahelp.methods. - Do not register an MCP unified/composite handler with the same name as an
adapter method;
onec_request(method=...)must call the adapter method, not shadow it inside MCP. - When adding a new adapter method, verify it through MCP with
onec_request({"method": "...", "payload": {...}}). MCP should not require a schema edit for ordinary adapter growth. - Run
python scripts/check_1c_mcp_adapter_contract.pybefore release; it verifies thatonec_requeststays generic and that every method listed by the REST adapter is forwarded through/rpc.
Example:
{
"method": "metadata.object.get",
"payload": {
"base_id": "<base_id-from-project-context>",
"kind": "document",
"name": "ПриходнаяНакладная",
"view": "merged"
}
}
Do not copy placeholder or sample base_id values from documentation into real
requests. For live database methods, get base_id from the current project,
user request, environment, or another authoritative context.
Agent Request Policy
The MCP proxy blocks live database methods without payload.base_id before
calling the REST adapter. This is intentional: agents must not probe metadata,
modules, extensions, queries, storage, or code without a concrete target base.
Affected method families include:
metadata.*
modules.*
code.*
templates.*
diagnostics.*
extensions.*
query.*
storage.*
schema.*
codec.*
Allowed without base_id:
onec_help / help.methods
onec_health without a base for generic service health
adapter.job.get / adapter.job.cancel
Agent rules:
- If
base_idis unknown, ask for it or obtain it from project context. - For object-scoped calls, use one of the public selector shapes supported by
the adapter:
ref,kind+name,guid, or MCP-friendlyobject_type/object_name/object_guid. Do not add MCP-side conditions for concrete object names. - If a prior result contains
module_ref,module_id, GUID, or read selector, use direct read methods before global search. - If a search result contains
read_selector.method, call that method with the selector payload.code.searchselectors point tocode.read;modules.searchselectors point tomodules.read. - If a result contains
related_selectors, prefer those payloads for the next object-scoped call. They preservekind/name/guidand includerefwhen the adapter knows the canonical object kind and name. - When
modules.searchorcode.searchresolves a module owner, keep both the public owner selector (ref,kind,name,guid) and the opaquemodule_refin the next read payload.module_refis the direct read handle;refmakes the owner clear to the agent and later calls. - When narrowing
code.searchto one module, passmodule_ordinaltogether with the object selector. The adapter response should remain a publiconec_code_search.v1object withitem.read_selector, not a low-level tuple or storage result. - For BSL edits, prefer high-level
metadata.writewith a 1C canonical path,routine_text, androutine_operation. Do not ask the user for SQL/save gates: the adapter prepares saved-state when needed, writes only to the saved-state working layer, and does not activate changes. Usemetadata.form.command_button.writefor the complete form command + visible button + handler workflow.code.writeremains a compatibility shortcut for simple module edits. - For a metadata object's standard
synonymorcomment, call genericonec_requestwithmethod=metadata.object.property.write, a publicref/kind+name, andallow_saved_state_write=true. Preferexecution_mode=planfirst. The adapter resolves GUIDs and serialized paths; MCP callers must not pass SQL tables or file names. Object rename and adding a new synonym locale are intentionally unsupported. - For an existing requisite, tabular section, dimension, or resource, add a
public
member_refsuch asCatalog.Номенклатура.Attribute.Артикул. When onlymember_kind+member_nameis used and several identities match, preserve the adapter'sambiguousresult and retry with the full member path. - To add a requisite, call
metadata.object.member.addthroughonec_requestwith a fulltemplate_member_reffrom the same object and the new public name/synonym. Never invent a GUID, Config table, collection path, or type descriptor in MCP code; the new requisite inherits type/settings from the named template. - The same method adds a tabular-section column when
template_member_refcontains the full...TabularSection.<name>.Attribute.<column>path. Keep the complete path so duplicate checks and generated identity remain scoped to that table part. - For unresolved module owners, inspect
diagnostics.owner_resolutionandcounts.owner_scan_limit_hit; narrow bykind/name/guidor increaseowner_scan_limitbefore falling back to broader searches. - Do not treat
not_foundfrommetadata.definition.findor scoped search as proof that code is absent in extensions or ConfigCAS. - Treat
partial,truncated=true, scan limits, and timeouts as incomplete evidence.
Offline selector-chain smoke:
python scripts\smoke_1c_mcp_selector_chain.py --json --no-report
Saved-state BSL write smoke:
python scripts\smoke_1c_code_write_saved_state.py `
--adapter-url http://docker-gpu.cin.su:8011 `
--base-id <base-id-from-project-context> `
--extension <extension-name> `
--object-type CommonForm `
--object-name <form-name> `
--routine-name <routine-name> `
--json
This smoke performs idempotent code.write mode=apply checks with the current
routine text, a unique old/new fragment, and the current full
module_text. It then verifies code.read state=working,
code.read state=both, marker-hiding for saved form modules, and saved-state
form indexing. Every write step must report write_mode.target=saved_state
and activation_state=not_activated.
Agent working-view report:
python scripts\report_1c_agent_working_view.py `
--adapter-url http://docker-gpu.cin.su:8011 `
--base-id <base-id-from-project-context> `
--extension <extension-name> `
--object-type CommonForm `
--object-name <form-name> `
--routine-name <routine-name> `
--json
This read-only report shows the form names that an agent sees in the
working/save layer and verifies that code.read state=working and
state=both prefer saved_state when saved code exists.
The concise agent-facing coding rules are kept in
docs/runbooks/1c-agent-coding-contract.md.
Run this with the contract checks before release. It validates generic agent
routes through onec_request and rejects concrete object names in selector
examples.
Optional live selector-chain smoke against a real adapter/base:
python scripts\smoke_1c_mcp_selector_chain.py `
--live `
--transport rest `
--adapter-url http://docker-gpu.cin.su:8011 `
--base-id <base-id-from-project-context> `
--json `
--no-report
To verify both deployed layers with one command:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\verify_1c_adapter_deployment.ps1 `
-BaseId <base-id-from-project-context>
By default this also writes
reports/1c-sql/<base>/code-write-saved-state-rest-smoke.json and
reports/1c-sql/<base>/code-write-saved-state-mcp-smoke.json when the default
saved-state code-write target exists. The REST verification also writes
reports/1c-sql/<base>/agent-working-view.json to pin the save-first working
view that agents should use for coding. Use
-RequireCodeWriteSavedStateSmoke to make that smoke mandatory, or
-SkipCodeWriteSavedStateSmoke to skip it for bases where the scenario is not
available.
Pass multiple base ids to run the same REST and MCP checks against each base:
powershell -NoProfile -ExecutionPolicy Bypass `
-File scripts\verify_1c_adapter_deployment.ps1 `
-BaseId <base-id-1>,<base-id-2>
Use -ObjectRef, or -ObjectKind with -ObjectName/-ObjectGuid, to verify a
specific module-capable metadata object instead of auto-discovery.
Use -SavedStateTable ConfigSave or -SavedStateTable ConfigCASSave to choose
which save-layer table is used by the copy plan and saved-state write smokes.
Add -RequireSelectorChainWritePlanComposition when the selected base/object
must have a saved-state stream that lets the selector-chain smoke compose a
concrete read-only metadata.write.plan. The same strict mode also requires
the write-preflight smoke to discover an extension form by public
extension/ref/form/member names, compose an allowed plan, and prove that the
repository and support gates use the same resolved extension:<GUID> layer.
Run that check directly with
scripts/smoke_1c_write_preflight.py --require-name-first-extension-form.
To exercise the MCP proxy itself, switch transport and URL:
python scripts\smoke_1c_mcp_selector_chain.py `
--live `
--transport mcp `
--mcp-url http://docker.cin.su:8021 `
--base-id <base-id-from-project-context> `
--json `
--no-report
Live mode discovers a module-capable object from metadata lists and then checks
adapter.help.methods -> metadata.definition.find -> related_selectors.modules -> metadata.object.modules -> modules.read -> code.search -> item.read_selector -> code.read using the returned selector and a token derived
from module text or routine metadata. The adapter.help.methods step verifies
live REST contract_version and selector_capabilities, so stale REST adapter
images fail before the longer chain. MCP transport also performs initialize,
checks tools/list for the same contract_version and the generic
onec_request selector schema, keeps Mcp-Session-Id, and sends adapter calls
through tools/call + onec_request. This catches stale MCP proxy images where
REST works but agents still see old tool descriptions. Do not commit real base
ids or captured reports from live runs.
- Avoid increasing global search limits when a direct selector is already available.
- Do not request
include_storage=truemerely to read a module found by search; use the publicread_selectorfirst.
The request is proxied to the REST adapter through POST /rpc:
{
"method": "metadata.object.get",
"payload": {}
}
The MCP proxy intentionally does not know adapter-specific 1C methods. Add new
methods in the REST adapter and expose them through help.methods; MCP stays
unchanged unless the MCP transport itself changes.