c64-mcp 0.99.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. c64_mcp-0.99.0/.gitignore +8 -0
  2. c64_mcp-0.99.0/AGENTS.md +11 -0
  3. c64_mcp-0.99.0/CHANGELOG.md +64 -0
  4. c64_mcp-0.99.0/LICENSE +190 -0
  5. c64_mcp-0.99.0/NOTICE +16 -0
  6. c64_mcp-0.99.0/PKG-INFO +133 -0
  7. c64_mcp-0.99.0/README.md +122 -0
  8. c64_mcp-0.99.0/docs/specs/2026-07-26-vice-sampling-ergonomics.md +459 -0
  9. c64_mcp-0.99.0/pyproject.toml +48 -0
  10. c64_mcp-0.99.0/src/c64_mcp/__init__.py +13 -0
  11. c64_mcp-0.99.0/src/c64_mcp/__main__.py +34 -0
  12. c64_mcp-0.99.0/src/c64_mcp/config.py +71 -0
  13. c64_mcp-0.99.0/src/c64_mcp/contracts/__init__.py +1 -0
  14. c64_mcp-0.99.0/src/c64_mcp/contracts/c64-vice-api-v1.json +501 -0
  15. c64_mcp-0.99.0/src/c64_mcp/errors.py +103 -0
  16. c64_mcp-0.99.0/src/c64_mcp/ghidra_client.py +390 -0
  17. c64_mcp-0.99.0/src/c64_mcp/profile_tools.py +104 -0
  18. c64_mcp-0.99.0/src/c64_mcp/profiles/__init__.py +1 -0
  19. c64_mcp-0.99.0/src/c64_mcp/profiles/c64.json +2036 -0
  20. c64_mcp-0.99.0/src/c64_mcp/server.py +488 -0
  21. c64_mcp-0.99.0/src/c64_mcp/text/__init__.py +5 -0
  22. c64_mcp-0.99.0/src/c64_mcp/text/codec.py +476 -0
  23. c64_mcp-0.99.0/src/c64_mcp/text/tables.json +7190 -0
  24. c64_mcp-0.99.0/src/c64_mcp/text/tables.py +132 -0
  25. c64_mcp-0.99.0/src/c64_mcp/text/tools.py +745 -0
  26. c64_mcp-0.99.0/src/c64_mcp/tool_profiles.py +400 -0
  27. c64_mcp-0.99.0/src/c64_mcp/vice.py +1071 -0
  28. c64_mcp-0.99.0/src/c64_mcp/vice_contract.py +416 -0
  29. c64_mcp-0.99.0/tests/integration/test_apply_c64_profile.py +77 -0
  30. c64_mcp-0.99.0/tests/integration/test_define_c64_text.py +33 -0
  31. c64_mcp-0.99.0/tests/integration/test_vice_tools.py +98 -0
  32. c64_mcp-0.99.0/tests/test_c64_profile.py +141 -0
  33. c64_mcp-0.99.0/tests/test_config.py +63 -0
  34. c64_mcp-0.99.0/tests/test_ghidra_client.py +354 -0
  35. c64_mcp-0.99.0/tests/test_main.py +31 -0
  36. c64_mcp-0.99.0/tests/test_profile_tools.py +129 -0
  37. c64_mcp-0.99.0/tests/test_server.py +185 -0
  38. c64_mcp-0.99.0/tests/test_text_codec.py +297 -0
  39. c64_mcp-0.99.0/tests/test_text_tables.py +92 -0
  40. c64_mcp-0.99.0/tests/test_text_tools.py +450 -0
  41. c64_mcp-0.99.0/tests/test_tool_profiles.py +261 -0
  42. c64_mcp-0.99.0/tests/test_vice.py +663 -0
  43. c64_mcp-0.99.0/tests/test_vice_contract.py +290 -0
  44. c64_mcp-0.99.0/tools/generate_c64_profile.py +593 -0
  45. c64_mcp-0.99.0/tools/generate_text_tables.py +220 -0
  46. c64_mcp-0.99.0/tools/release +12 -0
  47. c64_mcp-0.99.0/tools/release.py +420 -0
  48. c64_mcp-0.99.0/uv.lock +1255 -0
@@ -0,0 +1,8 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ .mypy_cache/
4
+ .ruff_cache/
5
+ __pycache__/
6
+ dist/
7
+ build/
8
+ *.egg-info/
@@ -0,0 +1,11 @@
1
+ # AGENTS.md
2
+
3
+ - Never use conventional-commit prefixes (`feat/`, …) in commit titles or branch names
4
+
5
+ ## Releasing
6
+
7
+ - **Do not write tests for the release script.** No unit tests, no fixtures, no
8
+ mutation checks, no CI assertions about it. Releasing is verified by running
9
+ `tools/release <major|minor|patch>` and seeing what happens; a test suite around
10
+ it has repeatedly cost more than it caught. If a release breaks, fix the script.
11
+ - This is a standing instruction from the maintainer, not an oversight to correct.
@@ -0,0 +1,64 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ### Changed
6
+
7
+ - Renamed the project from `ghidra-mcp-c64` to `c64-mcp`, and the Python package
8
+ from `ghidra_mcp_c64` to `c64_mcp`. The old name implied a sibling of
9
+ `ghidra-mcp-next`; this is not a Ghidra extension and contains no Java. It is an
10
+ MCP server that reaches Ghidra over HTTP and VICE through the connector's
11
+ TraceRMI contract, and roughly half of it — the PETSCII and screen-code tables,
12
+ the C64 symbol profile, the tool-visibility profiles — needs neither.
13
+ **The console script is now `c64-mcp`**: update the `command` in any `.mcp.json`
14
+ and re-sync the virtualenv, which otherwise keeps the old script.
15
+
16
+ ### Added
17
+
18
+ - Added `tools/release <major|minor|patch>`, a single command that refuses unless
19
+ the checkout is on the default branch, clean and exactly in sync with origin,
20
+ then writes the version to `pyproject.toml`, regenerates `uv.lock`, rolls the
21
+ changelog, runs the gates through `uv run --locked` against that candidate,
22
+ builds, commits, tags and pushes. There is deliberately no publishing step:
23
+ nothing consumes a c64 release, and its compatibility with the connector rests
24
+ on the `c64.vice/1` runtime handshake rather than on matching versions.
25
+ Everything that can fail runs before the push, since the push cannot be undone;
26
+ until then a failure restores the working tree, the index and the branch ref.
27
+
28
+ ### Changed
29
+
30
+ - Version moves to `0.99.0`. `__version__` is now derived from installed package
31
+ metadata rather than duplicated as a literal, so it cannot drift from
32
+ `pyproject.toml`.
33
+ - Dropped `connector.version` from the packaged `c64-vice-api-v1.json`, matching
34
+ the connector: it is release metadata rather than part of the `c64.vice/1`
35
+ compatibility surface, and keeping it required a coordinated commit here on
36
+ every connector release. The runtime `connector_version` from `status` is
37
+ unaffected.
38
+
39
+ ### Added
40
+
41
+ - `minimal`, `static`, `vice`, and `full` tool-visibility profiles with
42
+ runtime group listing, search, load, and unload tools.
43
+ - Initial standalone package scaffold.
44
+ - Immutable, source-cited 256-entry PETSCII and C64 screen-code tables for
45
+ both C64 character-set modes.
46
+ - Lossless bounded PETSCII/screen-code decoding with fixed, terminated, and
47
+ length-prefixed sources, high-bit policies, control rendering, and
48
+ caller-owned token expansion.
49
+ - `decode_c64_text`, `search_c64_text`, and dry-run-first
50
+ `define_c64_text` MCP tools over the public Ghidra HTTP boundary.
51
+ - A versioned, source-attributed C64 profile covering VIC-II, SID, CIA,
52
+ KERNAL, vectors, workspace, control-bit equates, and opt-in memory
53
+ templates.
54
+ - `get_c64_symbol_profile` and dry-run-first
55
+ `apply_c64_symbol_profile` MCP tools.
56
+ - A strict packaged `c64.vice/1` connector contract and race-safe local
57
+ binding keyed by the Ghidra target token and connector instance ID.
58
+ - Complete `vice_*` tools for connector-owned registers, banks, memory,
59
+ checkpoints, execution, stop waits, reset, and cached session status.
60
+ - Dry-run-first `copy_vice_memory_to_ghidra`, with one complete VICE read,
61
+ SHA-256 verification, exactly one generic program write, and no payload
62
+ echo.
63
+ - Distinct connector, generic TraceRMI, and HTTP timeout reporting with
64
+ operation-specific uncertainty flags and no automatic retries.
c64_mcp-0.99.0/LICENSE ADDED
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ Copyright 2026 Saverio Proto
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.
c64_mcp-0.99.0/NOTICE ADDED
@@ -0,0 +1,16 @@
1
+ c64-mcp
2
+ Copyright 2026 Saverio Proto
3
+
4
+ This product includes C64-specific interoperability data whose individual
5
+ source attributions are recorded with the bundled profile and codec tables.
6
+
7
+ The bundled PETSCII and screen-code tables are transcribed from Appendices B
8
+ and C of the Commodore 64 Programmer's Reference Guide, published by
9
+ Commodore Business Machines, Inc. The package data records the source URL and
10
+ printed page references.
11
+
12
+ The bundled C64 symbol profile is transcribed and normalized from the
13
+ Commodore 64 Programmer's Reference Guide and Service Manual and the
14
+ MOS/Commodore 6581 SID and 6526 CIA data sheets. The generated package data
15
+ records the source title, relevant section or page range, and URL for every
16
+ symbol group.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: c64-mcp
3
+ Version: 0.99.0
4
+ Summary: C64-specific MCP tools for Ghidra and the Ghidra VICE connector
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: mcp==1.28.1
10
+ Description-Content-Type: text/markdown
11
+
12
+ # c64-mcp
13
+
14
+ C64-specific MCP tools layered over the public `ghidra-mcp` HTTP API and the
15
+ separately installed Ghidra VICE connector.
16
+
17
+ The server uses stdio transport by default. It does not open a VICE binary
18
+ monitor socket; the connector remains the sole owner of that connection.
19
+
20
+ ## Tool visibility
21
+
22
+ The default `static` profile exposes the symbol and text groups plus four
23
+ small catalog-management tools. This keeps live-debugger schemas out of the
24
+ agent context until they are needed. `minimal` starts with management tools
25
+ only, `vice` starts with the live-debugger group, and `full` exposes every
26
+ tool.
27
+
28
+ Use `list_c64_tool_groups`, `search_c64_tools`, and
29
+ `load_c64_tool_group` to discover and expose hidden tools at runtime.
30
+ `unload_c64_tool_group` removes only groups loaded after startup; profile
31
+ baseline groups remain visible. Thus `static` followed by loading `all`
32
+ still permits unloading the transient VICE group, while the `full` profile
33
+ does not permit partial unloading.
34
+
35
+ ## VICE debugger tools
36
+
37
+ The `vice_*` tools bind to the active **VICE C64 Debugger** TraceRMI target
38
+ through the generic Ghidra MCP HTTP API. Install and launch the separately
39
+ released `ghidra-vice-connector` first, then call `vice_connect`. The handshake
40
+ checks the complete versioned `c64.vice/1` method schema, capability set,
41
+ machine, limits, and immutable connector instance ID. Compatibility is based
42
+ on that runtime contract rather than an assumed package-version pairing.
43
+
44
+ The tool set covers cached status, dynamic registers and banks, bank-aware
45
+ memory, checkpoints, execution control, stop-event waits, and reset.
46
+ `vice_disconnect` releases only this MCP process's local binding; it never
47
+ closes the connector socket, trace, or VICE process. `vice_status` is cached
48
+ and performs no discovery or network operation.
49
+
50
+ `copy_vice_memory_to_ghidra` is the only implicit bridge from live VICE memory
51
+ to a static program. It performs one complete connector read, verifies the
52
+ exact byte count, computes SHA-256, and calls the generic
53
+ `write_memory_bytes` endpoint exactly once. It defaults to `dry_run=true` and
54
+ never returns the complete payload. It does not create memory blocks or
55
+ disassemble.
56
+
57
+ Connector, generic target-method, and HTTP timeouts remain distinguishable.
58
+ Mutating timeout responses explicitly say which VICE or Ghidra state may have
59
+ changed, and no timed-out operation is retried automatically. The C64 MCP
60
+ contains no VICE monitor host, port, socket, or binary protocol fallback.
61
+
62
+ ## C64 symbol profile
63
+
64
+ `get_c64_symbol_profile` returns the bundled, versioned C64 platform profile.
65
+ `apply_c64_symbol_profile` applies that exact profile to an explicitly named
66
+ Ghidra program through the generic `apply_symbol_profile` endpoint. It
67
+ defaults to `dry_run=true`, `conflict_policy=error`, and memory-block creation
68
+ disabled. Re-applying an unchanged profile is idempotent.
69
+
70
+ The profile covers the 6510 processor port, all VIC-II and SID registers,
71
+ both CIA devices, color RAM, the 39 standard KERNAL jump-table entry points,
72
+ processor vectors, and common KERNAL workspace addresses. Value-only equates
73
+ name documented VIC-II, SID, and CIA control bits. Optional RAM, ROM, I/O,
74
+ and color-RAM block templates are only considered when
75
+ `create_memory_blocks=true`; the generic endpoint preflights the complete
76
+ request before mutation and refuses ordinary-block overlap.
77
+
78
+ The checked-in profile is generated deterministically by
79
+ `tools/generate_c64_profile.py`. Every symbol group cites its authoritative
80
+ Commodore manual or chip data sheet in the package data.
81
+
82
+ ## C64 text tools
83
+
84
+ The server includes immutable 256-entry mappings for upper/graphics and
85
+ lower/upper PETSCII and C64 screen codes:
86
+
87
+ - `decode_c64_text` decodes inline hex/byte arrays or an exact bounded read
88
+ from a named Ghidra program.
89
+ - `search_c64_text` searches an inclusive program range by exact raw bytes or
90
+ exact decoded Unicode code points.
91
+ - `define_c64_text` decodes first, then sends one flat contiguous region to
92
+ Ghidra with byte typing, an optional label/namespace, and a complete plate
93
+ comment. It defaults to `dry_run=true`.
94
+
95
+ Every decode uses exactly one of a positive fixed `length`, a one-byte
96
+ `terminator`, or a one/two-byte little-endian `prefix_size`. Terminators are
97
+ consumed but excluded from text. Prefixes are consumed and excluded from
98
+ text, and may either describe payload length or include themselves.
99
+
100
+ `high_bit` accepts `exact`, `strip`, or `annotate_reverse`; the latter is
101
+ screen-code-only. `controls` accepts `names`, `escaped`, or `unicode`.
102
+ Lossless payload output retains every original text byte as a stable fragment
103
+ such as `{A:$41}`, `{CLR:$93}`, or `{REV A:$81}`. Prefix and terminator bytes
104
+ remain available in `consumed_bytes` and the per-byte records even though
105
+ framing bytes are excluded from both decoded text renderings.
106
+
107
+ Caller token maps use unprefixed decimal keys (`"129"`) or explicitly
108
+ hexadecimal keys (`"0x81"`). Expansion is single-pass by default. Recursive
109
+ mode recognizes two-digit hexadecimal references such as `{81}`, enforces a
110
+ caller-selected depth, detects cycles, and fails rather than truncating when
111
+ the aggregate rendering cap is exceeded.
112
+
113
+ All reads and inline inputs have a 1 MiB hard cap. Search defaults to 64 KiB
114
+ and 100 results, with hard caps of 1 MiB and 1,000 results. Ghidra reads must
115
+ be complete; partial or unmapped reads are errors.
116
+
117
+ The normative mapping source is Appendices B and C of the official
118
+ *Commodore 64 Programmer's Reference Guide*. The generated package data
119
+ records the source URL and printed page references.
120
+
121
+ ## Configuration
122
+
123
+ - `GHIDRA_MCP_URL` defaults to `http://127.0.0.1:8089`.
124
+ - `GHIDRA_MCP_AUTH_TOKEN` optionally supplies a bearer token.
125
+ - `GHIDRA_MCP_TIMEOUT` defaults to 30 seconds.
126
+ - `GHIDRA_MCP_C64_TOOL_PROFILE` accepts `minimal`, `static`, `vice`, or
127
+ `full`; the default is `static`.
128
+
129
+ The `--tool-profile` command-line option overrides the environment setting.
130
+
131
+ VICE method calls accept a caller-visible `timeout_ms` from 1 through 55,000.
132
+ The wrapper reserves an additional five seconds for generic TraceRMI
133
+ invocation and another five seconds for HTTP transport.
@@ -0,0 +1,122 @@
1
+ # c64-mcp
2
+
3
+ C64-specific MCP tools layered over the public `ghidra-mcp` HTTP API and the
4
+ separately installed Ghidra VICE connector.
5
+
6
+ The server uses stdio transport by default. It does not open a VICE binary
7
+ monitor socket; the connector remains the sole owner of that connection.
8
+
9
+ ## Tool visibility
10
+
11
+ The default `static` profile exposes the symbol and text groups plus four
12
+ small catalog-management tools. This keeps live-debugger schemas out of the
13
+ agent context until they are needed. `minimal` starts with management tools
14
+ only, `vice` starts with the live-debugger group, and `full` exposes every
15
+ tool.
16
+
17
+ Use `list_c64_tool_groups`, `search_c64_tools`, and
18
+ `load_c64_tool_group` to discover and expose hidden tools at runtime.
19
+ `unload_c64_tool_group` removes only groups loaded after startup; profile
20
+ baseline groups remain visible. Thus `static` followed by loading `all`
21
+ still permits unloading the transient VICE group, while the `full` profile
22
+ does not permit partial unloading.
23
+
24
+ ## VICE debugger tools
25
+
26
+ The `vice_*` tools bind to the active **VICE C64 Debugger** TraceRMI target
27
+ through the generic Ghidra MCP HTTP API. Install and launch the separately
28
+ released `ghidra-vice-connector` first, then call `vice_connect`. The handshake
29
+ checks the complete versioned `c64.vice/1` method schema, capability set,
30
+ machine, limits, and immutable connector instance ID. Compatibility is based
31
+ on that runtime contract rather than an assumed package-version pairing.
32
+
33
+ The tool set covers cached status, dynamic registers and banks, bank-aware
34
+ memory, checkpoints, execution control, stop-event waits, and reset.
35
+ `vice_disconnect` releases only this MCP process's local binding; it never
36
+ closes the connector socket, trace, or VICE process. `vice_status` is cached
37
+ and performs no discovery or network operation.
38
+
39
+ `copy_vice_memory_to_ghidra` is the only implicit bridge from live VICE memory
40
+ to a static program. It performs one complete connector read, verifies the
41
+ exact byte count, computes SHA-256, and calls the generic
42
+ `write_memory_bytes` endpoint exactly once. It defaults to `dry_run=true` and
43
+ never returns the complete payload. It does not create memory blocks or
44
+ disassemble.
45
+
46
+ Connector, generic target-method, and HTTP timeouts remain distinguishable.
47
+ Mutating timeout responses explicitly say which VICE or Ghidra state may have
48
+ changed, and no timed-out operation is retried automatically. The C64 MCP
49
+ contains no VICE monitor host, port, socket, or binary protocol fallback.
50
+
51
+ ## C64 symbol profile
52
+
53
+ `get_c64_symbol_profile` returns the bundled, versioned C64 platform profile.
54
+ `apply_c64_symbol_profile` applies that exact profile to an explicitly named
55
+ Ghidra program through the generic `apply_symbol_profile` endpoint. It
56
+ defaults to `dry_run=true`, `conflict_policy=error`, and memory-block creation
57
+ disabled. Re-applying an unchanged profile is idempotent.
58
+
59
+ The profile covers the 6510 processor port, all VIC-II and SID registers,
60
+ both CIA devices, color RAM, the 39 standard KERNAL jump-table entry points,
61
+ processor vectors, and common KERNAL workspace addresses. Value-only equates
62
+ name documented VIC-II, SID, and CIA control bits. Optional RAM, ROM, I/O,
63
+ and color-RAM block templates are only considered when
64
+ `create_memory_blocks=true`; the generic endpoint preflights the complete
65
+ request before mutation and refuses ordinary-block overlap.
66
+
67
+ The checked-in profile is generated deterministically by
68
+ `tools/generate_c64_profile.py`. Every symbol group cites its authoritative
69
+ Commodore manual or chip data sheet in the package data.
70
+
71
+ ## C64 text tools
72
+
73
+ The server includes immutable 256-entry mappings for upper/graphics and
74
+ lower/upper PETSCII and C64 screen codes:
75
+
76
+ - `decode_c64_text` decodes inline hex/byte arrays or an exact bounded read
77
+ from a named Ghidra program.
78
+ - `search_c64_text` searches an inclusive program range by exact raw bytes or
79
+ exact decoded Unicode code points.
80
+ - `define_c64_text` decodes first, then sends one flat contiguous region to
81
+ Ghidra with byte typing, an optional label/namespace, and a complete plate
82
+ comment. It defaults to `dry_run=true`.
83
+
84
+ Every decode uses exactly one of a positive fixed `length`, a one-byte
85
+ `terminator`, or a one/two-byte little-endian `prefix_size`. Terminators are
86
+ consumed but excluded from text. Prefixes are consumed and excluded from
87
+ text, and may either describe payload length or include themselves.
88
+
89
+ `high_bit` accepts `exact`, `strip`, or `annotate_reverse`; the latter is
90
+ screen-code-only. `controls` accepts `names`, `escaped`, or `unicode`.
91
+ Lossless payload output retains every original text byte as a stable fragment
92
+ such as `{A:$41}`, `{CLR:$93}`, or `{REV A:$81}`. Prefix and terminator bytes
93
+ remain available in `consumed_bytes` and the per-byte records even though
94
+ framing bytes are excluded from both decoded text renderings.
95
+
96
+ Caller token maps use unprefixed decimal keys (`"129"`) or explicitly
97
+ hexadecimal keys (`"0x81"`). Expansion is single-pass by default. Recursive
98
+ mode recognizes two-digit hexadecimal references such as `{81}`, enforces a
99
+ caller-selected depth, detects cycles, and fails rather than truncating when
100
+ the aggregate rendering cap is exceeded.
101
+
102
+ All reads and inline inputs have a 1 MiB hard cap. Search defaults to 64 KiB
103
+ and 100 results, with hard caps of 1 MiB and 1,000 results. Ghidra reads must
104
+ be complete; partial or unmapped reads are errors.
105
+
106
+ The normative mapping source is Appendices B and C of the official
107
+ *Commodore 64 Programmer's Reference Guide*. The generated package data
108
+ records the source URL and printed page references.
109
+
110
+ ## Configuration
111
+
112
+ - `GHIDRA_MCP_URL` defaults to `http://127.0.0.1:8089`.
113
+ - `GHIDRA_MCP_AUTH_TOKEN` optionally supplies a bearer token.
114
+ - `GHIDRA_MCP_TIMEOUT` defaults to 30 seconds.
115
+ - `GHIDRA_MCP_C64_TOOL_PROFILE` accepts `minimal`, `static`, `vice`, or
116
+ `full`; the default is `static`.
117
+
118
+ The `--tool-profile` command-line option overrides the environment setting.
119
+
120
+ VICE method calls accept a caller-visible `timeout_ms` from 1 through 55,000.
121
+ The wrapper reserves an additional five seconds for generic TraceRMI
122
+ invocation and another five seconds for HTTP transport.