Repository navigation
examples/mcp: the examples/sila machine served to AI assistants; the kind facts move into python/onemachine - #27
Merged
Merged
Conversation
…ry consumer A consumer's table is about its protocol's words. What a kind says about a role does not depend on the protocol: the fields it reports and commands, what bounds the command (a light's max), the values and labels, the scale and unit, a text's length, and the arithmetic between a raw integer and a presented value. role_facts(machine, role) reads them from the description and the command and report schemas, and refuses by name a description that does not hold what its kind needs. test/role/facts_check.py holds it to the examples/sila machine (46 checks) and runs in test/role/build.sh. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Its table keeps the SiLA words (type, property, command, parameter); the description's field names, the bounds, values, labels, scale, unit, the text length and the presented/raw arithmetic come from role_facts. The feature definitions it generates are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An MCP server (stdio) that reads the machine's description over the link and generates a tool per role: <role>_get, <role>_set or <role>_fire, and status. The schema of each _set is built from the kind and the description (a light's level up to its max, a select's labels, a text's length, a scaled value's bounds in its unit); a value outside it is refused with a tool error naming the parameter and the bound, and nothing is sent. A set returns the value the device holds. The kind facts come from python/onemachine; the table holds the MCP words. Serves the examples/sila machine: no new firmware. Promoted from R&D/OneMachine/mcpConsumer @ fce471e Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ough python/onemachine consumers.md names examples/mcp as a second worked example and says, in rule 1 and in "Adding a consumer", that a kind's facts come from role_facts while the consumer's table holds the protocol's words. The README lists the example. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One machine, two consumers.
examples/mcpserves theexamples/silamachine to AI assistants over MCP (Claude Code and others): a_get,_setor_firetool per role, generated from the machine's description, with the bounds in each tool's JSON Schema. No new firmware.To make that a second consumer and not a second copy, what a kind says about a role moves into
python/onemachine(role_facts), and each consumer's table keeps only its protocol's words.examples/sila/gateway.pygoes from 328 to 267 lines and generates the same feature definitions.Commits
python/onemachine: role_facts— the kind table (KINDS),Facts,KindError,role_facts;test/role/facts_check.py(46 checks), run bytest/role/build.sh.examples/sila: the gateway reads the kind facts from python/onemachine.examples/mcp—server.py,requirements.txt,README.md.docs—consumers.mdand the README name the example; rule 1 says where the kind facts come from.Where the claims are
KINDSpython/onemachine/machine.py:231,Facts:246,role_facts:288; the arithmetic between raw and presented values:presented:262,to_raw:265(nearest integer of the decimal as written, halves away from zero),label_of:272,raw_of:276,pack_text:280,unpack_text:285.KINDSexamples/sila/gateway.py:60holds the SiLA words only;model():86callsrole_facts(:92) and then applies its own unit table (UNITS:71) and the finite-decimal rule (decimal_str:75); the setter and the publisher useFactsat:207-209and:227-229.KINDSexamples/mcp/server.py:43holds the parameter names;Role:60;model():147callsrole_facts(:153);Factsis used at:68,:111-116,:131,:139-142.test/role/facts_check.py(the eight kinds of theexamples/silamachine, the arithmetic, 14 refusals by name from edited descriptions, 7 field-shape refusals from stub schemas); plugged in attest/role/build.sh:77.Serverdoes not validate arguments againstinputSchema;server.pyvalidates every argument itself (Role.refuse,examples/mcp/server.py:97-131).Identity (ran)
examples/silamachine are byte-identical to the onesorigin/maingenerates (diff -r, 8 files).tools/listresult and theinstructions(captured over JSON-RPC, 16 tools, 434 characters of instructions) are byte-identical to those of the server before it was moved.examples/silafirmware frommain, image97f1f9ea…5614e, built from this branch'sexamples/sila): the full end-to-end run with an independent SiLA 2 client (unitelabs-sila0.10.0,sila_base58290aa): 124 checks as before. The only differences from the same run onmain: three refusal messages are reworded (below), and one negative check, which patchedto_rawingateway.py, patches nothing now thatto_rawis inpython/onemachine; the same mutation made inFacts.to_rawfails the same duty edge case (SetValue(0.05)reads 0.0, not 0.1) on the Nano, and the specified rounding passes.lamp_set 250reach the board, which clamps it; a schema withoutmaximumchangestools/list; an answer from the previous report fails the set-after-set check).Factsreporting a light's bound asmax - 1(ased-patched copy), the Lamp definition changes to 199 andlamp_set'smaximumchanges to 199, andfacts_check.pyfails.claude mcp addthenclaude mcp listreports Connected).Behaviour that changes
... which the X row does not useis now... which the X kind does not use(a label on a discrete) and... which the X kind does not print(a strayvalue,scaleorunitline). They still name the role and the thing.analogrole has a scale that is zero or negative: the SiLA gateway used to accept it and the MCP server (before it was moved) refused it; both now accept it (the positive-scale rule is kept forscaled, where it orders the bounds).Local test notes
test/role/build.shlocally: 34 ok, 1 failed. The failure,role_link_avr(AVR image size 6984 against the 6950 baseline), is the same on an untouchedorigin/mainhere (33 ok, 1 failed), so it is the local AVR toolchain and not this branch; CI's toolchain decides.Not here
examples/mcphas no network transport, authentication, tuned roles, timeouts or reconnect (its README says so). The link helpers (Traced,open_link) are still a copy in each example.🤖 Generated with Claude Code