Skip to content

Commit cef65da

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
feat: add binder-mcp and interoperability sections to README generator
1 parent f325bb7 commit cef65da

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,99 @@ Unit tests run automatically on every push and pull request via [GitHub Actions]
17881788

17891789
A [weekly workflow](.github/workflows/check-aosp-updates.yml) checks for new AOSP revision tags, regenerates version tables and proxy code, and opens a PR automatically if anything changed.
17901790

1791+
## binder-mcp
1792+
1793+
AI agents can interact with Android devices through [binder-mcp](cmd/binder-mcp/), a [Model Context Protocol](https://modelcontextprotocol.io/) server that exposes binder services as tools.
1794+
1795+
<!-- BEGIN GENERATED BINDER_MCP -->
1796+
1797+
### Device mode
1798+
1799+
```bash
1800+
# Build and push
1801+
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o build/binder-mcp ./cmd/binder-mcp/
1802+
adb push build/binder-mcp /data/local/tmp/
1803+
1804+
# Use with Claude Code (or any MCP client)
1805+
# In your MCP config, add:
1806+
# {
1807+
# "mcpServers": {
1808+
# "android": {
1809+
# "command": "adb",
1810+
# "args": ["shell", "/data/local/tmp/binder-mcp"]
1811+
# }
1812+
# }
1813+
# }
1814+
```
1815+
1816+
### Remote mode (runs on host)
1817+
1818+
```bash
1819+
go run ./cmd/binder-mcp/ --mode remote
1820+
# Auto-discovers device via ADB, pushes daemon, serves MCP on stdio
1821+
```
1822+
1823+
### Available tools
1824+
1825+
| Tool | Description |
1826+
|---|---|
1827+
| `list_services` | Enumerate all binder services |
1828+
| `get_service_info` | Descriptor, handle, liveness for a service |
1829+
| `call_method` | Invoke raw binder transactions |
1830+
| `get_device_info` | Power, display, thermal status |
1831+
| `get_location` | GPS/fused location |
1832+
| `check_permissions` | SELinux context and service accessibility |
1833+
1834+
<!-- END GENERATED BINDER_MCP -->
1835+
1836+
## Interoperability
1837+
1838+
<!-- BEGIN GENERATED INTEROPERABILITY -->
1839+
1840+
<details>
1841+
<summary><strong>gadb</strong> — Pure Go ADB for CI/CD</summary>
1842+
1843+
The `interop/gadb/runner/` package provides pure-Go ADB device control
1844+
without requiring the `adb` binary. Discover devices, push binaries,
1845+
and run commands programmatically:
1846+
1847+
```go
1848+
dr, _ := runner.NewDeviceRunner("SERIAL")
1849+
dr.PushBinary(ctx, "build/mybinary", "/data/local/tmp/mybinary")
1850+
output, _ := dr.Run(ctx, "/data/local/tmp/mybinary", "--flag")
1851+
```
1852+
1853+
For remote binder access from a host machine, `interop/gadb/proxy/`
1854+
sets up a forwarded session:
1855+
1856+
```go
1857+
sess, _ := proxy.NewSession(ctx, "SERIAL")
1858+
defer sess.Close(ctx)
1859+
sm := servicemanager.New(sess.Transport())
1860+
// Use sm as if running on-device
1861+
```
1862+
1863+
</details>
1864+
1865+
<details>
1866+
<summary><strong>gomobile</strong> — Android AAR</summary>
1867+
1868+
`interop/gomobile/client/` wraps binder calls in a Java-friendly API
1869+
via gomobile. Build the AAR:
1870+
1871+
```bash
1872+
gomobile bind -target android -o binder.aar ./interop/gomobile/client/
1873+
```
1874+
1875+
Available methods: `GetPowerStatus()`, `GetDisplayInfo()`,
1876+
`GetLastLocation()`, `GetDeviceInfo()`.
1877+
1878+
See the example app at [`examples/gomobile/`](examples/gomobile/).
1879+
1880+
</details>
1881+
1882+
<!-- END GENERATED INTEROPERABILITY -->
1883+
17911884
## Project Layout
17921885

17931886
```

tools/cmd/spec2readme/main.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ func run(
138138
{"GENERATED_CODE", renderGeneratedCode()},
139139
{"EXAMPLES_TABLE", renderExamplesTable(examples)},
140140
{"BINDERCLI_POWER", renderBindercliPower()},
141+
{"BINDER_MCP", renderBinderMCP()},
142+
{"INTEROPERABILITY", renderInteroperability()},
141143
}
142144

143145
for _, s := range sections {
@@ -555,6 +557,91 @@ bindercli android.hardware.health.IHealth get-health-info
555557
`
556558
}
557559

560+
func renderBinderMCP() string {
561+
return `### Device mode
562+
563+
` + "```bash" + `
564+
# Build and push
565+
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o build/binder-mcp ./cmd/binder-mcp/
566+
adb push build/binder-mcp /data/local/tmp/
567+
568+
# Use with Claude Code (or any MCP client)
569+
# In your MCP config, add:
570+
# {
571+
# "mcpServers": {
572+
# "android": {
573+
# "command": "adb",
574+
# "args": ["shell", "/data/local/tmp/binder-mcp"]
575+
# }
576+
# }
577+
# }
578+
` + "```" + `
579+
580+
### Remote mode (runs on host)
581+
582+
` + "```bash" + `
583+
go run ./cmd/binder-mcp/ --mode remote
584+
# Auto-discovers device via ADB, pushes daemon, serves MCP on stdio
585+
` + "```" + `
586+
587+
### Available tools
588+
589+
| Tool | Description |
590+
|---|---|
591+
| ` + "`list_services`" + ` | Enumerate all binder services |
592+
| ` + "`get_service_info`" + ` | Descriptor, handle, liveness for a service |
593+
| ` + "`call_method`" + ` | Invoke raw binder transactions |
594+
| ` + "`get_device_info`" + ` | Power, display, thermal status |
595+
| ` + "`get_location`" + ` | GPS/fused location |
596+
| ` + "`check_permissions`" + ` | SELinux context and service accessibility |
597+
`
598+
}
599+
600+
func renderInteroperability() string {
601+
return `<details>
602+
<summary><strong>gadb</strong> — Pure Go ADB for CI/CD</summary>
603+
604+
The ` + "`interop/gadb/runner/`" + ` package provides pure-Go ADB device control
605+
without requiring the ` + "`adb`" + ` binary. Discover devices, push binaries,
606+
and run commands programmatically:
607+
608+
` + "```go" + `
609+
dr, _ := runner.NewDeviceRunner("SERIAL")
610+
dr.PushBinary(ctx, "build/mybinary", "/data/local/tmp/mybinary")
611+
output, _ := dr.Run(ctx, "/data/local/tmp/mybinary", "--flag")
612+
` + "```" + `
613+
614+
For remote binder access from a host machine, ` + "`interop/gadb/proxy/`" + `
615+
sets up a forwarded session:
616+
617+
` + "```go" + `
618+
sess, _ := proxy.NewSession(ctx, "SERIAL")
619+
defer sess.Close(ctx)
620+
sm := servicemanager.New(sess.Transport())
621+
// Use sm as if running on-device
622+
` + "```" + `
623+
624+
</details>
625+
626+
<details>
627+
<summary><strong>gomobile</strong> — Android AAR</summary>
628+
629+
` + "`interop/gomobile/client/`" + ` wraps binder calls in a Java-friendly API
630+
via gomobile. Build the AAR:
631+
632+
` + "```bash" + `
633+
gomobile bind -target android -o binder.aar ./interop/gomobile/client/
634+
` + "```" + `
635+
636+
Available methods: ` + "`GetPowerStatus()`" + `, ` + "`GetDisplayInfo()`" + `,
637+
` + "`GetLastLocation()`" + `, ` + "`GetDeviceInfo()`" + `.
638+
639+
See the example app at [` + "`examples/gomobile/`" + `](examples/gomobile/).
640+
641+
</details>
642+
`
643+
}
644+
558645
// updateExampleCount replaces "N runnable examples" in the directory tree.
559646
func updateExampleCount(content string, count int) string {
560647
re := regexp.MustCompile(`\d+ runnable examples`)

0 commit comments

Comments
 (0)